c - 在使用堆栈方面,为什么我们需要一个基指针和一个堆栈指针

标签 c assembly x86 stack abi

这个问题在这里已经有了答案:





Why is it better to use the ebp than the esp register to locate parameters on the stack?

(1 个回答)



What is the purpose of the EBP frame pointer register?

(5 个回答)


2年前关闭。




无论如何,就 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 ;
} ;

存储在堆栈中的项目数现在是变量(arg+5 个 double 项目)。从堆栈中计算“arg”的位置需要运行时计算,这会对性能产生重大的负面影响。

使用额外寄存器 (EBP),arg 的位置始终位于固定位置 (EBP-2)。执行“返回”总是很简单——将 BP 移动到 SP,然后返回,等等。

归根结底,将 EBP 寄存器提交给单个函数(而不是将其用作通用寄存器)的决定是性能、简单性、代码大小和其他因素之间的权衡。实践经验表明, yield 大于成本。

关于c - 在使用堆栈方面,为什么我们需要一个基指针和一个堆栈指针,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58226249/

相关文章:

c - 使用指定初始值设定项时不同的 gcc 程序集

assembly - 替代x86汇编的“调用”指令?

assembly - REP 指令是否被视为向量运算?

c - 指向同一堆区域的随机地址的双指针

c - 如何在c中输出char数组

assembly - 我如何获得负股息的正模

gcc - GNU 汇编宏

c - 为什么我的字符串的第一个字母不打印?

c - 关于实现新的传输协议(protocol)

assembly - 什么是 ESP 和 EBP 寄存器?