C++(嵌套)函数调用指令 - 寄存器 [英] C++ (nested) function call instructions - registers

查看:38
本文介绍了C++(嵌套)函数调用指令 - 寄存器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

C++ 常见问题解答中:

假设一个典型的 C++ 实现有寄存器和堆栈,寄存器和参数在调用 g(),然后从 g() 内部的堆栈中读取参数并在 g() 返回到 f() 时再次读取以恢复寄存器.

Assuming a typical C++ implementation that has registers and a stack, the registers and parameters get written to the stack just before the call to g(), then the parameters get read from the stack inside g() and read again to restore the registers while g() returns to f().

关于嵌套函数调用

void f()
{
  int x = /*...*/;
  int y = /*...*/;
  int z = /*...*/;
  ...code that uses x, y and z...
  g(x, y, z);
  ...more code that uses x, y and z...
}

1/是否所有的 C++ 实现都带有寄存器和堆栈?这是否意味着:实现依赖于编译器/处理器/计算机架构?

1/ Are all implementation of C++ with registers and stack? Does it mean: implementation dependent on compiler/processor/computer architecture?

2/当我调用 f() 时,指令序列是什么(没有汇编语言,只有大图)?我已经阅读了关于这个主题的不同内容,而且我不记得提到的寄存器,而只是堆栈.

2/ What is sequence of instructions (without assembly language, just the big picture) when i call f() ? I have read diverging things on this topic, and also I don't remember that registers where mentionned, but only stack.

3/在处理嵌套函数时,还有哪些额外的特性/要点需要强调?

3/ what are additional specificities/points to underline when you deal with nested functions?

谢谢

推荐答案

对于 2 这取决于许多因素,包括编译器和平台.基本上,向函数传递和返回参数的不同方式称为调用约定.文章 x86 平台上的调用约定 详细介绍了操作顺序和您可以看到仅使用平台和编译器的这一小组合就变得多么丑陋和复杂,这很可能是您听说过各种不同场景的原因,函数调用约定的 gen. 涵盖了更广泛的场景集,包括 64 位 平台,但更难阅读.它变得更加复杂,因为 gcc 实际上可能不会pushpop 堆栈而是直接操作堆栈指针,我们可以看到一个例子,尽管在此处的汇编中.调用约定很难概括,如果参数的数量足够小,许多调用约定可以完全避免使用stack,而是只使用registers.

For number 2 this depends on many things including the compiler and the platform. Basically the different ways of passing and returning arguments to functions are called calling conventions. the article Calling conventions on the x86 platform goes into some detail on sequence of operations and you can see how ugly and complicated it gets with just this small combination of platforms and compilers which is most likely why you have heard all sorts of different scenarios, The gen on function calling conventions. covers a wider set of scenarios including 64 bit platforms but is harder to read. It gets even more complicated because gcc may not actually push and pop the stack but directly manipulate the stack pointer, we can see an example of this, albeit in assembly here. It is hard to generalize about calling conventions, if the number of arguments is small enough many calling conventions can avoid using the stack at all and will use registers exclusively.

对于数字3,嵌套函数没有任何改变,它只是在下一次函数调用时重复这个过程.

As to number 3, nested functions does not change anything, it will just repeat the procedure over again for the next function call.

至于数字 1 正如 Sean 指出的那样,.Net 编译为字节码,并在堆栈上执行所有操作.Common Intermediate Language 上的维基百科页面有一个很好的例子.

As to number 1 As Sean pointed out .Net compiles to byte code with performs all it's operations on the stack. The Wikipedia page on Common Intermediate Language has a good example.

x86-64 ABI 文档 如果您想详细了解一个特定的调用约定是如何工作的,这是另一个很棒的文档.图 3.5 和 3.6 很简洁,因为它们给出了一个很好的例子,展示了一个有很多参数的函数,以及如何使用通用寄存器浮动的组合来传递每个参数点寄存器堆栈.在查看涵盖调用约定的文档时,这种漂亮的图表很少见.

The x86-64 ABI document is another great document if you want to understand how one specific calling convention works in detail. Figure 3.5 and 3.6 are neat since they give a nice example of a function with many parameters and how each parameter is passed using a combination of general purpose registers, floating point registers and the stack. This sort of nice diagram is a rare find when looking at documents that cover calling conventions.

这篇关于C++(嵌套)函数调用指令 - 寄存器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆