我刚刚发现push指令可以有一个立即的字节,字,dword参数,而且每一个都有不同的操作码。我正在阅读的书中没有例子,所以我不明白汇编程序如何区分这三种类型。例如,如果我写push 12h
它将如何被汇编器解释以及堆栈上会发生什么?x86汇编,堆栈推入指令
回答
汇编程序为每个变体生成不同的操作码。它将在决定将哪个操作码组合到之前检查参数。由于您示例中的12h不是寄存器的名称,但符合数字的十六进制表示的特征,因此推断需要推送立即值,并生成相应的操作码以及二进制值作为指令。它还将检查该论证是否被方括号括起来,用于间接。 对于CPU,执行该代码时,这些不同的变体实际上是不同的指令 - 虽然在执行时共享一些共同点。
检查参数以确定它们的性质是汇编程序对许多指令的操作,除了推送以外,也是为了相同目的:决定需要为指令选择哪个操作码。
这取决于汇编程序。它可以选择操作码的最小操作数字段足够大,以保存即时值。它也可能要求你告诉它你想使用哪个变体。
例如,NASM将push 12h
组装成6A 12
(push byte 12h
)。
如果您想要得到push imm16
变体,你会说push strict word 12h
(如果你不希望NASM优化指令到字节推送,则需要strict
)。
请注意,立即字节push
实际上并未将字节推送到堆栈。在被推动之前,该值将被符号扩展到至少16位(这发生在执行期间,而不是在编译期间)。
如果它将字节扩展为单词或双字,是否有立即字节指令的原因? – user1978522
缩小代码大小将是一个原因。 – Michael
我对此有两点评论,我为其他人感兴趣:当我在Gnu AS中编译“push 1”时,它会变成push imm8指令“6A01”。但这有点误导 - 我认为它会像推一个字节或一个字一样疯狂。但事实并非如此,它推动了32位。 “push 1”,然后“pop eax”在eax中返回1。所以,迈克尔是正确的:-) – carveone
- 1. 汇编堆栈指针AVR
- 2. x86 - 将8位值推入堆栈
- 3. 相同x86汇编指令的不同
- 4. x86汇编:MOVSD指令问题
- 5. 汇编语言x86 JL指令
- 6. C inline汇编x86 fbstp指令
- 7. x86汇编指令:CALL *注册
- 8. ARM汇编 - 监视器堆栈指针
- 9. 6502汇编 - RTS命令和堆栈
- 10. x86 - CALL指令是否总是将EIP指向的地址推送到堆栈?
- 11. x86堆栈指针指向哪里?
- 12. 堆栈中的预留字节:x86汇编(64位)
- 13. x86汇编:为什么我需要堆栈框架?
- 14. 在x86汇编中添加一个变量到堆栈
- 15. 在x86汇编代码中追踪堆栈
- 16. 汇编堆栈访问
- 17. 堆栈在NASM汇编
- 18. 汇编语言 - 堆栈机
- 19. 汇编堆栈3函数
- 20. 汇编堆栈持久性
- 21. x86汇编栈布局混乱
- 22. x86汇编堆内存分配
- 23. x86程序集 - masm32:将变量推入堆栈的问题
- 24. 汇编级编程中的堆栈指针
- 25. 当我向程序集x86中插入新指令时堆栈的帧大小?
- 26. POPF x86汇编
- 27. CIL堆栈交换指令
- 28. DCD指令和IRQ堆栈
- 29. 将整数推入堆栈
- 30. 将链表推入堆栈
一个设想的*完整目的*当然是找出与您的输入相对应的操作码序列。给它一些信用。 –
+1在我之前问这个问题!我会给NASM一些信用:-) – carveone