【问题标题】:Push and pop interfering with ret instructionPush 和 pop 干扰 ret 指令
【发布时间】:2021-06-08 19:04:38
【问题描述】:

我在 x86 汇编中编写了一个简单的递归打印函数,但是,我注意到 call print 之后的所有指令都不会被执行,在摸索它之后,我想如果我删除 push ax, pop ax 一切正常,堆栈有什么我想念的吗?

代码如下:

print:
    push ax
    mov ah, 0x0e
    mov al, [bx+si]
    inc si
    cmp al, 0x00
    int 0x10
    jne print
    mov al, 0x0d
    int 0x10
    mov si,0
    pop ax
    ret

它是一个简单的以空字符为基本条件的递归函数,参数为bx,计数器为SI。

【问题讨论】:

  • 这不是递归,因为你没有call 你的函数。这是一个循环。你在循环中有一个push ax,所以它会推送多个东西,然后你只弹出一个东西。因此,您不平衡堆​​栈。您还将int 0x10 放在cmpjne 之间的错误位置。
  • 是的。这是正确的行为。对于每个push,必须有一个pop(一般来说)。如果您的循环的推送次数多于弹出次数,ret 将返回另一个地址,因为两者都使用相同的堆栈。
  • 为什么需要递归?另外即使需要递归,为什么还要保存ax
  • 递归不是基础列表中的第一件事,它不在基础列表中。所以先尝试基础知识。
  • 保持代码干净,尽可能减少对函数的干扰,因为它是引导扇区的一部分。 - 引导扇区最多为 510 字节的代码。这足够小,只需在每个函数上使用 cmets 来指定它会/不会修改哪些寄存器。如果您希望所有函数都有一个共同的调用约定,那么该约定最好让 AX 和 DX(可能还有 CX)被调用破坏,因此想要调用函数的循环可以将它们的数据保存在任何其他寄存器中如果他们想让它生存下去。

标签: assembly x86 nasm


【解决方案1】:

感谢评论部分好心人的帮助,我能够找到一种迭代方式。

print:
    push ax
    mov ah, 0x0e
    mov al, [bx+si]
    inc si
    cmp al, 0x00
    int 0x10
    pop ax
    jne print
    push ax
    mov ah, 0x0e
    mov al, 0x0d
    int 0x10
    xor si,si
    pop ax
    ret

非常低效和hacky,但它确实有效!

编辑:

我使用了 ECM 的技巧,这是一个更有效的实现:

print:
    push ax
    push si
    .loop:
    mov ah, 0x0e
    mov al, [bx+si]
    inc si
    cmp al, 0x00
    int 0x10
    jne .loop
    mov ah, 0x0e
    mov al, 0x0d
    int 0x10
    pop si
    pop ax
    ret

这样更清洁、更高效。

【讨论】:

  • 你的第一个版本没有明显的原因将 SI 归零,而不是返回字符串的结尾作为调用者可以用来找出打印了多少字节的奖励返回值。呼叫者是否应该为您将 SI 归零?你不初始化它。您可以只保存/恢复 BX 和 inc bx 来增加指针。 (或者为了优化代码大小,在循环外使用cld,并让调用者在SI中传递一个指针,这样你就可以使用lodsb来加载AL并增加SI。)
  • TL:DR:通常函数将指针 arg 作为一个寄存器,而不是“DS: BX+SI”是指向字符的指针。此外,您可以在循环外设置一次 AH:int 0x10 / ah=0x0e 不会修改 AH 或 AL。您已经依赖它不修改 FLAGS! (通常你会将 cmp 放在 jne 旁边。通常你不想实际打印终止的 0 字节。例如,将 load / cmp/jne 放在底部,然后在顶部打印。你可以输入使用jmp 循环到负载+循环条件。参见Why are loops always compiled into "do...while" style?)
猜你喜欢
  • 2020-10-07
  • 2013-04-05
  • 2011-04-07
  • 2017-04-23
  • 2017-09-04
  • 2017-09-12
  • 1970-01-01
  • 2013-04-05
  • 1970-01-01
相关资源
最近更新 更多