在我的
x86_64
机器上,
我用objdump -d
检查以下两条指令的编码:
movzbl (%rdi),%eax
:编码为 3 个字节 (0f b6 07)movzbq (%rdi),%rax
:编码为 4 个字节 (48 0f b6 07)由于 32 位操作数的高 32 位隐式零扩展,
movzbl
将实现与 movzbq
相同的数据移动任务,但少了 1 个字节的编码。
编译器什么时候更喜欢使用
movzbq
而不是 movzbl
尽管 movzbq
占用一个额外的字节?
尽管 movzbq 占用一个额外的字节,编译器什么时候更喜欢使用 movzbq 而不是 movzbl?
movbq
是否占用额外的字节取决于使用的寄存器。例如,movzbl (%rdi),%r8d
被编码为44 0f b6 07
(因为选择r8
需要“REX前缀”)和movzbq (%rdi),%r8
被编码为4C 0f b6 07
.
这给出了 2 种略有不同的情况:
a) 它可以短 1 个字节。在这种情况下,没有正当理由选择更长的
movzbq
,并且这样做的编译器(当启用优化时)在指令选择方面很糟糕。
b) 不能短 1 个字节。在这种情况下,没有理由选择其中之一——这根本没有区别。
对于这两种情况;为了“编译器开发人员的方便”,编译器的决定可能倾向于与
movsbl
和movsbq
(存在实际差异)对称。