【发布时间】:2016-03-23 09:21:42
【问题描述】:
正如问题所述,
(例如)mov eax, 0 和 mov eax, dword 0 之间有什么区别?
我一直在使用 cmp 语句,但我无法发现其中的区别。 一个是地址,另一个是数值吗?
【问题讨论】:
-
使用寄存器没有区别。
-
有差异是什么情况?
正如问题所述,
(例如)mov eax, 0 和 mov eax, dword 0 之间有什么区别?
我一直在使用 cmp 语句,但我无法发现其中的区别。 一个是地址,另一个是数值吗?
【问题讨论】:
如上所述,MOV 指令没有区别。对于 CMP,您将有以下区别
一个qword的CMP内存地址,一个32位立即数
不同于
一个qword的CMP内存地址,一个8位立即数
因为比较将在符号扩展之后进行,因此,使用较小维度的立即数,特别是当它是负数时,建议谨慎。
祝你编程愉快……
【讨论】:
[rax + 32]: mod/rm + 8bit 位移。 [rax + dword 32]: mod/rm + 32b 位移。如果您想请求汇编器使用更大的编码,这很有用,无论是出于对齐原因(而不是用于填充的 NOP),还是因为您要重写占位符值。如果您没有这样的充分理由,只需让汇编程序为您编写的内容选择最小的编码。
[] 的开头有dword。喜欢mov ecx, [dword 1 + rax]。否则 NASM 拒绝它。
它与寄存器没有区别,因为寄存器的名称已经告诉汇编器“有多大”数据项(在本例中为0)是:
mov eax, dword 0 ; move a 4-byte 0 into eax
mov eax, 0 ; move a 0 into eax (eax is 4 bytes, so move 4 bytes)
但是,在某些情况下,您可能希望能够指定该值的大小,因为可以选择。在 x86 32 位汇编中,以下代码会将一个 4 字节的 0 值压入堆栈:
push 0 ; push 4-byte 0 onto the stack
如果你想推送一个 2 字节的 0 值,你可以使用:
push word 0
如果您想明确说明 4 字节立即推送,您可以使用 dword:
push dword 0
如果你想将一个立即数移动到内存中,大小说明符变得很有必要,因为汇编器不知道数据项有多大。例如,考虑nasm 程序集中的以下代码:
section .bss
num resb 4
...
section .text
...
mov [num], 0
这会产生错误:
error: operation size not specified
所以你需要指定大小,比如 4 字节:
mov [num], dword 0
【讨论】:
cmp eax, byte 0 与cmp eax, dword 0 的编码。但是,没有 mov r32, imm8 符号扩展立即操作数。请参阅我对 Quasar 答案的评论。实际上 nvm,add ebx, dword 1 并没有改变 YASM 的行为:仍然是 imm8。
mov 执行此操作会在nasm 中产生不匹配的操作数大小错误,但cmp 允许不同大小的操作数。它可能在那个区域依赖于汇编程序。
它们完全一样,只是汇编语法。
附带说明,xor eax, eax 通常是首选,因为它生成的指令要小得多。
【讨论】:
xor eax, eax是两个字节长。第一个字节为操作码,第二个字节为 mod R/M。