深入理解C函数传递参数的过程

1,大致分为传值和传地址,不过总体说来都是传值,地址也是一种数值。

传递参数都是拷贝数据进行传递的。这是编译器以及函数调用约定决定的。

首先了解一下主要的函数调用约定

__stdcall,__cdecl,__fastcall,__thiscall,__nakedcall,__pascal

  1.从右到左依次入栈:__stdcall,__cdecl,__thiscall

  2.从左到右依次入栈:__pascal,__fastcall

(1)__cdecl调用约定

  1、参数是从右向左传递的,也是放在 堆栈 中。
  2、堆栈平衡是由调用函数来执行的(在call B,之后会有add esp x,x表示参数的字节数)。
  3、函数的前面会加一个前缀_(_sumExample)
  下面来看看具体的反汇编代码,这是从VC反汇编的代码截取的一部分代码。

  10: int c = 0;

  00401088 C7 45 FC 00 00 00 00 mov dword ptr [ebp-4],0
  11: c = sumExample(2, 3);
  0040108F 6A 03 push 3
  00401091 6A 02 push 2
  从上面的两个push操作我们就可以知道参数是从右向左传递的了。另外这里也回答前面的问题为什么参数会被扩展为4个字节,因为堆栈的操作都是对一个字进行操作的,所以参数都是4个字节的。
  00401093 E8 7C FF FF FF call @ILT+15(_Max) (00401014)
  这里就是调用函数操作了。在进行call操作之后,会自动将call的下一条语句作为函数的返回地址保存在栈中,也就是下面的(00401098)。在地址00401014处我们可以看到这样的一小段代码
  @ILT+0(_Max):
  00401005 E9 26 00 00 00 jmp _sumExample (00401030)
  这里就可以知道程序在编译之后会在函数前面加上前缀_
  00401098 83 C4 08 add esp,8
  这里就是平衡堆栈操作了。可以看出是在调用者进行的。
  0040109B 89 45 FC mov dword ptr [ebp-4],eax
  保存值是由eax寄存器返回的,从这里就可以看出了。
  12:
  13: return 0;
  0040109E 33 C0 xor eax,eax
  14: }
  3: int __cdecl sumExample(int a, int b)
  4: { <
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值