Wie kompiliere ich den von GCC generierten ASM?


74

Ich spiele mit 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.Sdieser erzeugt ein schönes 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?

Antworten:


90

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 gibt eine Objektcodedatei mit dem Namen file.o. Führen Sie die folgenden Schritte aus, um den Linker aufzurufen:

gcc file.o -o file

30
Sie können auch nur verwendengcc file.S -o file
— Breno Leitão

was ist mit "> als -o hallo.o hallo.s"? wie unter www3.ntu.edu.sg/home/ehchua/programming/cpp/gcc_make.html angegeben . Die Reihenfolge des Prozesses scheint Vorverarbeitung ( .i-Datei), Kompilieren ( .s-Datei), Zusammenstellen ( .o-Datei) und Verknüpfen ( .exe-Datei) zu sein.
— user1677716

@ user1677716: Ja, das gcc -cläuft, wenn Sie ihm eine .sDatei geben. Sie können verwenden gcc -v, um die ausgeführten Befehle anzuzeigen, z. B. gcc -v -c foo.soder gcc -v foo.sum sie zusammenzusetzen und zu verknüpfen . Der Verknüpfungsteil ist komplexer als nur ld foo.o; Es muss mit CRT-Startcode und Bibliotheken einschließlich libc ( -lc) verknüpft sein .
— Peter Cordes

51

gccSie können eine Assembly-Datei als Eingabe verwenden und den Assembler nach Bedarf aufrufen. Es gibt jedoch eine Subtilität:

  • Wenn der Dateiname mit " .s" (Kleinbuchstaben) endet , wird gccder Assembler aufgerufen.
  • Wenn der Dateiname mit " .S" endet (Großbuchstaben 'S'), wird gccder C-Präprozessor auf die Quelldatei angewendet (dh er erkennt Anweisungen wie #ifund ersetzt Makros) und ruft dann 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 würde es funktionieren, aber ich erhalte eine Fehlermeldung: 'Malformed Mach-o file'
— Martin Kristiansen

Ich denke, Sie müssen das .SPräfix (Großbuchstaben) verwenden, sonst erkennt gcc einen anderen Dateityp ( .asmzum Beispiel fehlgeschlagen )
— Jean-François Fabre

11

Sie können den Assemblycode in ein normales C-Programm einbetten. Hier ist eine gute Einführung . 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 wird nach Ausführung des Assembler-Codes in foo gespeichert

\ 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;
}

4

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


1
Wie finde ich heraus, wie gcc verwendet hätte?
— Martin Kristiansen

Außerdem habe ich Intel ICC herumliegen, welchen Assembler verwenden sie?
— Martin Kristiansen

4
@ Martin, bitte darum gcc -v, seine Handlungen zu erzählen.
— SK-Logik


2

Wenn Sie die Datei main.s haben. Sie können Objektdateien von GCCund auch generierenas

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

Wenn Sie diesen Link überprüfen, können Sie einige Binutils von GCC kennenlernen. http://www.thegeekstuff.com/2017/01/gnu-binutils-commands/


Beachten Sie, dass Sie keine Verknüpfung zu einer ausführbaren Datei herstellen können ld(ohne eine Reihe von Optionen hinzuzufügen): Sie möchten weiterhin gcc main.o -o maineine Verknüpfung mit dem CRT-Startcode und-lc
— Peter Cordes

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

2
Dies ist eine ziemlich kurze Antwort. Könnten Sie bitte eine Erklärung hinzufügen? Vielleicht können Sie uns sagen, was die Parameter tun und was Sie anders machen als die anderen Antworten.
— GameDroids

GCC generiert keine NASM-Syntax, sondern GAS mit AT & T oder .intel_syntax noprefix. Es gibt keine Kombination von GCC- und NASM-Optionen, mit denen Sie C zu asm mit GCC kompilieren und dann mit NASM zusammenstellen können.
— Peter Cordes
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.