x86_64 程序集 %rsp 与 %esp
x86_64 assembly %rsp vs %esp
最近一直在玩汇编,在我的程序中遇到了一个奇怪的错误。我发现如果我通过 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 , %esp # bug here if I use this (32 bit math)
subq , %rsp # works fine if I use this (64 bit math)
call bob
addq , %rsp
# program cleanup
movq %rbp, %rsp
popq %rbp
ret
# assumes 16 byte aligned when called. Prints %rax
bob:
subq , %rsp
movq %rax, %rsi
lea _format(%rip), %rdi
call _printf
addq , %rsp
ret
在 x86_64 中,地址是 64 位的,那么您怎么能指望在其上进行 32 位数学运算并且还能正常工作呢?此外,x86_64 上的大多数 32 位操作会将前 32 位清零,使地址无效
通过与KerrekSB的交谈,不一致的原因是打印错误。当我说我同时打印了 RSP 和 ESP 时,我在 _printf
调用中使用了 %d
,它打印了一个 4 字节的值。当应用于 RSP 时,它只打印低 4 字节(相当于 ESP),这让我相信 RSP 只在低 4 字节中有有意义的数据。当我改成打印%lu
时,我发现RSP和ESP确实不等价,RSP是使用高4字节。这就是 32 位数学导致分段错误的原因。
最近一直在玩汇编,在我的程序中遇到了一个奇怪的错误。我发现如果我通过 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 , %esp # bug here if I use this (32 bit math)
subq , %rsp # works fine if I use this (64 bit math)
call bob
addq , %rsp
# program cleanup
movq %rbp, %rsp
popq %rbp
ret
# assumes 16 byte aligned when called. Prints %rax
bob:
subq , %rsp
movq %rax, %rsi
lea _format(%rip), %rdi
call _printf
addq , %rsp
ret
在 x86_64 中,地址是 64 位的,那么您怎么能指望在其上进行 32 位数学运算并且还能正常工作呢?此外,x86_64 上的大多数 32 位操作会将前 32 位清零,使地址无效
通过与KerrekSB的交谈,不一致的原因是打印错误。当我说我同时打印了 RSP 和 ESP 时,我在 _printf
调用中使用了 %d
,它打印了一个 4 字节的值。当应用于 RSP 时,它只打印低 4 字节(相当于 ESP),这让我相信 RSP 只在低 4 字节中有有意义的数据。当我改成打印%lu
时,我发现RSP和ESP确实不等价,RSP是使用高4字节。这就是 32 位数学导致分段错误的原因。