Bitte um Erläuterung für diese Disassemblierung



  • Hallo allerseits 😉
    Ich habe ein kleines C-Programm geschrieben und es mit dem gdb disassembliert. Im Grunde kann ich das meiste von diesem Code nachvollziehen aber manches ist mir noch unklar. Hier erstmal die Disassemblierung:

    Dump of assembler code for function main:
       0x08048424 <+0>:     push   ebp
       0x08048425 <+1>:     mov    ebp,esp
       0x08048427 <+3>:     and    esp,0xfffffff0
       0x0804842a <+6>:     sub    esp,0x20
       0x0804842d <+9>:     mov    DWORD PTR [esp+0x1c],0x0
       0x08048435 <+17>:    mov    DWORD PTR [esp+0x18],0x5
       0x0804843d <+25>:    mov    DWORD PTR [esp+0x1c],0x6
       0x08048445 <+33>:    mov    eax,0x8048540
       0x0804844a <+38>:    mov    edx,DWORD PTR [esp+0x1c]
       0x0804844e <+42>:    mov    DWORD PTR [esp+0x8],edx
       0x08048452 <+46>:    mov    edx,DWORD PTR [esp+0x18]
       0x08048456 <+50>:    mov    DWORD PTR [esp+0x4],edx
       0x0804845a <+54>:    mov    DWORD PTR [esp],eax
       0x0804845d <+57>:    call   0x8048354 <printf@plt>
       0x08048462 <+62>:    leave  
       0x08048463 <+63>:    ret
    

    So wass machenv die Zeilen 1-4. Ich weiß nur das es etwas mit dem Stack und dem Basepointer zu tun hat. Hoffe mir kann das einer in 2-3 Sätzer erklären 😕



  • ASSA schrieb:

    So wass machenv die Zeilen 1-4. Ich weiß nur das es etwas mit dem Stack und dem Basepointer zu tun hat. Hoffe mir kann das einer in 2-3 Sätzer erklären 😕

    Zuerst wird der frame pointer (EBP) eingerichtet und anschließend 32 Byte mit einem alignment von 16 (and esp,-16) auf dem stack reserviert (sub esp,0x20).



  • Dump of assembler code for function main:
       0x08048424 <+0>:     push   ebp                      //alten Basepointer sichern
       0x08048425 <+1>:     mov    ebp,esp                  //meinen Basepointer auf den Stackpointer setzen
    //Ab jetzt könnte ich alle meine lokalen Variablen anhand relativ zum ebp angeben. 
    //Aber ich benutze hier keine lokalen Variablen...
       0x08048427 <+3>:     and    esp,0xfffffff0           //auf 16 alignen durch bis zu 15 Bytes Verschwendung
       0x0804842a <+6>:     sub    esp,0x20                 //32 Bytes Platz machen für Funktionsargumente
       0x0804842d <+9>:     mov    DWORD PTR [esp+0x1c],0x0 //Diese Argumente auf den Stack schreiben
       0x08048435 <+17>:    mov    DWORD PTR [esp+0x18],0x5 //Statt einzeln zu pushen
       0x0804843d <+25>:    mov    DWORD PTR [esp+0x1c],0x6 
       0x08048445 <+33>:    mov    eax,0x8048540
       0x0804844a <+38>:    mov    edx,DWORD PTR [esp+0x1c]
       0x0804844e <+42>:    mov    DWORD PTR [esp+0x8],edx
       0x08048452 <+46>:    mov    edx,DWORD PTR [esp+0x18]
       0x08048456 <+50>:    mov    DWORD PTR [esp+0x4],edx
       0x0804845a <+54>:    mov    DWORD PTR [esp],eax
       0x0804845d <+57>:    call   0x8048354 <printf@plt>   //printf aufrufen
       0x08048462 <+62>:    leave                           //macht mov esp,ebp; pop ebp
    //Also alle loaklen Variablen wegschmeißen und den esp und den ebp dahinstellen, wo er bei Funktionseintritt war. 
       0x08048463 <+63>:    ret
    


  • Das ist die übliche Parameterübergabeprozedur an Unterprogramme über den Stack bei Hochsprachen.
    Schön erklärt 👍

    Allerdings kommt mir das ganze Prozedere immer irgendwie ein wenig redundant vor, das hin und herkopiere im Speicher - müsste vielleicht gar nicht immer sein, und das ein oder andere proggi wäre eventuell leichter lesbar (wo bin ich denn nun gerade genau im Stack???) und so mancher Stackoverflow eingespart...



  • nachtfeuer schrieb:

    Allerdings kommt mir das ganze Prozedere immer irgendwie ein wenig redundant vor, das hin und herkopiere im Speicher - müsste vielleicht gar nicht immer sein, und das ein oder andere proggi wäre eventuell leichter lesbar (wo bin ich denn nun gerade genau im Stack???) und so mancher Stackoverflow eingespart...

    Genau dafür gibt es doch die Compiler-Optimierungen, als einfachstes Beispiel sei hier Inlining genannt. Ebenso könen durch Optimierungen bspw. Caller-/Callee-Safe Register gespart werden.

    Ansonsten ist das ganze nicht so einfach, wenn man sich mal mit der Mikroarchitektur beschäftigt und sieht, wie das in der digitalen Logik dann hinterher auf dem Chip aussieht.


Anmelden zum Antworten