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

C语言调用函数时参数传递实测(好久以前记录的)_第1张图片

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

第一步:int i= 10

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

C语言调用函数时参数传递实测(好久以前记录的)_第2张图片

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

C语言调用函数时参数传递实测(好久以前记录的)_第3张图片

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

011E1405  lea         eax,[i]  

011E1408  push        eax  

011E1409  call        f (11E105Ah)  

011E140E  add         esp,4  

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

C语言调用函数时参数传递实测(好久以前记录的)_第4张图片

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的值会增加, 这是为了下一次的存储做准备。

C语言调用函数时参数传递实测(好久以前记录的)_第5张图片

第四步:*x = 100;

mov         eax,dword ptr [x]  

Mov       dword ptr [eax],64h

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

 C语言调用函数时参数传递实测(好久以前记录的)_第6张图片

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

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

C语言调用函数时参数传递实测(好久以前记录的)_第7张图片

第5步:下括号

C语言调用函数时参数传递实测(好久以前记录的)_第8张图片

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

C语言调用函数时参数传递实测(好久以前记录的)_第9张图片

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

C语言调用函数时参数传递实测(好久以前记录的)_第10张图片

 

 

 

 

 

 

 

你可能感兴趣的:(C语言,c语言,开发语言)