C编译器是否优化汇编中的函数,以使对堆栈的使用最小化?

兰斯·波拉德

我开始学习汇编(在OSX上的NASM中为x86-64),现在正在探索函数的外观。

解释“调用约定”工作原理的大多数资源都按照以下方式显示示例:

// c code
MyFunction1(a, b);

// assembly code
main:
  push a
  push b
  push rbp ; save frame pointer on stack
  mov rsp, rbp  ; save stack pointer in frame pointer
  xor rax, rax  ; set function return value to 0.
  call _MyFunction
  mov rbp, rsp  ; restore stack pointer
  pop rbp ; restore frame pointer
  ret ; return to calling function

我只是在合并了几种资源之后才做出的,所以可能有很多问题,但这不在主要问题之列。

诸如cdecl调用约定之类的调用约定的要旨是:

  • 您以与在C代码中出现的方式相反的顺序推入参数。
  • 然后,您可以保存对框架指针和堆栈指针的引用(我猜是这样,您可以递归地执行此操作,但到目前为止还不知道)。
  • 然后,您可以计算出函数中所需的一切。
  • 然后,弹出堆栈,并从堆栈中弹出框架指针

因此,希望获得在汇编中使用堆栈和函数调用约定的更多实践经验,我希望看到现有的C编译器如何将函数调用转换为汇编(gcc和clang,非常有用)。但是,我没有看到调用约定模式(到目前为止,我所见过的每个资源都说过这是做到这一点的方法)!

检查一下,这是从某些C生成的相对复杂的汇编代码:

https://gist.github.com/lancejpollard/a1d6a9b4820473ed8797

查看该C代码,有几个层次的嵌套函数调用。但是输出程序集代码未显示该推/弹出堆栈模式!

所以问题是,这些编译器是否只是为了优化汇编程序而避免这样做?(因为该示例C代码虽然具有一些嵌套函数,但仍然非常简单,因此我认为编译器可以预先计算很多东西)。还是我错过了什么?

布伦丹

一般来说:

  • 如果某个函数可能被另一个目标文件中的某个东西调用(例如,该函数不是,static而您正在创建一个目标文件),则编译器必须遵守调用约定(以便链接可以工作)。
  • 如果您要进行调试编译,那么典型的调试器将使用堆栈框架查找内容(输入参数,局部变量等),并且性能并不是优先考虑的事情,因此遵守调用约定是一个好主意。

对于所有其他情况,编译器可以自由地完全忽略调用约定,并且可以做任何它认为更有效的事情(包括在寄存器中传递参数,而不使用堆栈或帧指针,还包括完全内联函数)。

然而:

  • 在某些情况下(例如,函数指针和具有可变数量的参数的函数),编译器可能无法做很多事情,并且可能仅使用标准的调用约定(即使严格不需要)。
  • 编译器可能会生成2个或更多不同版本的函数(例如,一个遵循其他对象文件中的代码可以使用的调用约定的版本,以及另一个不遵循调用约定的优化版本)。
  • 链接器可能会优化编译器无法进行的优化(链接时间优化),包括修改编译器无法优化的函数的调用约定(因为编译器对潜在调用者的了解不足),但是链接器可以(因为链接程序“看到”整个程序)。

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

C编译器是否优化汇编中的函数,以使对堆栈的使用最小化?

来自分类Dev

编译器可以优化汇编中的函数序言吗?

来自分类Dev

使用scipy最小化函数。使用ipython优化并行

来自分类Dev

优化问题 - 最小化 R 中的函数

来自分类Dev

编译器优化是否可以消除在for循环的条件中反复调用的函数?

来自分类Dev

是否对不使用模板参数的模板化类的方法进行了编译器优化?

来自分类Dev

是否可以使用C#编译器添加PostSharp进行动态编译

来自分类Dev

是否允许C编译器优化掉多余的语句?

来自分类Dev

是否允许C编译器优化掉多余的语句?

来自分类Dev

C ++编译器优化放弃模板专业化

来自分类Dev

确定C ++编译器是否将在Visual Studio中以某种方式进行优化

来自分类Dev

C#编译器或JIT是否可以优化Lambda表达式中的方法调用?

来自分类Dev

确定C ++编译器是否将在Visual Studio中以某种方式进行优化

来自分类Dev

C编译器是否使用单个成员优化结构?

来自分类Dev

使用列表初始化时,C ++语言是否会强制执行编译器优化?

来自分类Dev

如何告诉编译器不要优化内联汇编中使用的变量?

来自分类Dev

编译器设计中的内联汇编

来自分类Dev

C / C ++优化编译器由于使用模板而损坏

来自分类Dev

编译器是否优化String文字?

来自分类Dev

使用寄存器而不是堆栈从x64汇编中调用C函数

来自分类Dev

使用寄存器而不是堆栈从x64汇编中调用C函数

来自分类Dev

我可以使用C / C ++编译器吗?

来自分类Dev

R中的字节编译器优化

来自分类Dev

在SBCL中检查编译器优化

来自分类Dev

gcc中的编译器优化

来自分类Dev

R中的字节编译器优化

来自分类Dev

了解MSVS C ++编译器优化

来自分类Dev

C#编译器优化

来自分类Dev

C 编译器优化的基准

Related 相关文章

  1. 1

    C编译器是否优化汇编中的函数,以使对堆栈的使用最小化?

  2. 2

    编译器可以优化汇编中的函数序言吗?

  3. 3

    使用scipy最小化函数。使用ipython优化并行

  4. 4

    优化问题 - 最小化 R 中的函数

  5. 5

    编译器优化是否可以消除在for循环的条件中反复调用的函数?

  6. 6

    是否对不使用模板参数的模板化类的方法进行了编译器优化?

  7. 7

    是否可以使用C#编译器添加PostSharp进行动态编译

  8. 8

    是否允许C编译器优化掉多余的语句?

  9. 9

    是否允许C编译器优化掉多余的语句?

  10. 10

    C ++编译器优化放弃模板专业化

  11. 11

    确定C ++编译器是否将在Visual Studio中以某种方式进行优化

  12. 12

    C#编译器或JIT是否可以优化Lambda表达式中的方法调用?

  13. 13

    确定C ++编译器是否将在Visual Studio中以某种方式进行优化

  14. 14

    C编译器是否使用单个成员优化结构?

  15. 15

    使用列表初始化时,C ++语言是否会强制执行编译器优化?

  16. 16

    如何告诉编译器不要优化内联汇编中使用的变量?

  17. 17

    编译器设计中的内联汇编

  18. 18

    C / C ++优化编译器由于使用模板而损坏

  19. 19

    编译器是否优化String文字?

  20. 20

    使用寄存器而不是堆栈从x64汇编中调用C函数

  21. 21

    使用寄存器而不是堆栈从x64汇编中调用C函数

  22. 22

    我可以使用C / C ++编译器吗?

  23. 23

    R中的字节编译器优化

  24. 24

    在SBCL中检查编译器优化

  25. 25

    gcc中的编译器优化

  26. 26

    R中的字节编译器优化

  27. 27

    了解MSVS C ++编译器优化

  28. 28

    C#编译器优化

  29. 29

    C 编译器优化的基准

热门标签

归档