函数调用,堆栈
回答
无法保证参数在堆栈上传递,它依赖于体系结构和编译器。
至于值和内存是如何改变的 - 当你调用一个必须做调用者看到的更改的函数时,你提供的内容不是实际值,而是指向)那个价值。只要函数知道正确的内存位置,就可以进行这些更改。
堆栈在大多数情况下用于将参数传递给函数。使用它的原因是你没有被绑定到固定的存储空间(用于参数)来让你的函数起作用。如果你有可以从固定内存中获取参数的函数,那么如果内存是空闲的,你可能只能运行它,你只能运行它的一个实例。 Stack可以随时将您的参数存储到程序的当前上下文中。在x86处理器上,有一个寄存器指向堆栈的末尾,另一个寄存器指向开始。这些实际上只是您希望堆栈驻留的主要内存的地址。
有一个PUSH指令将堆栈结束寄存器移到下一个地方,并将指定的数据(可能是来自其他寄存器的值或某地址或直接值)存储到堆栈结束寄存器指向的地址。另一条指令是POP,它的工作方式与其他方式相同。这样,如果你坚持这个计划并跟踪你推动堆栈的内容,你可以从任何上下文中使用你的函数。
还有一些不太常用的选项可以像通过寄存器那样传递参数,例如bios中断。如果你想更多地了解这一点,我建议你阅读“调用约定”。
非常好的解释!!我现在明白了,但是我不明白你在做什么在这里nt:“这样,如果你坚持计划并跟踪你推入堆栈的内容,你可以从任何上下文中使用你的函数。 “ – Apeee
这个部分实际上是由编译器为你完成的,如果你用栈传递参数,你的编译器将它们压入堆栈,之后它将它们称为堆栈结束寄存器+4 +8 +12等等..可能发生的是,你传递了一些像(int,int,char,short int,int)这样的地址有点麻烦的东西,因为char只是1个字节而short int是2个字节。所以它会被解决像+8 +12 +13 +15 +19 ..这就是我的意思是跟踪你推动堆栈。 (参数在+8开始,因为通用编译器在参数之前推入了另外两个int) – Pyjong
我不会通过寄存器传递参数“less used option”,因为它通常用在x86-64上。 –
让我们开始这个假设你有一个函数
int foo(int value) {
int a = 10;
return a;
}
所以每当一个函数调用由操作系统需要一定的存储空间,在这种情况下和参数传递的功能分配功能int a
的局部变量在这种情况下为int value
。该内存需求通过在堆栈上分配内存来实现。堆栈不过是分配给每个进程的内存区域,它实际上表现为堆栈数据结构(LIFO)。
现在问题出现了,当进行函数调用时,所有东西都存储在堆栈中。推入堆栈的第一件事是以相反顺序传递给函数的参数(如果多于一个)。 2.然后调用该函数的函数的返回地址(因为一旦这个函数foo
完成执行,它应该返回到调用该函数的代码中的位置) 3.最后,调用的函数的局部变量被推送在堆栈上。
一旦被调用的函数完成执行代码,它将返回到先前存储在堆栈上的返回地址,因此我们说函数调用完成或返回。 在这种情况下,函数有一个返回值,它返回到被调用函数。 该空间随后可以自由使用,并可在随后的函数调用中被覆盖。(现在如果连接了dotes,你可以意识到为什么函数中的局部变量(自动变量)的范围局限于函数调用的生命期(你问了一个与被关闭的范围有关的SO问题),因为一旦调用返回分配给这些语言环境变量的内存空间消失(这是仍然存在,但你不能一次访问它们的函数返回),所以在这种情况下,限制直至foo()
返回到调用函数,这些自动变量int a
的生活。
注意:我已经阅读了许多你在SO中发布过的问题,我想你一般都是在学习C和底层硬件和操作系统的基本工作,并且他们之间的混淆正在消灭你。我会建议你除了回答这个问题外,还要阅读和理解哪些内容,这些内容可以让你深入了解你所面临的问题。
- 对于C参考K & R它是最好的书。
- 在开始阅读有关操作系统概念(内存处理,特别是虚拟内存)的一点点读取
- 尝试想象广义上的系统工作,就像不同组件之间的交互方式一样。
- 理解记忆相关的东西和系统内部http://duartes.org/gustavo/blog/best-of
,如果你想潜入函数调用堆栈空间尝试此链接http://www.binarypirates.in/2011/02/17/understanding-function-stack-in-c/
希望这有助于
- 1. DebugDiag调用堆栈不显示调用堆栈中函数的行数
- 2. OpenCL函数调用堆栈大小
- 3. 调用堆栈显示匿名函数
- 4. 调用堆栈
- 5. 堆栈溢出调用堆栈#timememoryfunctionlocation 10.0000143728
- 6. 调用已经在调用堆栈中的函数
- 7. JavaScript调用堆栈
- 8. erlang调用堆栈
- 9. jQuery调用堆栈?
- 10. MEAN堆栈更新函数
- 11. 汇编堆栈3函数
- 12. jQuery bug,slidetoggle()函数堆栈
- 13. 调用堆栈 - 函数返回调用函数的局部变量引用,然后调用另一个函数
- 14. D3堆叠面积图堆栈函数
- 15. 在递归函数中调用堆栈大小:最大调用堆栈大小低于预期
- 16. 字符堆栈,字符串堆栈,整数堆栈,整数数组堆栈等
- 17. 在javascript中使用函数堆栈调用非递归方法
- 18. 如何在GCC中不使用堆栈和函数调用?
- 19. GNU汇编程序,函数调用使用堆栈,seg错误
- 20. 使用函数,类和堆栈指针
- 21. 在Haskell函数中使用堆栈
- 22. 使用堆栈跟踪检测函数
- 23. C sprintf函数,使用malloc或堆栈
- 24. 函数修改堆栈时如何将堆栈传递给函数?
- 25. 非托管调用堆栈
- 26. 调用堆栈问题
- 27. 清除JavaScript调用堆栈
- 28. 调用堆栈大小?
- 29. 协程调用堆栈
- 30. PHP调用堆栈问题
是感谢一些好的链接您!现在我发现它被称为传递价值,并通过引用。所以它说,当你按值传递时,函数在一个已经被复制到堆栈的值上运行。那么为什么你需要通过价值传递? – Apeee
按价值传递更安全。当您正在调用的函数不需要修改该值时,如果您通过引用传递,则调用者必须非常小心或有风险破坏被调用者不希望更改的数据。这是正常情况,对通过引用的真正需求不太常见。 – mah
取决于你想要做什么。如果你希望你的变量值在功能调用后不应该改变......你可以通过值发送它。如果你希望他们改变......你可以通过引用或指针发送它。例如,数组总是通过指针传递。 – rahul