繁体   English   中英

如何通过调用和ret在程序中更改堆栈指针

[英]How is the stack pointer changed in this program with call and ret

我的问题与上下文更改时似乎发生在线路之间的动作有关,尤其是与RSPRBP有关。

鉴于这个非常简单的程序:

Reading symbols from ./function_call...done.
(gdb) disass main
Dump of assembler code for function main:
   0x00000000004004d6 <+0>: push   rbp
   0x00000000004004d7 <+1>: mov    rbp,rsp
   0x00000000004004da <+4>: mov    esi,0x2
   0x00000000004004df <+9>: mov    edi,0x1
   0x00000000004004e4 <+14>:    call   0x4004b6 <add_and_7>
   0x00000000004004e9 <+19>:    mov    eax,0x0
   0x00000000004004ee <+24>:    pop    rbp
   0x00000000004004ef <+25>:    ret    
End of assembler dump.
(gdb) disass add_and_7
Dump of assembler code for function add_and_7:
   0x00000000004004b6 <+0>: push   rbp
   0x00000000004004b7 <+1>: mov    rbp,rsp
   0x00000000004004ba <+4>: mov    DWORD PTR [rbp-0x14],edi
   0x00000000004004bd <+7>: mov    DWORD PTR [rbp-0x18],esi
   0x00000000004004c0 <+10>:    mov    DWORD PTR [rbp-0x4],0x7
   0x00000000004004c7 <+17>:    mov    edx,DWORD PTR [rbp-0x14]
   0x00000000004004ca <+20>:    mov    eax,DWORD PTR [rbp-0x18]
   0x00000000004004cd <+23>:    add    edx,eax
   0x00000000004004cf <+25>:    mov    eax,DWORD PTR [rbp-0x4]
   0x00000000004004d2 <+28>:    add    eax,edx
   0x00000000004004d4 <+30>:    pop    rbp
   0x00000000004004d5 <+31>:    ret    
End of assembler dump.
(gdb) list
1   int add_and_7( int num1, int num2 ) {
2       int seven = 7;
3       return num1 + num2 + seven;
4   }
5   
6   int main() {
7       add_and_7( 1, 2 );
8       return 0;
9   }

所有功能都以push rbp开始,据我所知,push rbp是将父上下文保存到堆栈中。 父函数如何知道如何重建自身? callret是否已内置必要的步骤?

然后, rsp始终移至rbp 如我所读,这会将新的堆栈基设置为当前函数的上下文。 我似乎无法弄清楚是什么时候或如何将堆栈指针设置到该位置。 我最好的猜测是汇编函数调用会执行此操作,这是怎么回事?

最后,当方法返回时,似乎eax是用于父函数以利用其子函数的返回的寄存器。 eax明确用于此目的还是仅仅是我的编译器和体系结构的约定?

父函数如何知道如何重建自身? 呼叫和退回中是否已内置必要的步骤?

在调用函数之前,将保存寄存器的当前状态以及返回地址。 call指令跳转到被调用函数开始的特定地址。 返回地址被压入堆栈。 当被调用的函数返回时, ret指令会弹出先前推送的返回地址,然后转到该位置。

然后将rsp始终移至rbp

先前将rbp推入堆栈,以便能够从调用者的函数中恢复rbp的值。 然后,将rsp移至rbp,以为被调用者函数创建一个新的堆栈框架。 新的基本指针已设置。 因此,当前,rbp和rsp指向相同的地址。 如果还有其他push指令,则会自动调整esp。 功能完成后, pop ebp指令将恢复先前压入的堆栈基指针地址。

Push和Pop修改堆栈指针SP

呼叫推送FLAGS-状态寄存器以及RA-返回地址。 Ret弹出FLAGS弹出并跳转到返回地址。

正如rkhb所说,保持某些寄存器原样的需要来自调用约定。

暂无
暂无

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

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