Assembly 什么';0和dword 0之间的区别是什么?

Assembly 什么';0和dword 0之间的区别是什么?,assembly,nasm,Assembly,Nasm,正如问题所述, (例如)mov-eax,0和mov-eax,dword 0之间有什么区别 我一直在使用cmp语句,我无法理解其中的区别。 一个是地址,另一个是数值吗?它们完全一样,只是汇编程序语法 作为旁注,xor eax,eax通常是首选,因为它生成的是一个小得多的双字节指令。如上所述,MOV指令没有区别。对于CMP,您将在 一个qword的CMP内存地址,一个32位立即数 不同于 CMP一个qword的内存地址,一个8位立即数 由于比较将在符号扩展后进行,因此,对于较小的维度立即数,特别是当

正如问题所述, (例如)
mov-eax,0
mov-eax,dword 0
之间有什么区别

我一直在使用cmp语句,我无法理解其中的区别。
一个是地址,另一个是数值吗?

它们完全一样,只是汇编程序语法


作为旁注,
xor eax,eax
通常是首选,因为它生成的是一个小得多的双字节指令。

如上所述,MOV指令没有区别。对于CMP,您将在

一个qword的CMP内存地址,一个32位立即数

不同于

CMP一个qword的内存地址,一个8位立即数

由于比较将在符号扩展后进行,因此,对于较小的维度立即数,特别是当其为负数时,建议谨慎一些


享受编程乐趣…

它与寄存器没有区别,因为寄存器的名称已经告诉汇编程序数据项(在本例中,
0
)有多大:

但是,在某些情况下,您可能希望能够指定该值的大小,因为存在选择。在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

使用寄存器时没有区别。有区别的情况是什么?相关:实际上
xor eax,eax
有两个字节长。第一个字节用于操作码,第二个字节用于mod R/M,Xor eax,eax更改标志的值,因此您可能会丢失以前比较的状态,因此,使用CMOVcc或SETcc之类的指令,MOV不影响任何flags@Wulf:NASM语法还允许您覆盖默认值,即选择最小大小以在有效地址中编码位移。e、 g.
[rax+32]
:mod/rm+8位位移<代码>[rax+dword 32]:mod/rm+32b位移。如果您希望请求汇编器使用更大的编码,无论是出于对齐原因(而不是用于填充的NOPs),还是因为您要重写占位符值,这都非常有用。如果你没有这样好的理由,就让汇编程序为你写的东西选择最小的编码。更正,编码覆盖必须在
[]
的开头有
dword
。像
mov-ecx,[dword 1+rax]
。否则NASM会拒绝它。它可能会影响
cmp eax,字节0
cmp eax,dword 0
的编码。但是,没有扩展立即操作数的符号。见我对类星体答案的评论。实际上,nvm,
添加ebx,dword 1
并没有改变YASM的行为:仍然是一个imm8。@PeterCordes是的,很好。尝试使用
mov
执行此操作会在
nasm
中产生不匹配的操作数大小错误,但
cmp
允许不同大小的操作数。在那个领域,它可能依赖于汇编程序。
        mov    [num], dword 0