C语言调用函数时参数传递实测(好久以前记录的)

上面是函数原型。来看看它编译后的反汇编是怎样执行的。理解函数的调用过程。

第一步:int i= 10

在执行完i= 10后,可以查到i的地址是0x0028FAAC,然后查对应的内存地址

从图中可以看到,10已经被写到对应的内存中去了。

第二步:f(&i);这句话对应的汇编有以下4句

011E1405  lea         eax,[i]  

011E1408  push        eax  

011E1409  call        f (11E105Ah)  

011E140E  add         esp,4  

Lea eax,[i]    将i的有效地址传递给eax,执行完可观察到eax的值已经发生变化

Push eax ,将eax的值压栈,然后call函数f

第三步

void f(int * x)

{

011E13A0  push        ebp  

011E13A1  mov         ebp,esp  

011E13A3  sub         esp,0C0h  

011E13A9  push        ebx  

011E13AA  push        esi  

011E13AB  push        edi  

011E13AC  lea         edi,[ebp-0C0h]  

011E13B2  mov         ecx,30h  

011E13B7  mov         eax,0CCCCCCCCh  

011E13BC  rep stos    dword ptr es:[edi]

这一段汇编来逐个看一下

Push ebp将旧的ebp压栈

Mov ebp,esp   对栈底指针重新赋值,指向现在的栈顶

然后将bx,si,di压栈

Lea edi,[ebp-c0h]将[ebp-c0h]的地址传递给edi寄存器

011E13B2  mov         ecx,30h  

011E13B7  mov         eax,0CCCCCCCCh  

011E13BC  rep stos    dword ptr es:[edi]

F9D0到F910的区域初始化,全部写成ccH,共C0H个字节,每次写4个字节,共写30H次。

上面三句话是一起的,相当于是一个循环。先将cx寄存器设为30h,然后对eax赋值为cccccccch。

Rep stos dword ptr es:[edi]的作用是将 eax的值写入到es:[edi]对应的地址。

STOS指令的作用是将eax中的值拷贝到ES:EDI指向的地址. 如果设置了direction flag, 那么edi会在该指令执行后减小, 如果没有设置direction flag, 那么edi的值会增加, 这是为了下一次的存储做准备。

第四步:*x = 100;

mov         eax,dword ptr [x]  

Mov       dword ptr [eax],64h

mov eax,dword ptr [x] ,将 [x]的值传递给eax。[x]的值就是实参i的地址,即

 

此时0028FAAC地址对应的值还是10.

Mov [eax],64h   往这个地址写入100,即64h

第5步:下括号

先是将edi,esi,ebx出栈。可以看到,出栈后寄存器中的值变化了,但是原来的栈区中的内容没有被清除。

然后将ebp的值赋给esp,让栈顶指针指向ebp所在的位置

 

 

 

 

 

 

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值