【发布时间】:2015-10-07 19:42:20
【问题描述】:
我最近一直在玩汇编,在我的程序中遇到了一个奇怪的错误。我发现如果我通过执行 64 位数学修改 %rsp,那么一切正常,但是如果我修改 %esp 相同的数量,除了 32 位数学,我会遇到分段错误。我试过把%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
【问题讨论】:
-
subl $16, %esp 将 RSP 的高 32 位设置为零。卡布姆。 Explained here.
标签: assembly x86-64 cpu-registers