【发布时间】:2017-07-18 16:02:22
【问题描述】:
我胡闹,发现如下
#include <stdio.h>
void f(int& x){
x+=1;
}
int main(){
int a = 12;
f(a);
printf("%d\n",a);
}
当由g++ (Ubuntu 4.8.4-2ubuntu1~14.04.3) 4.8.4 和g++ main.cpp -S 翻译时会生成此程序集(仅显示相关部分)
_Z1fRi:
pushq %rbp
movq %rsp, %rbp
movq %rdi, -8(%rbp)
movq -8(%rbp), %rax
movl (%rax), %eax
leal 1(%rax), %edx
movq -8(%rbp), %rax
movl %edx, (%rax)
popq %rbp
ret
main:
pushq %rbp
movq %rsp, %rbp
subq $16, %rsp
movl $12, -4(%rbp)
leaq -4(%rbp), %rax
movq %rax, %rdi
call _Z1fRi
movl -4(%rbp), %eax
movl %eax, %esi
movl $.LC0, %edi
movl $0, %eax
call printf
movl $0, %eax
leave
ret
问题:为什么编译器会选择使用leal 而不是incq?还是我错过了什么?
【问题讨论】:
-
请看优化后的代码。如果有差异,请更新您的帖子。
-
在这种情况下如何使用
incq?incq是一元的。并且编译器需要rdx = rax + 1。也许真正的问题是:为什么它选择涉及两个寄存器,其中一个就足够了(incq)?这是优化的代码吗?显然不是。 -
lea也很有用,因为它不会影响任何标志寄存器值,这对于 x86[-64] 代码非常有用,其中有很多指令.这只是一个更好的范例。inc还引入了其他问题,例如部分标志寄存器停顿。真正的问题是为什么你会在这里使用inc而不是lea?