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

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u010442328/article/details/45823969

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

一目了然。。

阅读更多

没有更多推荐了,返回首页