以下面的程序为例:
#include
using namespace std;
int sum(int a,int b)
{
int temp=0;
temp=a+b;
return temp;
}
int main()
{
int a=10;
int b=20;
int ret=sum(a,b);
cout<<ret<<endl;
return 0;
}
问题1:main函数调用sum,sum执行完后,怎么知道回到哪个函数中?
问题2:sum函数执行完,回到main后,怎么知道从哪行指令开始运行。
要描述一个栈,需要知道栈底和栈顶就可以了。其中esp来标识栈顶,ebp来标识栈底。(栈是从高地址向低地址增长的,所以ebp要比esp的地址大)
…esp
ret
b 10
a 20
…ebp0–0x0018ff40
…esp
10=》int a
20=》int b
ret
b 10
a 20
…ebp0–0x0018ff40
上述压栈完毕后,进行call sum,call sum做的第一件事就是,将call的下一行指令的地址进行压栈(解决了上面的问题二)!然后第二件事情才是进入sum。这里假设call指令的下一行代码的地址是0x08124458。过程如下:
…esp
0x08124458
10=》int a
20=》int b
ret
b 10
a 20
…ebp0–0x0018ff40
…esp
…ebp
0x0018ff40
0x08124458
10=》int a
20=》int b
ret
b 10
a 20
需要注意的是,temp=a+b的这一行代码,汇编指令中会有特殊的地址偏移,在栈上找到a和b的值。然后return temp这一行代码,是将temp的值放在了全局的eax寄存器上。
只有定义局部变量或者函数调用的时候才会进行压栈操作,其余的计算过程和return操作是不会在栈上体现的。
…esp
temp 0
…ebp
0x0018ff40
0x08124458
10=》int a
20=》int b
ret
b 10
a 20
…esp
0x08124458
10=》int a
20=》int b
ret
b 10
a 20
…ebp–0x0018ff40
…esp
10=》int a
20=》int b
ret
b 10
a 20
…ebp–0x0018ff40
…esp
ret
b 10
a 20
…ebp–0x0018ff40
…esp
ret 30
b 10
a 20
…ebp–0x0018ff40
下面回答问题1:问题1:main函数调用sum,sum执行完后,怎么知道回到哪个函数中?
就是通过压栈的顺序。
(未完待续,见视频)