【发布时间】:2016-11-13 04:30:06
【问题描述】:
有时 gcc 使用 32 位寄存器,而我希望它使用 64 位寄存器。例如下面的 C 代码:
unsigned long long
div(unsigned long long a, unsigned long long b){
return a/b;
}
使用 -O2 选项编译(省略了一些样板文件):
div:
movq %rdi, %rax
xorl %edx, %edx
divq %rsi
ret
对于无符号除法,寄存器%rdx 需要为0。这可以通过xorq %rdx, %rdx 来实现,但xorl %edx, %edx 似乎也有同样的效果。
至少在我的机器上,xorl 与 xorq 相比没有性能提升(即加速)。
我实际上不止一个问题:
- 为什么 gcc 更喜欢 32 位版本?
- 为什么 gcc 停在
xorl而不使用xorw? - 是否存在
xorl比xorq快的机器? - 是否应该总是更喜欢 32 位寄存器/操作而不是 64 位寄存器/操作?
【问题讨论】:
-
如果你
objdump -d创建了目标文件,你会看到xorq需要一个额外的编码字节。有关详细信息,请参阅 x86 程序员手册。 -
这只是一个优化。代码大小(可以说也是性能,管道中的内容越多,缓存中的内容越多)。 x86 从 16 位开始,然后是 32 位扩展,然后是 64 位。根据您的工具,其中一些指令可能在 32 位或 64 位上使用相同的操作码。有时它只是反汇编程序误导您,有时它实际上是一个较小的寄存器和零扩展或符号扩展或其他。只需阅读 x86 文档。
标签: gcc assembly x86-64 micro-optimization