- 函数的调用操作包括:从一块代码到另一块代码之间的双向数据传递换和执行控制。其中:数据传递:函数参数和返回值。
- 大多数CPU上的程序实现使用栈来支持函数调用操作。栈用来传递函数参数、存储返回信息、临时保存寄存器原有值以用于回复以及存储局部数据。
- 单个函数调用操作所使用的栈部分称为栈帧结果(stack
frame)。栈帧结构的两端由两个指针来指定。寄存器ebp通常用作栈帧的指针、esp用作栈的指针。esp随着数据的入栈和出栈。因此对于函数中大部分数据的访问都是通过基于帧帧指针ebp来实现。
如下图显示:
批注:在C语言中,如果C语言的地址符'&'被应用到一个局部变量时,栈则需要为该变量生成一个地址值即变量的地址值分配一个空间。
call和ret用于处理函数调用和返回操作。
call:把返回地址压入栈中并且跳转到调用函数开始处并且执行。
ret:调用ret之前要好好处理栈中的内容。使得当前栈指针所指向的位置刚好为call指令保存的返回地址。另外若函数返回一个整数或指针,那么用eax返回。
main():一个函数:在编译的链接的时候它将会作为Ctr0.s汇编程序的函数被调用。ctro.s是一个桩(stu)程序,它被链接在一个用户程序的开始部分,主要用于设置一些初始化的全局变量等。
举例;
void swap (int *a, int *b)
{
int c;
c= *a;
*a =
*b;
*b =
c;
}
void caller()
{
int i =0,b=3;
swap(&i,&b);
}
如图显示:(栈是向低地址扩展)
注意:对于返回地址的保存是在跳转到调用函数之前(调用swap之前),然后对调用函数callee的栈帧指针进行保存,此外以该栈(内存地址)作为swap的栈帧指针,通过对ebp的上下移动来调用函数的参数和局部变量。对于该函数的参数则是ebp加正整数,对于局部变量的引用是通过edp减一个整数。
ebp前面的e:32位寄存器
rbp前面的r:
64位寄存器
阅读(2773) | 评论(0) | 转发(1) |