一个很简单的例子,从汇编层次理解函数调用
虽然这种东西在书上网上很多,自己动手做一遍还是很有收获的。
测试例子
#include<stdio.h>
int test_function(int a, int b)
{
printf("hello world, %d,%d\n",a,b);
}
int main()
{
test_function(1,2);
}
main函数中:执行call后,eip的值进栈,存放的是从函数调用返回后继续执行的指令的地址(本例子中是leave指令,地址为0x08048424)
test_function函数中:在函数序言部分,将ebp压栈,重置esp和ebp的值,建立test_function的栈(本例子中ebp的值为0xbffff288,压在0xbffff268处,再将ebp置为0xbffff268,esp置为0xbffff250)新的ebp指向旧ebp的值(即ebp的值是一个内存地址,这个内存单元存放的是旧的ebp的值)
test_function函数中:执行leave后:test_function栈清空,将ebp恢复成main函数的ebp值,esp指向待执行的main函数中的指令的地址
test_functino函数中:执行ret后:将待执行的main函数中的指令的地址恢复到eip中,此后完全进入main函数中。
根据以上过程绘制的图示:xxxxxx表示此地址内容无意义
-
调用test_function前指针位置
调用test_function后指针位置
内容
地址
esp(test_f)
0x8048500
0xbffff250
1
0xbffff254
2
0xbffff258
xxxxxxxx
xxxxxxxx
xxxxxxxx
ebp(test_f)
0xbffff288 ($ebp(main))
0xbffff268
0x08048424(main中leave)
0xbffff26c
esp(main)
1
0xbffff270
2
0xbffff274
xxxxxxxx
xxxxxxxx
xxxxxxxx
xxxxxxxx
ebp(main)
ebp(old)
0xbffff288
xxxxxxxx内容是什么东西,有待进一步学习。