首先,插入一段代码:
#include <stdio.h>
int myadd(int x,int y)
{
int z=x+y;
return z;
}
int main()
{
int a = 0xaaaaaaaa;
int b = 0xbbbbbbbb;
int c = myadd(a,b);
printf("you should runhere!:%d\n");
return 0;
}
在VC6.0下运行该程序;
转换成汇编语言:
做一些概念的说明:
通用寄存器:EAX、EBX、ECX、EDX……
EIP(PC):程序计数器(保存正在执行指令的下一条指令地址)
ESP:栈顶
EBP:栈底
及一些汇编语言的含义:
mov 将数据放置区域
push:入栈
pop:出栈
add:两者相加
sub:相减
call:1.保存当前汇编指令的下一条指令地址(入栈保存),目的是为了恢复;
2.跳转至目标函数的入口处(修改EIP)(jmp)
ret:1.将当前保存的函数的返回值的地址出栈;将弹出的数据修改EIP;
2.常规的临时变量通过寄存器返回,从而将结果拿回。
对a、b进行入栈;
将b的值放在EAX中;
将a的值放在ECX中;
形参实例化顺序:从右至左(先b后a);
执行call命令:
将下一条指令的地址00401093存入0018FEE4中(小端);
并跳转至myadd函数;
修改EIP:
跳转至myadd函数:
开始执行myadd函数:
此时,EBP、ESP指向同一位置。
接下来执行 sub ESP,44h;
此时,蓝色框中形成栈帧结构,供myadd函数使用;EIP中存放的为myadd函数的地址。
把a的值放在EAX里,再将a+b的值放在EAX里。
然后:
将EBP弹出,ESP上移;
此时,栈帧结构释放,执行ret;
EIP变为00401093,回到了下一条指令的地址。
再执行add esp,8;
过程调用结束,临时变量被释放。
返回值通过EAX寄存器返回。
函数调用结束。