【问题标题】:What's the difference between 0 and dword 0?0 和 dword 0 有什么区别?
【发布时间】:2016-03-23 09:21:42
【问题描述】:

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

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

【问题讨论】:

标签: assembly nasm


【解决方案1】:

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

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

不同于

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

因为比较将在符号扩展之后进行,因此,使用较小维度的立即数,特别是当它是负数时,建议谨慎。

祝你编程愉快……

【讨论】:

  • @Wulf:NASM 语法还允许您覆盖默认选择最小尺寸以将位移编码到有效地址中。例如[rax + 32]: mod/rm + 8bit 位移。 [rax + dword 32]: mod/rm + 32b 位移。如果您想请求汇编器使用更大的编码,这很有用,无论是出于对齐原因(而不是用于填充的 NOP),还是因为您要重写占位符值。如果您没有这样的充分理由,只需让汇编程序为您编写的内容选择最小的编码。
  • 更正,编码覆盖必须在[] 的开头有dword。喜欢mov ecx, [dword 1 + rax]。否则 NASM 拒绝它。
【解决方案2】:

它与寄存器没有区别,因为寄存器的名称已经告诉汇编器“有多大”数据项(在本例中为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 0cmp eax, dword 0 的编码。但是,没有 mov r32, imm8 符号扩展立即操作数。请参阅我对 Quasar 答案的评论。实际上 nvm,add ebx, dword 1 并没有改变 YASM 的行为:仍然是 imm8。
  • @PeterCordes 是的,好点。尝试使用mov 执行此操作会在nasm 中产生不匹配的操作数大小错误,但cmp 允许不同大小的操作数。它可能在那个区域依赖于汇编程序。
【解决方案3】:

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

附带说明,xor eax, eax 通常是首选,因为它生成的指令要小得多。

【讨论】:

猜你喜欢
  • 2021-06-16
  • 1970-01-01
  • 2012-09-23
  • 2021-02-13
  • 2012-08-02
  • 1970-01-01
  • 2016-02-19
  • 2012-03-24
相关资源
最近更新 更多