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