从汇编的角度去理解函数会让你更加的深刻。。。。。。
看这篇文章需要一定的c语言基础和汇编基础(能基本看懂简单的汇编指令)
先来分析一个简单的函数
这个函数功能是将两个数相加并返回结果
当我们这样调用
这是它的汇编代码
这是add函数的汇编代码 其他的汇编代码不用管
00401078 push 8 //第二个参数的值
0040107A push 7 //第一个参数的值
0040107C call @ILT+20(add) (00401019)
00401081 add esp,8
根据上面这段汇编代码我们得知
调用add函数的代码,参数是这样传递的:
先分别把两个参数的值给传入栈中(一般都是自右向左的传入参数)
当call指令执行时 自动将call的下一条指令的地址(函数返回地址)传入栈中
然后跳到00401019这个地址
我们进这个call来看看
这个jmp只是用来作为中转的
继续执行
好 进来了
这个就是add函数的汇编代码
我们来分析这段汇编代码
//将ebp寄存器也就是栈底保存到栈中
push ebp
//ebp用来寻找栈空间地址 为了方便esp更好的操作栈空间
mov ebp,esp
//开辟内存大小为40h(注意是十六机制!)的栈空间
sub esp,40h
//这三个寄存器要拿来当指针操作
所以需要先保存,
程序返回时需要恢复,以免数据被破坏
push ebx //[ebp-4]
push esi //[ebp-8]
push edi //[ebp-0xC]
//填充栈空间
lea edi,[ebp-40h] //将栈顶的地址给edi
mov ecx,10h
mov eax,0CCCCCCCCh
//将eax的值放入edi的内存空间(栈)中 执行ecx次 每执行一次edi+4
//大致意思就是把栈空间全部填为CC
rep stos dword ptr [edi]
//这里是这个函数的主要功能
mov eax,dword ptr [ebp+8] //ebp+8存的就是我们第一个参数的值
add eax,dword ptr [ebp+0Ch] //ebp+0ch存的第二个参数的值
//恢复堆栈
pop edi
pop esi
pop ebx
//恢复栈顶
mov esp,ebp
//恢复栈底
pop ebp
//函数返回
//就是把eip寄存器的值
修改成函数返回地址(eip存的地址就是CPU下一条执行的指令)
ret
这样分析函数已经够详细了吧
如果还看不懂可能是基础不够
可以自己观察栈空间的数值变化 很有趣的!
网友评论