简体   繁体   English

当函数调用返回时,压入堆栈的参数会发生什么变化?

[英]What happens to arguments pushed on the stack when a function call returns?

Assume this C code:假设这个 C 代码:

int add(int a, int b){
 int c = a+b;
 return c;
}

int main(){
  int c = add(3,4);
  printf("%d", c);
  return 0;
}

When calling add the following happens:调用add时会发生以下情况:

Push 4 on the stack
Push 3 on the stack
Push the address of `printf` on the stack (return address)
call `add`
// do stuff under add
pop the stack and and goto `printf`

But values 4 and 3 under add are still on the stack -0x18(%rbp) .但是add下的值 4 和 3 仍在堆栈中-0x18(%rbp) Are they not supposed to be cleared?他们不应该被清除吗?

00000000000005fa <add>:
 5fa:   55                      push   %rbp
 5fb:   48 89 e5                mov    %rsp,%rbp
 5fe:   89 7d ec                mov    %edi,-0x14(%rbp)
 601:   89 75 e8                mov    %esi,-0x18(%rbp)
 604:   8b 55 ec                mov    -0x14(%rbp),%edx
 607:   8b 45 e8                mov    -0x18(%rbp),%eax
 60a:   01 d0                   add    %edx,%eax
 60c:   89 45 fc                mov    %eax,-0x4(%rbp)
 60f:   8b 45 fc                mov    -0x4(%rbp),%eax
 612:   5d                      pop    %rbp
 613:   c3                      retq   

0000000000000614 <main>:
 614:   55                      push   %rbp
 615:   48 89 e5                mov    %rsp,%rbp
 618:   be 04 00 00 00          mov    $0x4,%esi
 61d:   bf 03 00 00 00          mov    $0x3,%edi
 622:   e8 d3 ff ff ff          callq  5fa <add>
 627:   5d                      pop    %rbp
 628:   c3                      retq  

But values 4 and 3 under add are still on the stack但是 add 下的值 4 和 3 仍在堆栈中

Not really, because stack no longer covers the memory where 4 and 3 are stored.不是真的,因为堆栈不再覆盖存储43的内存。 They are in the memory beyond the stack pointer.它们位于堆栈指针之外的内存中。 Although the values are still in the place in memory that used to be part of stack, they are now part of uninitialized garbage.尽管这些值仍然在内存中曾经是堆栈一部分的位置,但它们现在是未初始化垃圾的一部分。 Accessing them after the stack has moved on, eg by storing their addresses, would be undefined behavior.在堆栈移动后访问它们,例如通过存储它们的地址,将是未定义的行为。

Are they not supposed to be cleared?他们不应该被清除吗?

No, clearing these values is unnecessary, and could impact run-time efficiency of the program.不,清除这些值是不必要的,并且可能会影响程序的运行时效率。

When you call the pop instruction, the value at the top of the stack is stored in the specified register and the SP (stack pointer) register is incremented (on x86 the stack grows down).当您调用pop指令时,堆栈顶部的值存储在指定的寄存器中,并且 SP(堆栈指针)寄存器递增(在 x86 上堆栈向下增长)。 It does NOT modify the memory location that was previously the top of the stack as there's no need to do so.它不会修改以前位于堆栈顶部的内存位置,因为没有必要这样做。

Whatever value was at the top of the stack will remain there until a new value is pushed on top of it.堆栈顶部的任何值都将保留在那里,直到将新值压入堆栈顶部。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM