本文将对函数栈进行解析,在此之前先对程序的内存分配有个大概了解。
程序内存逻辑分配
一个程序中内存分布如下图:
代码段:保存程序文本,可读可执行不可写,指令寄存器EIP指向代码段中将要执行的代码行首地址
数据段:保存已初始化的全局变量和静态变量,可读可写不可执行
BBS:未初始化的全局变量和静态变量
Heap(堆):动态内存,数据存放向内存高端增长,可读可写可执行
Stack(栈):存放局部变量,函数参数,函数调用信息,寄存器状态等,函数栈便是在栈区,数据存放向内存低端增长,可读可写可执行
简单介绍下几个常用的寄存器
通用寄存器:
EAX:累加寄存器。用于算术运算的主要寄存器,也常用来存放函数的返回值。在保护模式下也可作为内存偏移指针。
ECX:计数器寄存器。常用于特定指令的计数。
EBX:基地址寄存器。内存寻址时用于存放基地址。
EDX:多功能寄存器。常用于乘除法和I/0指针。
ESI:源变址寄存器。通常在内存操作指令中作为“源地址指针”使用。
EDI:目的变址寄存器。通常在内存操作指令中作为“目的地址指针”使用。
ESP:栈指针。作为指针指向当前栈的栈顶(栈顶为栈的低地址)。
EBP:帧指针。作为指针指向当前栈的栈底(栈底为栈的高地址)。
EIP:指令寄存器。作为指针指向下一条指令,该寄存器的值不能直接修改。
函数栈解析:
本文将以一个示例程序对函数栈进行解析: