1、C++源代码
1
2
3
4
5
6
7
8
9
10
| #include <iostream>
#include <cmath>
using namespace std;
int main(){
int a = 1;
int b = a++ + a++ + a++;
return 0;
}</cmath></iostream> |
#include <iostream>
#include <cmath>
using namespace std;
int main(){
int a = 1;
int b = a++ + a++ + a++;
return 0;
}</cmath></iostream>
2、xCode中汇编结果
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
| cplus`main:
0x100000f70 <+0>: pushq %rbp
0x100000f71 <+1>: movq %rsp, %rbp
0x100000f74 <+4>: xorl %eax, %eax
0x100000f76 <+6>: movl $0x0, -0x4(%rbp)
0x100000f7d <+13>: movl $0x1, -0x8(%rbp);设置局部变量(a=1)
;第一步(左运算值)%ecx
0x100000f84 <+20>: movl -0x8(%rbp), %ecx;取出变量值(1)[准备第一个+号左运算]
0x100000f87 <+23>: movl %ecx, %edx;准备第一次a++
0x100000f89 <+25>: addl $0x1, %edx;a++
0x100000f8c <+28>: movl %edx, -0x8(%rbp);第一次a++结果返回变量中(2)
;第二步(右运算值)%edx
0x100000f8f <+31>: movl -0x8(%rbp), %edx;取出第一次++的结果(2)[第一个+号右运算]
0x100000f92 <+34>: movl %edx, %esi;准备第二次a++
0x100000f94 <+36>: addl $0x1, %esi;a++
0x100000f97 <+39>: movl %esi, -0x8(%rbp);第二次a++结果返回变量中(3)
;第三步(第一个+运算)(返回值)%ecx
0x100000f9a <+42>: addl %edx, %ecx;运算第一个+号(1+2=3)[运算返回值,第二个+号的左运算值]
;第四步(右运算值)%edx
0x100000f9c <+44>: movl -0x8(%rbp), %edx;取出第二次a++后的结果(3)[第二个+号的右运算值]
0x100000f9f <+47>: movl %edx, %esi;准备第三次a++
0x100000fa1 <+49>: addl $0x1, %esi;a++
0x100000fa4 <+52>: movl %esi, -0x8(%rbp);第三次a++结果返回变量中(4)
;第五步(第二个+运算)(返回值)%ecx
0x100000fa7 <+55>: addl %edx, %ecx;运算第二个+号(3+3=6)[运算返回值]
;第六步(运算结束,赋值)
0x100000fa9 <+57>: movl %ecx, -0xc(%rbp);结果传给局部变量(c=6)
0x100000fac <+60>: popq %rbp
0x100000fad <+61>: retq |
cplus`main:
0x100000f70 <+0>: pushq %rbp
0x100000f71 <+1>: movq %rsp, %rbp
0x100000f74 <+4>: xorl %eax, %eax
0x100000f76 <+6>: movl $0x0, -0x4(%rbp)
0x100000f7d <+13>: movl $0x1, -0x8(%rbp);设置局部变量(a=1)
;第一步(左运算值)%ecx
0x100000f84 <+20>: movl -0x8(%rbp), %ecx;取出变量值(1)[准备第一个+号左运算]
0x100000f87 <+23>: movl %ecx, %edx;准备第一次a++
0x100000f89 <+25>: addl $0x1, %edx;a++
0x100000f8c <+28>: movl %edx, -0x8(%rbp);第一次a++结果返回变量中(2)
;第二步(右运算值)%edx
0x100000f8f <+31>: movl -0x8(%rbp), %edx;取出第一次++的结果(2)[第一个+号右运算]
0x100000f92 <+34>: movl %edx, %esi;准备第二次a++
0x100000f94 <+36>: addl $0x1, %esi;a++
0x100000f97 <+39>: movl %esi, -0x8(%rbp);第二次a++结果返回变量中(3)
;第三步(第一个+运算)(返回值)%ecx
0x100000f9a <+42>: addl %edx, %ecx;运算第一个+号(1+2=3)[运算返回值,第二个+号的左运算值]
;第四步(右运算值)%edx
0x100000f9c <+44>: movl -0x8(%rbp), %edx;取出第二次a++后的结果(3)[第二个+号的右运算值]
0x100000f9f <+47>: movl %edx, %esi;准备第三次a++
0x100000fa1 <+49>: addl $0x1, %esi;a++
0x100000fa4 <+52>: movl %esi, -0x8(%rbp);第三次a++结果返回变量中(4)
;第五步(第二个+运算)(返回值)%ecx
0x100000fa7 <+55>: addl %edx, %ecx;运算第二个+号(3+3=6)[运算返回值]
;第六步(运算结束,赋值)
0x100000fa9 <+57>: movl %ecx, -0xc(%rbp);结果传给局部变量(c=6)
0x100000fac <+60>: popq %rbp
0x100000fad <+61>: retq
3、如果对上述理解有一点难度,可以简化一下过程,因为都是a,所以容易绕晕,重点在于理解运算时,左运算数、右运算数准备到寄存器中,计算结果返回到相关变量中这一原则!!![……]
继续阅读