Asm-Typ von Compiler-Tutorial



  • Hallo,

    ich bin gerade dabei das Compiler-Tutorial von Ben04 durchzuarbeiten. Bin gerade bei den Variablen angekommen und ab da verstehe ich die Asm-Codes nicht mehr.

    Könnte mir jemand sagen, welcher Asm-Typ in dem Tutorial verwendet wird, damit ich das nachschlagen kann?



  • gas assembler, AT&T-Syntax
    :schland: :schland: :schland: :schland:



  • Antoras schrieb:

    Hallo,

    ich bin gerade dabei das Compiler-Tutorial von Ben04 durchzuarbeiten. Bin gerade bei den Variablen angekommen und ab da verstehe ich die Asm-Codes nicht mehr.

    Könnte mir jemand sagen, welcher Asm-Typ in dem Tutorial verwendet wird, damit ich das nachschlagen kann?

    Du kannst zur Übung vielleicht noch aus deinen C/C++-Dateien mit gcc Assembler-Dateien generieren und schauen, was macht und wie der "echte" Compiler:

    gcc -S main.c
    

    Ergebnis ist eine main.s Assembler-Datei (mit GNU Assembler Syntax)...



  • Das Assemblieren von C-Quelltext hab ich schon mal vorgenommen, aber mangels Kenntnisse des Assemblers hab ich nichts mit dem Code anfangen können.
    Aber jetzt, wo ich weiß wie der Assembler heißt, kann ich unbekannte Befehle ja nachgucken.

    Nur noch ein Problem:
    Ich hab das Programm unter WindowsXP mit MinGW immer erfolgreich ausgeführt bekommen. Unter meinem 64Bit-Linux bekommen ich aber immer bei den pop- und push-Befehlen eine Fehlermeldung:

    out.s:15: Error: suffix or operands invalid for `push'
    out.s:18: Error: suffix or operands invalid for `pop'
    

    Hab schon nachgeguckt und es hängt scheinbar damit zusammen, dass mein Linux 64Bit ist. In den Betroffenen Zeilen steht das:

    push %eax
    pop %eax
    

    Gibt es beim GAS-Asm auch Befehle für eine 64-Bit Architektur oder muss ich da einen anderen Asm nehmen?



  • Antoras schrieb:

    Hab schon nachgeguckt und es hängt scheinbar damit zusammen, dass mein Linux 64Bit ist. In den Betroffenen Zeilen steht das:

    push %eax
    pop %eax
    

    Gibt es beim GAS-Asm auch Befehle für eine 64-Bit Architektur oder muss ich da einen anderen Asm nehmen?

    Ach du Glücklicher, hast eine 64-Bit CPU... 😞 Ich nicht...
    In der Instruction Set Reference von Intel gibt es zu PUSH einen Eintrag, dass dieser Befehl mit einem 32-Bit Register im 64-Bit Modus N.E. ist. Das steht wahrscheinlich für "not executable" 😕



  • Antoras schrieb:

    Gibt es beim GAS-Asm auch Befehle für eine 64-Bit Architektur oder muss ich da einen anderen Asm nehmen?

    GAS unterstützt jede (na, vielleicht nicht jede, aber viele) CPU und das kostenlos 😉



  • In dem Fall werd ich mal schauen ob ich eine Alternative zu den Befehlen finde. Falls es da einen direkten Alternativbefehl gibt, kann den hier ja noch jemand posten. Ansonsten muss ich den Asm-Code halt ein wenig umbauen.



  • Antoras schrieb:

    In dem Fall werd ich mal schauen ob ich eine Alternative zu den Befehlen finde. Falls es da einen direkten Alternativbefehl gibt, kann den hier ja noch jemand posten. Ansonsten muss ich den Asm-Code halt ein wenig umbauen.

    Der Befehl ist schon richtig, aber wie abc.w geschrieben hat, läuft dieser im 64 Bit Modus nicht mit den 32 Bit Registern. Die Register mit r am Anfang (z.B. rax statt eax) sind die 64 Bit Register.

    Alternativ könntest du einfach eine 32 Bit Binary erstellen, da diese meistens auch auf einem 64 Bit System lauffähig ist. Ich weiß nicht wie sich das mit dem Assembler Teil verhält, aber normalerweise sollte -m32 als zusätzlicher gcc Parameter reichen.



  • Wenn ich die Anfangsbuchstaben der Register von e auf r ändere und z.B. statt einem movl ein movq benutze, dann kann ich das Programm erfolgreich kompilieren.

    Bei meiner Linux-Distri ist es leider nicht möglich eine 32Bit-Binary zu erstellen, aus welchem Grund auch immer.

    Bekomme bei der Ausführung jetzt nur noch einen Segmentation Fault. Da scheinen die ausgegebenen Asm-Befehle noch nicht zu stimmen. Das muss ich mir nochmal angucken.

    Danke für eure Hilfe.



  • der Wechsel von 32bit nach 64bit (Windows) ist nicht einfach mit Umbenennung der Register getan. z.B. kann man lokale Variablen nicht mehr nach Lust und Laune allozieren (ohne Probleme maximal 4096 Byte). Wenn API Funktionen aufgerufen werden sollen, muss man auch auf das Stack aligment achten. (mal davon abgesehen, das nur noch eine calling convention gibt: fastcall)



  • Hm, das ist aber nicht gut. Ich verwende zwar fast ausschließlich Linux, aber ich denke, dass es dort wohl genug Unterschiede bei der Asm-Programmierung geben dürfe? Aber gut, dann werde ich mir die Unterschiede bei der Asm-Programmierung halt anlesen müssen. Bringt sowieso mehr als den Asm-Code stur abzutippen. In dem Tut wird sowieso kein Syntaxbaum behandelt. Dann hab ich schon einen Grund den gleich einzubauen, damit ich sowohl für 32- und 64-Bit kompilieren kann...

    Ich hab mir den SegFault mal genauer angeguckt. Er tritt auf, da das hinzu linken der Asm-Datei zur C-Datei wohl nicht korrekt funktioniert. Laut GDB wird die Funktion _prog() nicht gefunden.

    Die C-Datei:

    #include <stdio.h>
    
    void _prog();
    
    void _print_int(int n){
        printf("%d", n);
    }
    
    int main(){
        _prog();
    }
    

    Ohne die führenden Unterstriche bringt mir GCC immer einen Linkerfehler.

    Die Asm-Datei:

    .text
    .globl _prog
    _prog:
      movq $5, %rax
      pushq %rax
      call _print_int
      addq $4, %rsp
      ret
    

    Das auszuführende Kommando:

    gcc <asm_datei>.s <c_datei>.c -o <programm_name>
    

    Unter Windows (32Bit) hat das immer funktioniert. Kann mir jemand sagen ob das an den 64Bit liegt oder hat das andere Gründe.

    EDIT:
    Das korrekte Programm, falls es mal jemand braucht:

    .text
    .globl _prog
    _prog:
    movq $5, %rax
    movq %rax, %rdi
    call _print_int
    ret
    

Anmelden zum Antworten