Beispiel Assembler - Frage



  • Hallo Assemblerprofis,

    ich hätte mal eine Frage zu einem Codebeispiel. Bin noch blutiger Anfänger und verstehe das Beispiel nicht ganz. Undzwar habe ich das klassische "Hello World"-Programm gegeben, kompiliert und mir die kompilierte Binärdatei angesehen. Jetzt steht dort folgendes:

    8048374:    55          push %ebp
    8048375:    89  e5      mov  %esp,%ebp
    8048377:    83  ec  08  sub  $0x8,%esp
    804837a:    ......
    

    Hier verwirrt mich vor allem die Schreibweise. Die erste Zahl gibt die Adresse an und jede Adresse zeigt auf genau ein Bytes (das ist alles klar), aber eig. müsste doch die nächste Adresse 8048376 heißen, da push als Instruktion ein Byte und dann der Source Parameter das zweite Byte benötigt? Irgendwie muss der push Befehl ja wissen, was das Ziel oder die Quelle ist. Genauso in der nächsten Zeile. 2 Bytes werden angezeigt für mov; %esp; %ebp, aber in der dritten Zeile werden 3 Bytes für sub; $0x8; %esp angezeigt (aber die gleiche Anzahl an Parametern liegt vor). Ist das irgendeine besondere Schreibweise oder verstehe ich da was ganz falsch?

    Würde mich sehr über Antworten freuen,
    sunjojo



  • Das ist etwas kompliziert, die x86 Befehle sind sehr schwer zu kodieren/dekodieren. Für mache Befehle gibt es auch viele verschiedene Opcodes, dann gibt es Opcodes die verschiedene Befehle darstellen können, usw.
    Wenn du dich wirklich dafür interessierst schau dir mal eine x86 Opcode Reference an.

    Bei diesen Befehl gibt es für jeden Operanten eine extra Instruction:

    55 push ebx
    50 push %eax
    53 push %ebx
    

    Für "push Register" ist der Opcode "50 + register.

    89  e5 mov %esp,%ebp
    

    Hier werden (zumindest für "mov Register, Register") die Register über das zweite Byte festgelegt. Stichwort "MOD R/M byte".

    83  ec  08  sub $0x8,%esp
    

    Läuft ähnlich. Die Instruktion wird durch den Opcode festgelegt. Das Register durch das 2. Byte (mod r/m), und das Dritte gibt an wieviel subtrahiert wird (0x08)



  • Die Kodierung vom Postbyte bzw. Mod R/M-Byte:

    Instruction Prefix                0 oder 1 Byte
       Address-Size Prefix               0 oder 1 Byte
       Operand-Size Prefix               0 oder 1 Byte
       Segment Prefix                    0 oder 1 Byte
       Opcode                            1 oder 2 Byte
    -> Mod R/M                           0 oder 1 Byte
       SIB, Scale Index Base (386+)      0 oder 1 Byte
       Displacement                      0, 1, 2 oder 4 Byte (4 nur 386+)
       Immediate                         0, 1, 2 oder 4 Byte (4 nur 386+)
    
    Format of Postbyte(Mod R/M aus Intel-Doku)
    ------------------------------------------
    MM RRR MMM
    
    MM  - Memeory addressing mode
    RRR - Register operand address
    MMM - Memoy operand address
    
    RRR Register Names
    Filds  8bit  16bit  32bit
    000    AL     AX     EAX
    001    CL     CX     ECX
    010    DL     DX     EDX
    011    Bl     BX     EBX
    100    AH     SP     ESP
    101    CH     BP     EBP
    110    DH     SI     ESI
    111    BH     DI     EDI
    
    ---
    
    16bit memory (No 32 bit memory address prefix)
    MMM   Default MM Field
    Field Sreg     00        01          10             11=MMM is reg
    000   DS       [BX+SI]   [BX+SI+o8]  [BX+SI+o16]
    001   DS       [BX+DI]   [BX+DI+o8]  [BX+DI+o16]
    010   SS       [BP+SI]   [BP+SI+o8]  [BP+SI+o16]
    011   SS       [BP+DI]   [BP+DI+o8]  [BP+DI+o16]
    100   DS       [SI]      [SI+o8]     [SI+o16]
    101   DS       [DI]      [DI+o8]     [SI+o16]
    110   SS       [o16]     [BP+o8]     [BP+o16]
    111   DS       [BX]      [BX+o8]     [BX+o16]
    Note: MMM=110,MM=0 Default Sreg is DS !!!!
    
    32bit memory (Has 67h 32 bit memory address prefix)
    MMM   Default MM Field
    Field Sreg     00        01          10             11=MMM is reg
    000   DS       [EAX]     [EAX+o8]    [EAX+o32]
    001   DS       [ECX]     [ECX+o8]    [ECX+o32]
    010   DS       [EDX]     [EDX+o8]    [EDX+o32]
    011   DS       [EBX]     [EBX+o8]    [EBX+o32]
    100   SIB      [SIB]     [SIB+o8]    [SIB+o32]
    101   SS       [o32]     [EBP+o8]    [EBP+o32]
    110   DS       [ESI]     [ESI+o8]    [ESI+o32]
    111   DS       [EDI]     [EDI+o8]    [EDI+o32]
    Note: MMM=110,MM=0 Default Sreg is DS !!!!
    
    ---
    
    SIB is (Scale/Base/Index)
    SS BBB III
    Note: SIB address calculated as:
    <sib address>=<Base>+<Index>*(2^(Scale))
    
    Fild   Default Base
    BBB    Sreg    Register   Note
    000    DS      EAX
    001    DS      ECX
    010    DS      EDX
    011    DS      EBX
    100    SS      ESP
    101    DS      o32        if MM=00 (Postbyte)
    SS      EBP        if MM<>00 (Postbyte)
    110    SS      ESI
    111    DS      EDI
    
    Fild  Index
    III   register   Note
    000   EAX
    001   ECX
    010   EDX
    011   EBX
    100              never Index SS can be 00
    101   EBP
    110   ESI
    111   EDI
    
    Fild Scale coefficient
    SS   =2^(SS)
    00   1
    01   2
    10   4
    11   8
    

    Dirk



  • Danke DarkShadow44 und freecrac! 🙂

    Ich werde mir eure Antworten nochmal genau Anschauen und wenn ich noch Fragen habe, werdet ihr das dann merken :D.

    Einen schönen Start in die Woche,
    sunjojo


Log in to reply