2014-06-14 36 views
2

我刚刚发现push指令可以有一个立即的字节,字,dword参数,而且每一个都有不同的操作码。我正在阅读的书中没有例子,所以我不明白汇编程序如何区分这三种类型。例如,如果我写push 12h它将如何被汇编器解释以及堆栈上会发生什么?x86汇编,堆栈推入指令

+0

一个设想的*完整目的*当然是找出与您的输入相对应的操作码序列。给它一些信用。 –

+0

+1在我之前问这个问题!我会给NASM一些信用:-) – carveone

回答

1

汇编程序为每个变体生成不同的操作码。它将在决定将哪个操​​作码组合到之前检查参数。由于您示例中的12h不是寄存器的名称,但符合数字的十六进制表示的特征,因此推断需要推送立即值,并生成相应的操作码以及二进制值作为指令。它还将检查该论证是否被方括号括起来,用于间接。 对于CPU,执行该代码时,这些不同的变体实际上是不同的指令 - 虽然在执行时共享一些共同点。

检查参数以确定它们的性质是汇编程序对许多指令的操作,除了推送以外,也是为了相同目的:决定需要为指令选择哪个操作码。

2

这取决于汇编程序。它可以选择操作码的最小操作数字段足够大,以保存即时值。它也可能要求你告诉它你想使用哪个变体。

例如,NASM将push 12h组装成6A 12push byte 12h)。

如果您想要得到push imm16变体,你会说push strict word 12h(如果你不希望NASM优化指令到字节推送,则需要strict)。

请注意,立即字节push实际上并未将字节推送到堆栈。在被推动之前,该值将被符号扩展到至少16位(这发生在执行期间,而不是在编译期间)。

+0

如果它将字节扩展为单词或双字,是否有立即字节指令的原因? – user1978522

+1

缩小代码大小将是一个原因。 – Michael

+0

我对此有两点评论,我为其他人感兴趣:当我在Gnu AS中编译“push 1”时,它会变成push imm8指令“6A01”。但这有点误导 - 我认为它会像推一个字节或一个字一样疯狂。但事实并非如此,它推动了32位。 “push 1”,然后“pop eax”在eax中返回1。所以,迈克尔是正确的:-) – carveone