2012-10-03 124 views
1

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

有人可以解释吗?

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

回答

2

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

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

+0

是感谢一些好的链接您!现在我发现它被称为传递价值,并通过引用。所以它说,当你按值传递时,函数在一个已经被复制到堆栈的值上运行。那么为什么你需要通过价值传递? – Apeee

+1

按价值传递更安全。当您正在调用的函数不需要修改该值时,如果您通过引用传递,则调用者必须非常小心或有风险破坏被调用者不希望更改的数据。这是正常情况,对通过引用的真正需求不太常见。 – mah

+1

取决于你想要做什么。如果你希望你的变量值在功能调用后不应该改变......你可以通过值发送它。如果你希望他们改变......你可以通过引用或指针发送它。例如,数组总是通过指针传递。 – rahul

2

堆栈在大多数情况下用于将参数传递给函数。使用它的原因是你没有被绑定到固定的存储空间(用于参数)来让你的函数起作用。如果你有可以从固定内存中获取参数的函数,那么如果内存是空闲的,你可能只能运行它,你只能运行它的一个实例。 Stack可以随时将您的参数存储到程序的当前上下文中。在x86处理器上,有一个寄存器指向堆栈的末尾,另一个寄存器指向开始。这些实际上只是您希望堆栈驻留的主要内存的地址。

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

还有一些不太常用的选项可以像通过寄存器那样传递参数,例如bios中断。如果你想更多地了解这一点,我建议你阅读“调用约定”。

+0

非常好的解释!!我现在明白了,但是我不明白你在做什么在这里nt:“这样,如果你坚持计划并跟踪你推入堆栈的内容,你可以从任何上下文中使用你的函数。 “ – Apeee

+0

这个部分实际上是由编译器为你完成的,如果你用栈传递参数,你的编译器将它们压入堆栈,之后它将它们称为堆栈结束寄存器+4 +8 +12等等..可能发生的是,你传递了一些像(int,int,char,short int,int)这样的地址有点麻烦的东西,因为char只是1个字节而short int是2个字节。所以它会被解决像+8 +12 +13 +15 +19 ..这就是我的意思是跟踪你推动堆栈。 (参数在+8开始,因为通用编译器在参数之前推入了另外两个int) – Pyjong

+0

我不会通过寄存器传递参数“less used option”,因为它通常用在x86-64上。 –

0

让我们开始这个假设你有一个函数

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

所以每当一个函数调用由操作系统需要一定的存储空间,在这种情况下和参数传递的功能分配功能int a的局部变量在这种情况下为int value。该内存需求通过在堆栈上分配内存来实现。堆栈不过是分配给每个进程的内存区域,它实际上表现为堆栈数据结构(LIFO)。

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

一旦被调用的函数完成执行代码,它将返回到先前存储在堆栈上的返回地址,因此我们说函数调用完成或返回。 在这种情况下,函数有一个返回值,它返回到被调用函数。 该空间随后可以自由使用,并可在随后的函数调用中被覆盖。(现在如果连接了dotes,你可以意识到为什么函数中的局部变量(自动变量)的范围局限于函数调用的生命期(你问了一个与被关闭的范围有关的SO问题),因为一旦调用返回分配给这些语言环境变量的内存空间消失(这是仍然存在,但你不能一次访问它们的函数返回),所以在这种情况下,限制直至foo()返回到调用函数,这些自动变量int a的生活。

注意:我已经阅读了许多你在SO中发布过的问题,我想你一般都是在学习C和底层硬件和操作系统的基本工作,并且他们之间的混淆正在消灭你。我会建议你除了回答这个问题外,还要阅读和理解哪些内容,这些内容可以让你深入了解你所面临的问题。

  1. 对于C参考K & R它是最好的书。
  2. 在开始阅读有关操作系统概念(内存处理,特别是虚拟内存)的一点点读取
  3. 尝试想象广义上的系统工作,就像不同组件之间的交互方式一样。
  4. 理解记忆相关的东西和系统内部http://duartes.org/gustavo/blog/best-of

,如果你想潜入函数调用堆栈空间尝试此链接http://www.binarypirates.in/2011/02/17/understanding-function-stack-in-c/

希望这有助于