Wie kompiliere ich das von GCC generierte asm?

Lesezeit: 4 Minuten

Benutzeravatar von Martin Kristiansen
Martin Kristiansen

Ich spiele mit etwas asm-Code herum, und etwas stört mich.

Ich kompiliere das:

#include <stdio.h>

int main(int argc, char** argv){
  printf("Hello World\n");
  return 0;
}

mit gcc file.c -S -o file.S dies erzeugt ein nettes kleines Stück asm-Code:

    .cstring
LC0:
    .ascii "Hello World\0"
    .text
.globl _main
_main:
LFB3:
    pushq   %rbp
LCFI0:
    movq    %rsp, %rbp
LCFI1:
    subq    $16, %rsp
LCFI2:
    movl    %edi, -4(%rbp)
    movq    %rsi, -16(%rbp)
    leaq    LC0(%rip), %rdi
    call    _puts
    movl    $0, %eax
    leave
    ret
LFE3:
    .section __TEXT,__eh_frame,coalesced,no_toc+strip_static_syms+live_support
EH_frame1:
    .set L$set$0,LECIE1-LSCIE1
    .long L$set$0
LSCIE1:
    .long   0x0
    .byte   0x1
    .ascii "zR\0"
    .byte   0x1
    .byte   0x78
    .byte   0x10
    .byte   0x1
    .byte   0x10
    .byte   0xc
    .byte   0x7
    .byte   0x8
    .byte   0x90
    .byte   0x1
    .align 3
LECIE1:
.globl _main.eh
_main.eh:
LSFDE1:
    .set L$set$1,LEFDE1-LASFDE1
    .long L$set$1
LASFDE1:
    .long   LASFDE1-EH_frame1
    .quad   LFB3-.
    .set L$set$2,LFE3-LFB3
    .quad L$set$2
    .byte   0x0
    .byte   0x4
    .set L$set$3,LCFI0-LFB3
    .long L$set$3
    .byte   0xe
    .byte   0x10
    .byte   0x86
    .byte   0x2
    .byte   0x4
    .set L$set$4,LCFI1-LCFI0
    .long L$set$4
    .byte   0xd
    .byte   0x6
    .align 3
LEFDE1:
    .subsections_via_symbols

Mein nächstes Problem ist wirklich, wie kompiliere ich diese Ausgabe und kann ich GCC dazu bringen, dies für mich zu tun?

Ja, Sie können gcc verwenden, um Ihren asm-Code zu kompilieren. Verwenden Sie -c für die Kompilierung wie folgt:

gcc -c file.S -o file.o

Dies ergibt eine Objektcodedatei mit dem Namen file.o. Um den Linker aufzurufen, führen Sie nach dem obigen Befehl Folgendes aus:

gcc file.o -o file

  • kannst du auch einfach verwenden gcc file.S -o file

    – Breno Leitão

    9. September 2015 um 15:46 Uhr


  • was ist mit “> as -o hello.o hello.s” ? Wie angegeben durch www3.ntu.edu.sg/home/ehchua/programming/cpp/gcc_make.html. Scheint so, als ob die Reihenfolge des Prozesses die Vorverarbeitung ist (.i-Datei), kompilieren (.s-Datei), Assemblieren (.o-Datei) und Verlinkung (.exe-Datei).

    – Benutzer1677716

    15. Juni 2016 um 13:50 Uhr

  • @ user1677716: Ja, das ist was gcc -c läuft, wenn du ihm a gibst .s Datei. Sie können verwenden gcc -v um die Befehle zu sehen, die es ausführt, z gcc -v -c foo.s oder gcc -v foo.s montieren und verlinken. Der Verknüpfungsteil ist komplexer als nur ld foo.o; es muss mit CRT-Startcode und Bibliotheken einschließlich libc (-lc).

    – Peter Cordes

    29. Juli 2020 um 22:21 Uhr

gcc kann eine Assemblydatei als Eingabe verwenden und den Assembler nach Bedarf aufrufen. Es gibt jedoch eine Feinheit:

  • Wenn der Dateiname mit „.s” (kleines ‘s’), dann gcc ruft den Assembler.
  • Wenn der Dateiname mit „.S” (großes ‘S’), dann gcc wendet den C-Präprozessor auf die Quelldatei an (d. h. er erkennt Direktiven wie z #if und ersetzt Makros) und dann ruft den Assembler für das Ergebnis auf.

Im Allgemeinen möchten Sie also Folgendes tun:

gcc -S file.c -o file.s
gcc -c file.s

  • Das sieht so aus, als ob es funktioniert, aber ich erhalte eine Fehlermeldung: ‘Malformed Mach-o file’

    – Martin Kristiansen

    25. August 2011 um 12:44 Uhr

  • Ich denke, Sie müssen die verwenden .S Präfix (Großbuchstaben), sonst erkennt gcc einen anderen Dateityp (fehlgeschlagen mit .asm zum Beispiel)

    – Jean-Francois Fabre

    6. März 2017 um 14:29 Uhr

Sie können den Assembler-Code in ein normales C-Programm einbetten. Hier ist eine gute Einleitung. Mit der entsprechenden Syntax können Sie GCC auch mitteilen, dass Sie mit in C deklarierten Variablen interagieren möchten. Das folgende Programm weist gcc an, dass:

  • eax soll foo sein
  • ebx soll bar sein
  • der Wert in eax soll in foo gespeichert werden, nachdem der Assembler-Code ausgeführt wurde

\n

int main(void)
{
        int foo = 10, bar = 15;
        __asm__ __volatile__("addl  %%ebx,%%eax"
                             :"=a"(foo)
                             :"a"(foo), "b"(bar)
                             );
        printf("foo+bar=%d\n", foo);
        return 0;
}

Ja, gcc kann auch Assembly-Quellcode kompilieren. Alternativ können Sie aufrufen as, das ist der Assembler. (gcc ist nur ein “Treiber”-Programm, das Heuristik verwendet, um C-Compiler, C++-Compiler, Assembler, Linker usw. aufzurufen.)

Sie können GAS verwenden, den Backend-Assembler von gcc:

http://linux.die.net/man/1/as

Benutzeravatar von McGrady
McGrady

Wenn Sie eine main.s-Datei haben. Sie können eine Objektdatei generieren, indem Sie GCC und auch as

# gcc -c main.s
# as main.s -o main.o

Überprüfen Sie diesen Link, er wird Ihnen helfen, einige Binutils von GCC zu lernen
http://www.thegeekstuff.com/2017/01/gnu-binutils-commands/

Benutzeravatar von Hassan Maher
Hassan Maher

nasm -f bin -o 2_hello 2_hello.asm

  • Dies ist eine ziemlich kurze Antwort. Könnten Sie bitte eine Erklärung hinzufügen? Vielleicht können Sie uns sagen, was die Parameter bewirken und was Sie im Vergleich zu den anderen Antworten anders machen.

    – GameDroids

    10. November 2014 um 13:42 Uhr

  • GCC generiert keine NASM-Syntax, es generiert GAS mit AT&T oder .intel_syntax noprefix. Es gibt keine Kombination aus GCC- und NASM-Optionen, mit der Sie C mit GCC zu asm kompilieren und es dann mit NASM assemblieren können.

    – Peter Cordes

    29. Juli 2020 um 22:18 Uhr

1418710cookie-checkWie kompiliere ich das von GCC generierte asm?

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy