0

我也是 C/C++ 和汇编语言的新手。这也可能是非常基本的问题。我试图了解堆栈帧是如何构建的以及哪些变量(参数)以什么顺序被推送到堆栈?一些搜索结果表明...... C/C++ 的编译器根据函数内执行的操作来决定。例如,如果假设函数只是将传递的 int 参数的值增加 1 并返回(类似于 ++ 运算符),它将把函数的所有参数和局部变量放在寄存器中的函数中并执行加法。 ...想知道哪个寄存器用于返回/按值传递?....如何返回引用?.....b/w eax、ebx、ecx 和 edx 的区别。

请求一本书/博客/链接或任何类型的材料来理解寄存器,堆栈和堆引用在函数调用期间被使用/构建和销毁......以及如何存储主函数?提前致谢

4

2 回答 2

5

你的问题在这里是临界的。程序员可能是一个更好的地方。

理解堆栈等概念的好书可能是 Queinnec 的Lisp In Small Pieces(它很好地解释了 Lisp 的堆栈是什么)。此外,SICP 一本好书

D.Knuth的书和MMIX也不错。

仔细阅读 Wikipedia调用堆栈页面。

理论上,不需要调用堆栈,并且一些语言和实现(例如旧的 SML/NJ)不使用任何堆栈(而是在垃圾收集堆中分配调用帧)。请参阅 A.Appel 的旧论文Garbage Collection Can be Faster than Stack Allocation(并了解有关一般垃圾收集的更多信息)。

通常 C 和 C++ 实现都有一个堆栈(并且经常使用硬件堆栈)。一些 C 局部变量可能没有任何堆栈位置(因为它们已经过优化,或者保存在寄存器中)。有时,C 局部变量的堆栈位置可能会改变(编译器会在某些情况下使用一个调用堆栈槽,而对同一局部变量的其他情况使用另一个调用堆栈槽)。当然,一些临时值可能会像您的局部变量一样编译(所以留在一个寄存器中,在一个堆栈槽中,然后在另一个堆栈槽中,等等......)。在优化编译器时,可能会用变量做一些奇怪的技巧。

在一些老机器IBM/360或 I BM z/series上,没有硬件栈;C 编译器使用的堆栈是一种软件约定(例如,某些寄存器专用于该用途,没有特定的硬件支持)

想想递归定义的函数的执行(或解释)(比如天真的代码)。阅读有关递归(一般而言,在计算机科学中)、原始递归函数lambda 演算指称语义堆栈自动机寄存器分配尾调用延续ABI中断Posix 信号sigaltstack(2)getcontext(2)longjmp(3)等等……等等……

另请阅读有关计算机体系结构的书籍。在实践中,调用堆栈非常重要,以至于一些硬件资源(包括堆栈指针寄存器,通常是调用帧基指针寄存器,可能还有隐藏的机器,例如缓存相关)在公共处理器上专用于它。

您还可以查看 GCC 编译器使用的中间表示。然后使用-fdump-tree-allGCC MELT 探针。如果查看生成的程序集,请务必传递-S -fverbose-asm给您的gcc命令。

另请参阅linux 程序集 howto

我给了很多链接。很难更好地回答,因为我不知道你的背景。

于 2013-04-18T16:18:19.730 回答
3

我试图了解堆栈帧是如何构建的以及哪些变量(参数)以什么顺序被推送到堆栈?

这取决于处理器的架构。但是,通常,堆栈从高地址向低地址增长(如果我们将内存地址视为数值)。一个堆栈帧是“这个函数放在堆栈上的任何东西”

放入堆栈的“东西”通常是:

  • 将地址返回给调用函数。
  • 一个帧指针,指向调用开始时的堆栈帧。
  • 当此函数返回时,需要“保留”的已保存寄存器。
  • 局部变量。
  • 调用堆栈中“下一个”函数的参数。

C/C++ 的编译器根据函数内执行的操作来决定。例如,如果假设函数只是将传递的 int 参数的值增加 1 并返回(类似于 ++ 运算符),它将把所有 ... 函数的参数和函数内的局部变量放在寄存器中并执行加法....想知道哪个寄存器用于返回/按值传递?....如何返回引用?

编译器有关于如何传递参数的规则,对于常规函数调用[即不是“内联”函数],参数总是以相同的顺序传递,在寄存器和堆栈内存的相同组合中。如果不是这种情况,编译器在决定传递参数之前必须确切地知道函数做了什么。

不同的处理器架构有不同的规则。x86-32 通常有一个或两个用于输入参数的寄存器,并且通常有一个用于返回值的寄存器。x86-64 最多使用 5 个寄存器将前五个值传递给函数。任何进一步的参数都在寄存器中传递。

返回引用与返回任何其他值没有什么不同。值(在这种情况下是返回对象的地址)。在 x86-32 中,返回值在 EAX 中。在 x86-64 中,返回值在 RAX 中。在 ARM 中,R0 用于返回值。在 29K 中,R96 用于返回值。

于 2013-04-18T17:02:33.340 回答