571
社区成员
发帖
与我相关
我的任务
分享c语言源代码如下:
#include <stdio.h>
int add(int a,int b){
int c;
c = a+b;
return c;
}
int main(){
int ans;
int a = 3;
int b = 4;
ans = add(a,b);
printf("%d\n",ans);
return 0;
}
其通过反汇编之后得到的汇编代码,在不提及优化等级时,默认为不优化,gcc提供了o0,o1,o2,o3层的层级优化
gcc反汇编优化参考:
gcc反汇编
反汇编指令
gcc -g -O0 hello.c
objdump -d a.out
反汇编结果:
0000000000001149 <add>:
1149: f3 0f 1e fa endbr64
114d: 55 push %rbp
114e: 48 89 e5 mov %rsp,%rbp
1151: 89 7d ec mov %edi,-0x14(%rbp)
1154: 89 75 e8 mov %esi,-0x18(%rbp)
1157: 8b 55 ec mov -0x14(%rbp),%edx
115a: 8b 45 e8 mov -0x18(%rbp),%eax
115d: 01 d0 add %edx,%eax
115f: 89 45 fc mov %eax,-0x4(%rbp)
1162: 8b 45 fc mov -0x4(%rbp),%eax
1165: 5d pop %rbp
1166: c3 ret
0000000000001167 <main>:
1167: f3 0f 1e fa endbr64
116b: 55 push %rbp
116c: 48 89 e5 mov %rsp,%rbp
116f: 48 83 ec 10 sub $0x10,%rsp
1173: c7 45 f4 03 00 00 00 movl $0x3,-0xc(%rbp)
117a: c7 45 f8 04 00 00 00 movl $0x4,-0x8(%rbp)
1181: 8b 55 f8 mov -0x8(%rbp),%edx
1184: 8b 45 f4 mov -0xc(%rbp),%eax
1187: 89 d6 mov %edx,%esi
1189: 89 c7 mov %eax,%edi
118b: e8 b9 ff ff ff call 1149 <add>
1190: 89 45 fc mov %eax,-0x4(%rbp)
1193: 8b 45 fc mov -0x4(%rbp),%eax
1196: 89 c6 mov %eax,%esi
1198: 48 8d 05 65 0e 00 00 lea 0xe65(%rip),%rax
首先看main函数
116b: 55 push %rbp
116c: 48 89 e5 mov %rsp,%rbp
116f: 48 83 ec 10 sub $0x10,%rsp
这三条语句保存了父函数的栈帧(注意main函数也有父函数),之后创建了main 函数的栈帧并且在栈帧中分配了16Byte 的空位。

1173: c7 45 f4 03 00 00 00 movl $0x3,-0xc(%rbp)
117a: c7 45 f8 04 00 00 00 movl $0x4,-0x8(%rbp)
1181: 8b 55 f8 mov -0x8(%rbp),%edx
1184: 8b 45 f4 mov -0xc(%rbp),%eax
1187: 89 d6 mov %edx,%esi
1189: 89 c7 mov %eax,%edi
保存参数,将参数3和4放入栈中,同时也放入了edi和esi寄存器中(实际上从下面可以看出,在add函数中用的参数是edi和esi中保存的参数)

118b: e8 b9 ff ff ff call 1149 <add>
调用add函数
114d: 55 push %rbp
114e: 48 89 e5 mov %rsp,%rbp
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-RaiMMbIz-1678780592875)(https://secure2.wostatic.cn/static/nHnoENL2qVo4dRBQmaJDGi/image.png?auth_key=1678779185-8PUauSMfHTCcpFiqiHKpg3-0-cb564780c18c1a7ddbe28482e34ded56)]](https://img-blog.csdnimg.cn/8af24542c91049fa9b9a5136657da9b9.png)
构造add函数所用的栈帧
1151: 89 7d ec mov %edi,-0x14(%rbp)
1154: 89 75 e8 mov %esi,-0x18(%rbp)
1157: 8b 55 ec mov -0x14(%rbp),%edx
115a: 8b 45 e8 mov -0x18(%rbp),%eax
115d: 01 d0 add %edx,%eax
115f: 89 45 fc mov %eax,-0x4(%rbp)
1162: 8b 45 fc mov -0x4(%rbp),%eax
进行c=a+b操作,并将结果存至eax中
而后在main函数中,完成后续操作
从上述代码中可以看出,很多地方的传参方式并不是向课上讲的一样通过栈进行参数传递,而是使用了寄存器传参的方式,这是因为gcc选择的优化等级不同,当选择o2优化方式时,优化方案会产生很大的变化。