从汇编的角度理解为什么c样式函数使用时,实参尽量使用指针传递

30 篇文章 0 订阅
18 篇文章 0 订阅

如题,常常将参数传递时,用常值传递和用地址传递都是可以的,但是实际都是用指针来传递。这是在中兴面试时,想到的联系,可以用汇编层来理解。
其实在之前的博文中已经提到过这个问题,只是那篇的角度和研究内容不一样,
连接为http://blog.csdn.net/u010442328/article/details/43152419
什么叫做函数传递参数,
在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]** 
}

一目了然。。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值