了解汇编中的弹出指令

时间:2018-09-16 17:05:03

标签: gcc assembly x86-64 inline-assembly

我是一名初次学习计算机系统的学生(带有计算机系统:程序员的视角)。我们正在组装,我开始了解x86_64的命令后缀,例如在以下内容中使用leaq

leaq (%rsp, %rdx), %rax

但是,我无法理解为pop使用后缀。例如,使用相同的逻辑,对我来说,我们将popl用于类似的事情:

popl %edi

但是,在网上的文字和其他示例中,我只看到:

pop %edi

有什么区别? popl甚至有效吗?只是寻找更多的见识。有什么帮助,谢谢。

1 个答案:

答案 0 :(得分:2)

您在asm中可以执行的操作受硬件可以执行的操作的限制。源中的隐式或显式操作数大小(带或不带后缀)都不会更改将要汇编到的机器代码。

所以正确的问题是硬件是否可以在64位模式下进行32位推送?不,它不能,因此不存在任何asm源语法,可以使它完全执行您要对一条指令执行的操作。

这就是为什么您的汇编器不接受pop %edipopl %edi的原因。它们完全等效,因为32位寄存器隐含DWORD(l)操作数大小。 您看到的关于poplpop %edi的示例适用于32位模式,,其中EDI是完整寄存器,而不是RDI的低半部分,并且该指令是可编码的。

只有模棱两可时才需要大小后缀mov $1, (%rdi)。您的汇编器将为此给出错误,而不是猜测b / w / l / q中的一个。

但是推入有些特殊:push $1将默认为64位推入,即使可以使用pushw $1How many bytes does the push instruction push onto the stack when I don't specify the operand size?