【问题标题】:Assembly- push'd register RAX is not the same when I pop it off the stack?当我将它从堆栈中弹出时,组装推送的寄存器 RAX 不一样?
【发布时间】:2012-09-29 01:40:08
【问题描述】:

我目前正在 64 位机器上编写程序集 NASM 以打印给定输入的阶乘,然后返回输入。该程序可以正确打印出阶乘值,但返回值未返回输入。是的,代码很糟糕,我不希望你简单地重写整个事情。 (这是我的作业。)我只想有人解释为什么我的返回寄存器(rax)没有保留它从一开始就有的值。

extern read_input
extern print_int
call read_input

push rax   ;save n
mov rcx, 1 ;counter
push rcx   ;save counter
push rdi   ;save print int

jmp test

print:
pop rdi
imul rdi, rcx ;multiply by current counter
push rdi      ;save our multiplication factor
call print_int

pop rdi
pop rcx 
pop rax    ;restore trashed variables
add rcx, 1 ;increment counter by 1
push rax   ;push stuff back on stack
push rcx
push rdi

jmp test

test:
cmp rcx, rax
jle print

pop rax 
pop rcx 
pop rdi ;clear stack
ret

输出:

Please enter an input value:
read_input> Returning 4 (0x4)
Printing integer 1 (0x1)
Printing integer 2 (0x2)
Printing integer 6 (0x6)
Printing integer 24 (0x18)
Program complete.  Return 24 (0x18)

我希望它返回我的输入,在本例中为 4。

任何见解将不胜感激。

【问题讨论】:

  • 感谢您不使用已弃用的作业标签——它使我们免于这些争论。
  • 我不知道还有一个“作业”标签,或者这样的事情是禁忌。现在我知道了,我猜?
  • @derp 大约晚了一年,但是是的。

标签: assembly stack 64-bit nasm cpu-registers


【解决方案1】:

push 和 pop 的顺序是错误的。

推动:

push rax   ;save n
mov rcx, 1 ;counter
push rcx   ;save counter
push rdi   ;save print int
...
push rax   ;push stuff back on stack
push rcx
push rdi

流行音乐:

pop rdi
pop rcx 
pop rax    ;restore trashed variables
...
pop rax 
pop rcx 
pop rdi ;clear stack
ret

最后raxrdi 互换了,哎呀。

【讨论】:

    【解决方案2】:

    问题是,堆栈中的位置没有名称或标识符。您必须以相同的顺序推送和弹出。当您说pop rax 时,处理器不会说“push rax 创建的最后一个条目在哪里?”,而是说“要推送的最新内容在哪里?”。所以你的堆栈看起来像这样(假设 rax 1, rbx 2, rcx 3):

    0x0001 #push rax
    0x0002 #push rbx
    0x0003 #push rcx
      |
      \----- This is the value retrieved by pop rax
    

    请遵循以下规则:始终按弹出顺序相同的顺序推送,除非您明确尝试切换值(最好使用xchg)。

    注意:以错误的顺序做事可用于设置rflags寄存器之类的值:

    push 0x0000000000000000 ;New value for rflags
    popf ;Pop it into rflags
    

    【讨论】:

      猜你喜欢
      • 2020-02-06
      • 2015-06-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-03-09
      • 2016-12-04
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多