只是为了从“犹大”的角度说服自己(如果尚未完成),这证明我的帖子只回答了您简单案例中的简单问题。
小证据表明,在您的简单示例中 gcc 只做它需要的,而不是更多:
代码:
int main()
{
int x = 10;
x = 5 + 10;
return x;
}
使用调试构建
K:\jff\data\python\stackoverflow\c>gcc -g -std=c11 -c assign.c
带有混合 C/asm 代码的 objdump
K:\jff\data\python\stackoverflow\c>objdump -d -S assign.o
assign.o: file format pe-x86-64
Disassembly of section .text:
0000000000000000 <main>:
int main()
{
0: 55 push %rbp
1: 48 89 e5 mov %rsp,%rbp
4: 48 83 ec 30 sub $0x30,%rsp
8: e8 00 00 00 00 callq d <main+0xd>
int x = 10;
d: c7 45 fc 0a 00 00 00 movl $0xa,-0x4(%rbp)
x = 5 + 10;
14: c7 45 fc 0f 00 00 00 movl $0xf,-0x4(%rbp)
return x;
1b: 8b 45 fc mov -0x4(%rbp),%eax
}
1e: 90 nop
1f: 48 83 c4 30 add $0x30,%rsp
23: 5d pop %rbp
24: c3 retq
25: 90 nop
26: 90 nop
27: 90 nop
28: 90 nop
29: 90 nop
2a: 90 nop
2b: 90 nop
2c: 90 nop
2d: 90 nop
2e: 90 nop
2f: 90 nop
正如其他(不错的)答案中所述,不愿意解释,但如果表达式更复杂,则必须计算存储值的地址,因此需要进行某种评估。
编辑:
使用一些稍微复杂的代码:
int main()
{
int x[3];
int i = 2;
x[i] = 5 + 10;
return x[i];
}
反汇编:
Disassembly of section .text:
0000000000000000 <main>:
int main()
{
0: 55 push %rbp
1: 48 89 e5 mov %rsp,%rbp
4: 48 83 ec 30 sub $0x30,%rsp
8: e8 00 00 00 00 callq d <main+0xd>
int x[3];
int i = 2;
d: c7 45 fc 02 00 00 00 movl $0x2,-0x4(%rbp)
x[i] = 5 + 10;
14: 8b 45 fc mov -0x4(%rbp),%eax <== hey, could be more optimized here: movl $0x2,%eax covers line+above line :)
17: 48 98 cltq
19: c7 44 85 f0 0f 00 00 movl $0xf,-0x10(%rbp,%rax,4) <== this line holds the left-operand evaluation, in a way, %rax is used to offset the array address
20: 00
return x[i];
21: 8b 45 fc mov -0x4(%rbp),%eax
24: 48 98 cltq
26: 8b 44 85 f0 mov -0x10(%rbp,%rax,4),%eax
}
2a: 90 nop
2b: 48 83 c4 30 add $0x30,%rsp
2f: 5d pop %rbp
30: c3 retq