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.S
dieser 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?
c
gcc
compiler-construction
assembly
Martin Kristiansen
quelle
quelle
gcc file.S -o file
gcc -c
läuft, wenn Sie ihm eine.s
Datei geben. Sie können verwendengcc -v
, um die ausgeführten Befehle anzuzeigen, z. B.gcc -v -c foo.s
odergcc -v foo.s
um sie zusammenzusetzen und zu verknüpfen . Der Verknüpfungsteil ist komplexer als nurld foo.o
; Es muss mit CRT-Startcode und Bibliotheken einschließlich libc (-lc
) verknüpft sein .gcc
Sie können eine Assembly-Datei als Eingabe verwenden und den Assembler nach Bedarf aufrufen. Es gibt jedoch eine Subtilität:.s
" (Kleinbuchstaben) endet , wirdgcc
der Assembler aufgerufen..S
" endet (Großbuchstaben 'S'), wirdgcc
der C-Präprozessor auf die Quelldatei angewendet (dh er erkennt Anweisungen wie#if
und ersetzt Makros) und ruft dann den Assembler für das Ergebnis auf.Im Allgemeinen möchten Sie also Folgendes tun:
quelle
.S
Präfix (Großbuchstaben) verwenden, sonst erkennt gcc einen anderen Dateityp (.asm
zum Beispiel fehlgeschlagen )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:
\ 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; }
quelle
Ja, gcc kann auch Assembly-Quellcode kompilieren. Alternativ können Sie
as
den Assembler aufrufen . (gcc ist nur ein "Treiber" -Programm, das Heuristiken verwendet, um C-Compiler, C ++ - Compiler, Assembler, Linker usw. aufzurufen.)quelle
gcc -v
, seine Handlungen zu erzählen.Sie können GAS verwenden, den Backend-Assembler von gcc:
http://linux.die.net/man/1/as
quelle
Wenn Sie die Datei main.s haben. Sie können Objektdateien von
GCC
und 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/
quelle
ld
(ohne eine Reihe von Optionen hinzuzufügen): Sie möchten weiterhingcc main.o -o main
eine Verknüpfung mit dem CRT-Startcode und-lc
nasm -f bin -o 2_hello 2_hello.asm
quelle
.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.