汇编中的 MOVZX (NASM) - 当未指定源大小且目标为 16 位时,它如何选择源大小?

问题描述 投票:0回答:1

我对

movzx
在下面的示例中的表现有点困惑。 (请注意,我假设我的代码示例中使用的 print_int 函数有效,问题不存在,而是在我对
movzx
的理解中,因为这是我们的教授推荐的,据说它只是将寄存器中的内容打印为十进制数):

%include "../linux-ex/asm_io.inc"

extern printf

section .text

global main

main:
push ebp
mov ebp, esp

xor eax, eax

mov ax, [n1]
call print_int

leave
ret

section .data
n1 dw 01234h

这段 32 位架构上的 NASM 代码按预期打印出

4660
。如果我改变:

mov ax, [n1]

movzx ax, [n1]

我得到了

52
的输出。我知道尝试零扩展到
ax
没有任何意义,因为
n1
的大小也是 16 位,但我很惊讶它会产生不同的输出。在第二个示例中,前 8 位似乎被截断并设置为零,留下十六进制数:
34
,即十进制
52
。为什么会出现这种情况?

assembly x86 nasm mov zero-extension
1个回答
6
投票

当汇编器看到时

movzx ax, [n1]

它寻找适合此处使用的助记符和操作数的指令。 IE。具有助记符

movzx
的指令,其第一个操作数是 16 位寄存器,第二个操作数是内存操作数。唯一符合要求的
movzx
变体是

movzx r16, r/m8

这确实是 NASM 汇编此代码的目的。

与 MASM 相比,NASM 不跟踪交易品种的类型。虽然 MASM 可能会发出警告或导致汇编失败,因为

[n1]
具有字类型但用作字节类型的操作数,但 NASM 不会这样做。相反,如果操作数的大小不明确(即,如果有多个指令具有相同的助记符和操作数,但操作数大小不同),则必须使用
byte
word
dword
等关键字显式指定操作数的大小.

© www.soinside.com 2019 - 2024. All rights reserved.