汇编程序中的主要过程是否需要堆栈框架?

时间:2019-06-17 00:41:39

标签: assembly x86

如果主过程具有局部变量并更改了堆栈指针,您是否应该像在常规过程中那样麻烦地制作堆栈框架?

2 个答案:

答案 0 :(得分:2)

  

汇编程序中的主过程是否需要堆栈框架?

如果您查看一个完整的系统(从固件到网页中埋藏的一些JavaScript的所有内容);该软件是摇摇欲坠的不稳定碎片的高塔(可能像Jenga)。

此塔的底部是机器代码-数字,其中的硬件(CPU)以某些方式对不同的数字做出反应。在此级别上,没有过程,也没有堆栈。只是可能会或可能不会用于实施程序和指令(例如callpush)的可能会或可能不会用于实现堆栈的指令(例如,{{1})。

下一层是汇编语言-机器代码的文本表示。在此级别上,可能仍然存在或可能没有过程,并且可能存在或可能不是堆栈。在某些情况下(配置内存控制器之前执行的固件中的早期启动代码)甚至可能没有可用的RAM。

下一层是一堆约定,这些约定通常是从高级语言的实现中窃取的。这是过程/函数,堆栈,调用约定等。当然,对于不同的语言和同一语言的不同实现,这可以完全不同。并且(至少在理论上-例如,设计用于“连续传递样式”的语言,并且没有别的东西)可能仍不包括过程之类的东西,并且-(至少在理论上-例如,具有用于将所有代码转换为查找表)可能不包括堆栈,如果有一个堆栈,则实际上可能是两个(或更多?)堆栈(例如,出于安全性/控制流完整性的目的,一个堆栈用于控制流,另一个堆栈用于数据)。 / p>

下一层是一堆用于调试的约定。这就是帧指针的来源(出于向旧C编译器的实现中添加调试的愿望)。当然,对于更现代的系统,调试器已经转向了“更少愚蠢”的方法(将信息调试器需要从存在性能/优化问题的机器代码中转移到特殊的表中,例如DWARF的“呼叫帧信息表”)

本质上;对于程序集本身,可能没有过程,没有堆栈,也没有框架指针;但是,如果汇编语言程序员尝试编写符合“环境约定”的代码,则他们可能会使用过程并且可能会使用框架指针。

例如,下面是一些用于简单计算器的“伪程序集”:

pop

答案 1 :(得分:1)

简单的答案:这取决于

最佳实践答案:可能

懒惰的答案:如果它不崩溃,那就足够了。 (/ sarcasm)

详细答案:

这实际上取决于您对函数的处理方式。实际上,堆栈帧链接省略是一些编译器自己进行的优化。 (据我所知,它可能会省略堆栈框架的创建。)

实际上,除非您的代码需要它们,否则堆栈框架仅存在于调试目的(使遍历堆栈更容易)。我会给您一个小秘密:只要函数返回时,计算机就不会给出两个段错误,只要函数返回,堆栈就处于调用该函数时的状态。 (豁免某些希望被调用函数清除堆栈的ABI。)

因此,实际上,您不需要堆栈框架。如果要实际从函数中返回,甚至不需要堆栈框架,只要堆栈指针与输入时相同即可。

如果要通过返回退出,那么是的,您需要恢复堆栈指针。如果您通过调用exit退出,那么就如何对待堆栈而言,这是一个非常公平的游戏。 (只要您确保中断句柄不会破坏任何程序数据即可。)

尽管我同意您对原始问题的评论。准确了解您要定位的ABI很有帮助。因为虽然我通常说的是正确的,但是某些ABI会使事情变得很奇怪,并且在不知道您针对哪个ABI的情况下,无法给出明确的答案。