Wie wird der Stapelzeiger in diesem Programm mit call and ret geändert?

Meine Fragen beziehen sich auf die Aktionen, die scheinbar zwischen den Zeilen stattfinden, wenn sich der Kontext ändert, insbesondere in Bezug aufRSP undRBP.

Angesichts dieses sehr einfachen Programms:

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   }

Alle Funktionen beginnen mit Pushrbp was ich verstehe, ist es, den übergeordneten Kontext auf dem Stapel zu erhalten. Woher weiß die übergeordnete Funktion, wie sie sich selbst neu aufbaut? Sind die notwendigen Schritte eingebautcall undret?

Dann ist diersp wird immer verschoben nachrbp. Wie ich gelesen habe, setzt dies die neue Stapelbasis in den Kontext der aktuellen Funktion. Was ich anscheinend nicht herausfinden kann, ist, wann oder wie der Stapelzeiger an erster Stelle auf diesen Punkt gesetzt wurde. Ich vermute, dass der Aufruf der Assembly-Funktion dies tut, ist das, was passiert?

Wenn eine Methode zurückgegeben wird, sieht es schließlich so auseax ist das Register, das für die übergeordnete Funktion verwendet wird, um die Rückgabe ihrer untergeordneten Funktion zu verwenden. Isteax Wird dies explizit verwendet oder handelt es sich nur um eine Konvention mit meinem Compiler und meiner Architektur?

Antworten auf die Frage(2)

Ihre Antwort auf die Frage