我刚刚发现push指令可以具有立即字节,word和dword参数,并且每个参数都有不同的操作码。我正在阅读的书中没有示例,因此我不理解汇编程序如何区分这三种类型。例如,如果我写push 12h
,汇编程序将如何解释它,以及在堆栈上实际发生了什么?
由汇编程序决定。它可能会选择操作数字段最小的操作码,足以容纳立即数。它还可能需要您告诉它要使用哪个变体。
例如,NASM将push 12h
组装为6A 12
(push byte 12h
)。
如果您想要例如要获得push imm16
变体,您会说push strict word 12h
(如果您不希望NASM将指令优化为字节推送,则需要strict
。)>
请注意,立即数字节push
实际上不会将字节压入堆栈。该值在被压入之前将被符号扩展为至少16位(这种情况发生在执行期间,而不是在编译期间)。
汇编器会为每个变量生成不同的操作码。在决定要汇编的操作码之前,它将检查参数。由于示例中的12h不是寄存器的名称,而是满足数字的十六进制表示的特征,因此得出结论,需要推入立即数,并生成相应的操作码以及二进制值作为指令。它还将检查参数是否用方括号括起来,以进行间接调用。对于CPU,在执行该代码时,这些不同的变体实际上是不同的指令-尽管在执行时具有一些共同点。
push 12h
或push byte 12h
,这意味着我们将类似12h
的值压入堆栈。该值可以存储在esp
寄存器中。