Eng*_*999 6 c x86 assembly stack abi
无论如何,就 x86 汇编代码而言。我一直在阅读有关函数调用的内容,但仍然无法完全掌握对基/帧指针 (EBP) 和堆栈指针 (ESP) 的需求。
当我们调用一个函数时,EBP的当前值会被放入栈中,然后EBP获取当前的ESP值。
函数的返回值、函数参数和局部变量的占位符然后将被放置在堆栈中,并且堆栈指针 ESP 值将减少(或增加)指向放置在堆栈上的最后一个占位符之后。
现在我们让 EBP 指向当前堆栈帧的开头,而 ESP 指向堆栈帧的结尾。
由于与 EBP 的恒定偏移量,EBP 将用于访问函数的参数和局部变量。那没关系。我不明白的是,为什么 ESP 不能通过使用其偏移量来访问这些变量。EBP指向栈帧的开头,ESP指向栈帧的结尾。有什么不同?
一旦所有局部变量等有了占位符,ESP 就不应该改变,还是应该改变?
从技术上讲,可以(但有时很难)跟踪堆栈上存储了多少局部变量和临时变量,以便无需 EBP 即可访问函数输入和局部变量。
考虑以下“C”代码;
int func(int arg) {
int result ;
double x[arg+5] ;
// Do something with x, calculate result
return result ;
} ;
Run Code Online (Sandbox Code Playgroud)
存储在堆栈中的项目数现在是变量(arg+5 个 double 项目)。从堆栈中计算“arg”的位置需要运行时计算,这可能会对性能产生显着的负面影响。
使用额外寄存器(EBP),arg 的位置始终位于固定位置(EBP-2)。执行“返回”总是很简单 - 将 BP 移动到 SP,然后返回,等等。
底线是,将 EBP 寄存器提交给单个函数(而不是将其用作通用寄存器)的决定是性能、简单性、代码大小和其他因素之间的权衡。实践经验表明,收益大于成本。