我只是想知道究竟是什么导致没有生成序言/结尾的功能?如果程序仅使用stdcall / cdecl约定进行编译,为什么会有一些调用导致子例程没有典型的push ebp-> mov ebp,esp。这些仅仅是编译器生成的健全性检查吗?这些子例程重要吗?还是如果不进行实际分析就无法说出来吗?例如,编译器会产生对子例程的调用,该子例程将一个值移入eax然后返回,或者程序员将更改可执行文件的二进制文件吗?

评论

您是否知道序言/结尾的目的是什么?

此序言代码所做的是保存堆栈帧地址。稍后,在函数结尾处,在结尾代码中,将再次恢复堆栈帧。如果愿意,可以在编译器标志中禁用此行为。

相关:stackoverflow.com/questions/43310704/…

#1 楼

CPU不需要序言和结尾语来执行功能,因此大多数编译器仅在必要时才生成它们,否则就不会启用优化。特别是,叶子函数(不调用其他函数的叶子函数)通常不需要序言(除非ABI要求),并且编译器可以安全地忽略它。

#2 楼

框架指针省略编译器选项:
https://msdn.microsoft.com/zh-cn/library/2kxx5t2c.aspx

对于gcc,请参见-fomit-frame-pointer
https://gcc.gnu.org/onlinedocs/gcc-4.5.2/gcc/Optimize-Options.html

评论


这对于Microsoft的编译器来说是非常特定的-表示没有编译器,即使不需要时也会生成序言/结尾。我敢说还有另一个更好的理由。

–杂件
18年1月4日在16:51

不,它会禁用/ Oy指定的序言/结尾生成。这是发布版本的默认行为。但是,如果您仍然希望发布代码中有序言,则可以指定/ Oy-。

–安东·库科巴(Anton Kukoba)
18年1月5日,9:36