它是模棱两可的并且依赖于一些默认值,你不应该写这样的代码。
这就是为什么 AT&T 语法具有movzb
和movzw
指令(通常用作),用于 Intel 语法助记符movzbl -1(%rbp), %eax
的两种不同源大小。movzx
请参阅x86 汇编助记符是否标准化?(不,AT&T 编造了新名字。)
是的,您可以 xor %eax,%eax
/mov -1(%rbp), %al
合并到低字节中,但这毫无意义地低效。x86-64 保证 movzx 等 386 条指令的可用性。
令人惊讶的是,movzx -1(%rbp), %rax
确实组装。如果你组装它,然后用 反汇编回 AT&T 语法objdump -d foo.o
,你会得到movzbq
(字节到四边形),包括一个无用的 REX 前缀,而不是在编写 EAX 后让隐式零扩展来完成这项工作。
48 0f b6 45 ff movzbq -0x1(%rbp),%rax
或使用以下命令反汇编为 Intel 语法objdump -drwC -Mintel
:
48 0f b6 45 ff movzx rax,BYTE PTR [rbp-0x1]
有趣的事实:GAS 不能推断movzb
与movzw
如果你写 just movz
,因为movz
它不是指令助记符。与可以从操作数推断出的操作数大小后缀不同,b
andw
被视为助记符的一部分。但是您可以编写movzx
,然后它将从寄存器操作数中推断出两种大小,就像在 Intel 语法模式中一样。
5: 0f b6 c0 movzbl %al,%eax # source: movzx %al, %eax
8: 0f b7 c0 movzwl %ax,%eax # source: movzx %ax, %eax
movzw
并且movzb
本身就像指令助记符(可以从目标寄存器推断出大小后缀)。半相关: MOVZBL 指令在 IA-32 AT&T 语法中有什么作用?
还相关:cdq 等等价物movsx
和 AT&T 等价物的表格:cltq 在汇编中做了什么?
也相关:MOVZX 缺少 32 位寄存器到 64 位寄存器- 因为这在写入 32 位寄存器时是隐含的。