我可以从堆栈中 POP 一个值,但在 NASM 程序集中无处放置吗?

Vol*_*ort 6 x86 stack nasm stack-memory stack-pointer

NASM 程序集,Ubuntu,32 位程序。

通常,当从堆栈中弹出一个值时,我会做

POP somewhere
Run Code Online (Sandbox Code Playgroud)

放入寄存器或变量。但有时,我只是不想把它放在任何地方——我只想摆脱堆栈中的下一个元素。正在做

POP
Run Code Online (Sandbox Code Playgroud)

就像那样是行不通的。

我的解决方法是制作一个我根本不使用的 4 字节变量并将其转储POP到其中。有没有更好的方法来实现这一目标?

Joh*_*nck 7

将堆栈指针调整四个字节(或其他数量),忽略顶部的任何值:

add esp, 4
Run Code Online (Sandbox Code Playgroud)

  • @Omega:弹出不会删除任何内容,它只是移动堆栈指针。 (2认同)

ecm*_*ecm 5

正如约翰·兹温克(John Zwinck)已经指出的那样,你可以使用add esp, 4有效地“突然进入无处可去”。当然,您可以使用其他常量仅弹出一个字 (2)、两个双字 (8) 或其他任何内容。

如果您不想修改算术状态标志,lea esp, [esp + 4]则可以使用。(这不适用于由 寻址的 16 位堆栈,sp因为[sp + immediate]无法编码。)

如果您创建了一个ebp指向底部的堆栈帧,那么您可能只需丢弃自设置mov esp, ebp以来分配的所有堆栈槽即可逃脱惩罚。ebp(该指令的部分操作leave实际上与 相同mov esp, ebp。)

同样,您可以使用以下方法更改堆栈指针,lea esp, [ebp - immediate]但这需要跟踪与ebp所需esp值的距离。

最后,除了弹出到临时内存目的地之外,您始终可以弹出到未“使用”的寄存器,即此时可能会被您的代码破坏。例如,在这里我使用pop cx两次只是为了摆脱堆栈槽,它的编码时间比add sp, 4: https: //hg.ulukai.org/ecm/ldosboot/file/b7cf0f0fee06/boot.asm#l1186