0

Y86类似于x86-64。为什么函数 pushtest 总是返回零?

正如我所知,x86-64Push 会先递减 ESP 寄存器而不是写入。先弹出读取,然后递增 ESP 寄存器。

    。文本
.globl 推送测试
推送测试:
    movq %rsp, %rax
    pushq %rsp
    popq %rdx
    subq %rdx, %rax
    ret
4

2 回答 2

0

我参考这个答案“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  |
于 2019-07-11T11:34:22.327 回答
0

第一的。您不应该%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
于 2019-07-11T08:28:11.137 回答