Y86
类似于x86-64
。为什么函数 pushtest 总是返回零?
正如我所知,x86-64
Push 会先递减 ESP 寄存器而不是写入。先弹出读取,然后递增 ESP 寄存器。
。文本 .globl 推送测试 推送测试: movq %rsp, %rax pushq %rsp popq %rdx subq %rdx, %rax ret
Y86
类似于x86-64
。为什么函数 pushtest 总是返回零?
正如我所知,x86-64
Push 会先递减 ESP 寄存器而不是写入。先弹出读取,然后递增 ESP 寄存器。
。文本 .globl 推送测试 推送测试: movq %rsp, %rax pushq %rsp popq %rdx subq %rdx, %rax ret
我参考这个答案“pushq”可以替换为“subq and movq”,“popq”可以替换为“movq and addq”。
但“PUSH ESP”和“POP ESP”是特例。参考这个答案。但结果不是“0”
pushq %rsp ;推送指令执行前存在的 ESP 寄存器的值。
popq %rsp ;在旧堆栈顶部的数据写入目标之前增加堆栈指针(ESP)。
pushq %rdx ;递减堆栈指针,然后将源操作数存储在堆栈顶部。
popq %rdx ;将堆栈顶部的值加载到目标操作数(或显式操作码)指定的位置,然后递增堆栈指针。
rax =
rdx =
0x28 | 0x12 |
0x30 | 0x34 | <--- rsp
0x38 | 0x56 |
0x40 | 0x78 |
0x48 | 0x9A |
movq %rsp, %rax
rax = 0x30
rdx =
0x28 | 0x12 |
0x30 | 0x34 | <--- rsp
0x38 | 0x56 |
0x40 | 0x78 |
0x48 | 0x9A |
pushq %rsp ;store, using rsp as the address, then subtract 8 from rsp
rax = 0x30
rdx =
0x28 | 0x12 | <--- rsp
0x30 | 0x30 |
0x38 | 0x56 |
0x40 | 0x78 |
0x48 | 0x9A |
popq %rdx ;load, using rsp as the address, then add 8 to the rsp
rax = 0x30
rdx = 0x30
0x28 | 0x12 | <--- rsp
0x30 | 0x30 |
0x38 | 0x56 |
0x40 | 0x78 |
0x48 | 0x9A |
subq %rdx, %rax ;Return 0
rax = 0x00
rdx = 0x30
0x28 | 0x12 |
0x30 | 0x30 | <--- rsp
0x38 | 0x56 |
0x40 | 0x78 |
0x48 | 0x9A |
第一的。您不应该%rsp
手动修改(这是堆栈指针寄存器),不要这样做movq %rsp, ...
。是%rsp
(并且只能)由push
, pop
, call
,管理ret
。还要检查这个问题。
最后总是%rdx
==0,因为:
movq %rsp, %rax ; %rsp==%rax
pushq %rsp ; top of the stack := %rsp == %rax
popq %rdx ; %rdx := top of the stack == %rax
subq %rdx, %rax ; %rdx := %rdx - %rax , i.e. %rdx := %rax - %rax == 0