从汇编的角度理解为什么c样式函数使用时,实参尽量使用指针传递
2015-05-18 16:21
549 查看
如题,常常将参数传递时,用常值传递和用地址传递都是可以的,但是实际都是用指针来传递。这是在中兴面试时,想到的联系,可以用汇编层来理解。
其实在之前的博文中已经提到过这个问题,只是那篇的角度和研究内容不一样,
连接为/article/7829031.html
什么叫做函数传递参数,
在vs2008下做个实验吧,切换到ubuntu有点麻烦了。。
小程序
看看vs2008生成的汇编代码
可以看到参数是如何传到函数中去的,利用压栈,而且是右边的先压栈,也就是说是在栈中开辟一段区间用于传递参数的,设想加入要传递的是一个很大的数据结构,那不是效率low的很,而指针是什么,就是地址,充其量4个字节吧,这效率就high的很呀,在做个实验
生成汇编代码如下
上面调用时,就是push地址了,
这里面还有一个细节,就是函数如何将数据返回出来,看了汇编代码就一目了然了。。。。。
看看汇编是如何给i变量赋值的
00D81A8C mov dword ptr [i],eax
为什么是eax,回到swap函数看看
一目了然。。
其实在之前的博文中已经提到过这个问题,只是那篇的角度和研究内容不一样,
连接为/article/7829031.html
什么叫做函数传递参数,
在vs2008下做个实验吧,切换到ubuntu有点麻烦了。。
小程序
int swap(int a,int b) { return a+b; } int main() { int i=swap(1,2); return 0; }
看看vs2008生成的汇编代码
int main() { 00FA13E0 push ebp 00FA13E1 mov ebp,esp 00FA13E3 sub esp,0CCh 00FA13E9 push ebx 00FA13EA push esi 00FA13EB push edi 00FA13EC lea edi,[ebp-0CCh] 00FA13F2 mov ecx,33h 00FA13F7 mov eax,0CCCCCCCCh 00FA13FC rep stos dword ptr es:[edi] **int i=swap(1,2);** 00FA13FE push 2 00FA1400 push 1 00FA1402 call swap (0FA1028h) 00FA1407 add esp,8 00FA140A mov dword ptr [i],eax return 0; 00FA140D xor eax,eax }
int swap(int a,int b) { 00FA13A0 push ebp 00FA13A1 mov ebp,esp 00FA13A3 sub esp,0C0h 00FA13A9 push ebx 00FA13AA push esi 00FA13AB push edi 00FA13AC lea edi,[ebp-0C0h] 00FA13B2 mov ecx,30h 00FA13B7 mov eax,0CCCCCCCCh 00FA13BC rep stos dword ptr es:[edi] return a+b; 00FA13BE mov eax,dword ptr [a] 00FA13C1 add eax,dword ptr [b] } 00FA13C4 pop edi 00FA13C5 pop esi 00FA13C6 pop ebx 00FA13C7 mov esp,ebp 00FA13C9 pop ebp 00FA13CA ret
可以看到参数是如何传到函数中去的,利用压栈,而且是右边的先压栈,也就是说是在栈中开辟一段区间用于传递参数的,设想加入要传递的是一个很大的数据结构,那不是效率low的很,而指针是什么,就是地址,充其量4个字节吧,这效率就high的很呀,在做个实验
int swap(int* a,int* b) { return *a+*b; } int main() { int a=1; int b=2; int i=swap(&a,&b); return 0; }
生成汇编代码如下
int main() { 00D81A50 push ebp 00D81A51 mov ebp,esp 00D81A53 sub esp,0E4h 00D81A59 push ebx 00D81A5A push esi 00D81A5B push edi 00D81A5C lea edi,[ebp-0E4h] 00D81A62 mov ecx,39h 00D81A67 mov eax,0CCCCCCCCh 00D81A6C rep stos dword ptr es:[edi] int a=1; 00D81A6E mov dword ptr [a],1 int b=2; 00D81A75 mov dword ptr [b],2 int i=swap(&a,&b); **00D81A7C lea eax,[b] 00D81A7F push eax 00D81A80 lea ecx,[a] 00D81A83 push ecx** 00D81A84 call swap (0D811D1h) 00D81A89 add esp,8 00D81A8C mov dword ptr [i],eax return 0; 00D81A8F xor eax,eax }
上面调用时,就是push地址了,
这里面还有一个细节,就是函数如何将数据返回出来,看了汇编代码就一目了然了。。。。。
看看汇编是如何给i变量赋值的
00D81A8C mov dword ptr [i],eax
为什么是eax,回到swap函数看看
int swap(int* a,int* b) { 00D813A0 push ebp 00D813A1 mov ebp,esp 00D813A3 sub esp,0C0h 00D813A9 push ebx 00D813AA push esi 00D813AB push edi 00D813AC lea edi,[ebp-0C0h] 00D813B2 mov ecx,30h 00D813B7 mov eax,0CCCCCCCCh 00D813BC rep stos dword ptr es:[edi] **return *a+*b; 00D813BE mov eax,dword ptr [a] 00D813C1 mov eax,dword ptr [eax] 00D813C3 mov ecx,dword ptr [b] 00D813C6 add eax,dword ptr [ecx]** }
一目了然。。
相关文章推荐
- 关于指针作为函数参数传递的理解,对比普通变量作为函数参数的需注意点,其实就是行参和实参的问题。
- 从汇编的角度分析函数指针
- 从汇编角度来理解linux下多层函数调用堆栈运行状态
- 通过汇编代码理解成员函数指针并不是指针
- [转] 通过汇编代码理解成员函数指针并不是指针
- 对引用和指针使用以及函数返回引用和指针类型的理解
- 怎么样使用指针向函数传递一个多维数组
- C++函数参数和返回值三种传递方式:值传递、指针传递和引用传递(着重理解)
- 自己关于指针在函数中使用的理解和总结
- C++函数参数和返回值三种传递方式:值传递、指针传递和引用传递(着重理解)
- 函数指针使用的一点理解
- 关于C语言中一,二级指针函数中的使用和c语言中和函数发生调用时,实参和形参都会占用内存吗?
- 使用指针来将多维数组传递给函数
- 通过函数分配内存,理解实参,形参之间的传递.
- 通过汇编角度理解虚函数!
- 通过汇编角度理解虚函数
- 从安全的角度理解――为什么要使用 Google 的服务?【转贴】
- 实例解析使用指针作为函数参数传递需要注意的问题
- 一级指针不能做函数参数传递动态内存的理解
- 对引用和指针使用以及函数返回引用和指针类型的理解