函数调用,堆栈

时间:2012-10-03 12:57:40

标签: c stack

所以我不知道为什么但是我了解到当你调用一个函数并向它传递一个参数时,它会在堆栈上处理它(处理器?)。

有人可以解释一下吗?

那么它如何改变变量值,内存块等等?

3 个答案:

答案 0 :(得分:2)

无法保证参数在堆栈上传递,它依赖于体系结构和编译器。

关于值和内存如何变化 - 当你调用一个必须进行调用者看到的更改的函数时,你提供的不是实际值,而是(指向)的地址是正常的那个价值。只要函数知道正确的内存位置,它就可以进行这些更改。

答案 1 :(得分:2)

在大多数情况下使用Stack将参数传递给function。使用它的原因是你没有绑定到固定的内存位置(用于参数)以使你的功能正常运行。如果你有可以从固定内存获取参数的函数,你可能只能在内存空闲时运行它,并且你只能运行它的一个实例。 Stack使您可以随时将参数存储到程序的当前上下文中。在x86处理器上,有一个指向堆栈末尾的寄存器和指向开头的其他寄存器。这些只是你希望你的堆栈驻留的主存储器的地址。

有PUSH指令将堆栈结束寄存器移动到下一个位置,并将指定数据(可以是来自其他寄存器或某个地址或直接值的值)存储到堆栈结束寄存器指向的地址。另一条指令是POP,它的工作原理相反。这样,如果您坚持计划并跟踪推送到堆栈的内容,您可以在任何上下文中使用您的功能。

还有一些其他较少使用的选项来传递诸如via寄存器之类的参数,这些参数例如由bios中断使用。如果您想了解更多相关信息,我建议您阅读“呼叫约定”。

答案 2 :(得分:0)

让我们开始假设你有一个功能

int foo(int value) {
   int a = 10;
   return a;
}

因此,每当进行函数调用时,OS需要一些内存空间来分配函数int a的局部变量,在这种情况下,函数的参数传递给int value。通过在堆栈上分配内存来满足此内存要求。堆栈只是分配给每个进程的内存区域,它实际上表现为堆栈数据结构(LIFO)。

现在出现的问题是,在进行函数调用时,所有内容都存储在堆栈中。推送到堆栈的第一件事是以相反的顺序传递给函数的参数(如果多于一个)。 2.然后调用此函数的函数的返回地址(因为一旦此函数foo完成执行,它应该返回到调用它的代码中的位置) 3.最后调用的函数的局部变量被压入堆栈。

一旦被调用的函数完成执行代码,它就会返回到先前存储在堆栈中的返回地址,因此我们说函数调用完成或返回。 在这种情况下,函数有一个返回值,它返回到被调用函数。 然后可以自由使用该空间,并且可以在随后的函数调用中覆盖该空间。

(现在,如果你连接了dotes,你可以意识到为什么函数中的局部变量(自动变量)的范围仅限于函数调用的生命周期(你问过一个与关闭范围有关的SO问题),因为一旦调用返回为这些语言环境变量分配的内存空间已经消失(它仍然存在,但是一旦函数返回就无法访问它们),因此在这种情况下,这些自动变量int a的生命周期限制为foo()返回到被叫函数。

旁注::我已经阅读了您在SO中发布的许多问题。我想你一直在努力学习C和底层硬件和操作系统的基本工作,它们之间的混乱正在扼杀你。 除了这个问题的答案之外,我建议你一些指导,以便阅读和理解哪些内容可以让你深入了解你所面临的问题。

  1. 对于C,请参阅K& R,这是最好的书。
  2. 在开始阅读有关OS概念(内存处理,特别是虚拟内存)的一点点
  3. 试着想象一下广义上系统的工作方式,以及不同组件之间的交互方式。
  4. 了解内存相关内容和系统内部的一些很好的链接http://duartes.org/gustavo/blog/best-of
  5. 如果您想深入了解函数调用的堆栈空间,请尝试使用此链接http://www.binarypirates.in/2011/02/17/understanding-function-stack-in-c/

    希望这有帮助