[将x设置为零(x = 0)时,我的csapp书指出了两种方法。
第一:
xorq %rcx, %rcx
第二:
movq $0, %rcx
它还告诉您第一个仅占用3个字节,但是第二个仅占用7个字节。
[这两种方式如何运作?为什么第一个字节比第二个字节少?
因为mov
需要更多空间来对其32位立即数源操作数进行编码。xor
仅需要ModRM字节对其操作数进行编码。
都不需要REX前缀,所以您应该比较2字节xor %ecx,%ecx
与5字节mov $0, %ecx
] >>。Why do x86-64 instructions on 32-bit registers zero the upper part of the full 64-bit register?GAS不会为您执行此优化,movq
为您提供mov $sign_extended_imm32, %r/m64
编码,而不是省略ModRM字节的特殊情况下的5字节mov $imm32, %r32
编码。
((如CS:APP example uses idivq with two operands?中所述,CS:APP似乎充满了asm错误。这不是一个无效的语法错误,只是一个错过的优化。)
[不幸的是,没有mov
的符号扩展为8位立即数的编码,否则我们可以使用3字节的mov reg, imm8
。 (https://www.felixcloutier.com/x86/mov)。 (令我惊讶的是,x86-64的任何迭代都没有重新利用它的操作码字节中的任何一个,它释放出了类似的不错的mov
编码,也许与BMI1混在一起了。)
有关x86指令编码的更多详细信息,请阅读Intel的vol.2手册并了解反汇编。
另请参阅What is the best way to set a register to zero in x86 assembly: xor, mov or and?,了解为什么进行零或置零最佳的详细信息:在某些CPU上,尤其是P6-系列和Sandybridge系列,除简单的代码大小外,它比mov
具有微体系结构上的优势。
为什么第一个字节比第二个字节少?