我最近在研究汇编语言,不过我的程序遇到了一个奇怪的 bug。我发现如果使用 64 位的数学方式修改
问题:为什么当整个寄存器只使用了 32 位时,我使用 64 位数学或 32 位数学方式修改有所区别?
%rsp
,那么一切都没问题;但是,如果使用相同的 32 位数学方式修改 %esp
,就会出现分段错误。我尝试打印出 %esp
和 %rsp
的值,每次运行结果都相同。问题:为什么当整个寄存器只使用了 32 位时,我使用 64 位数学或 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