Недавно я играл с сборкой, и я наткнулся на странную ошибку в моей программе. Я обнаружил, что если я модифицирую %rsp
, выполнив 64-битную математику, тогда все будет хорошо, но если я изменю %esp
на ту же сумму, за исключением 32-битной математики, я получаю ошибку сегментации. Я попробовал распечатать как %esp
, так и %rsp
, и они одинаковы при каждом запуске.x86_64 сборка% rsp vs% esp
ВОПРОС: Почему имеет значение, выполняю ли 64-битную математику или 32-битную математику, когда весь регистр использует только 32 бита?
.cstring
_format: .asciz "%d\n"
.text
.globl _main
_main:
# program setup
pushq %rbp
movq %rsp, %rbp
# program - 16 byte aligned at this point
# print stack pointer memory
movq %rsp, %rax
call bob # prints the same value as the next call to bob
xorq %rax, %rax
movl %esp, %eax
call bob # prints the same value as previous call to bob
# this code breaks
subl $16, %esp # bug here if I use this (32 bit math)
subq $16, %rsp # works fine if I use this (64 bit math)
call bob
addq $16, %rsp
# program cleanup
movq %rbp, %rsp
popq %rbp
ret
# assumes 16 byte aligned when called. Prints %rax
bob:
subq $8, %rsp
movq %rax, %rsi
lea _format(%rip), %rdi
call _printf
addq $8, %rsp
ret
subl $ 16,% esp устанавливает верхние 32 бита RSP равным нулю. Kaboom. [Разъясняется здесь] (http://stackoverflow.com/a/25456097/17034). –
Связанные: http://stackoverflow.com/questions/15656887/a-modification-to-esp-cause-sigsegv – nrz