您的位置:首页 > Web前端 > CSS

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

2015-05-18 16:21 549 查看
如题,常常将参数传递时,用常值传递和用地址传递都是可以的,但是实际都是用指针来传递。这是在中兴面试时,想到的联系,可以用汇编层来理解。

其实在之前的博文中已经提到过这个问题,只是那篇的角度和研究内容不一样,

连接为/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]**
}


一目了然。。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: