在经典的操作系统里,栈总是向下增长的。在i386下,栈顶由称为esp的寄存器进行定位,压栈的操作使栈顶的地址减小,弹出的操作使栈顶地址增大
eax是累加器,它是很多加法乘法指令的缺省寄存器。
ebx是基地址(base)寄存器,在内存寻址时存放的基地址
eax是计数器(counter),是重复前缀指令和Loop指令的内定计数器
edx则总是被用来存放整数除法产生的余数
c语言可以把这些寄存器当做变量看待
ebp(栈底指针寄存器) esp(栈顶指针寄存器)
#include<stdio.h>
int sum(int a,int b)
{
int tmp;
tmp=a+b;
return tmp;
}
int main()
{
int a1=10;
int b1=20;
int rt=0;
rt = sum(a1,b1);
printf("sum(a,b):%d",rt);
return 0;
}
进入sum函数前main函数的栈帧布局:
进入sum函数后
栈在程序运行中具有举足轻重的地位,最重要的,栈保存了一个函数调用所需要的维护信息,这些常常被称为堆栈帧或活动记录,堆栈帧一般包括如下几个方面的内容:
1、函数的返回地址和参数
2、临时变量:包括函数的非静态局部变量,以及编译器自动生成的其他临时变量。
3、保存的上下文:包括函数调用前后需要保持不变的寄存器。
为什么被调用函数调用完成后回退到调用方栈帧?
进入被调用栈帧后,压入了调用方ebp的值
被调用函数调用完成后,怎么知道沿着下一条指令继续执行?
函数调用时压入了下一行指令地址
形参有没有开辟内存/谁开辟的
开辟内存:调用方 清理内存:调用方
return 后 返回值赋给了exa寄存器,由eax寄存器带回main函数赋给被调函数。