2009-09-26 8 views
10

Ho insegnato a me stesso GNU Assembly per un po 'di tempo scrivendo delle istruzioni in C, compilandole con "gcc -S" e studiando l'output. Questo funziona bene su x86 (e la compilazione con -m32), ma sulla mia macchina AMD64, per questo codice (tanto per fare un esempio):Pulire l'output dell'assieme x86_64 con gcc?

int main() 
{ 
    return 0; 
} 

GCC mi dà:

 .file "test.c" 
.text 
.globl main 
.type main, @function 
main: 
.LFB2: 
pushq %rbp 
.LCFI0: 
movq %rsp, %rbp 
.LCFI1: 
movl $0, %eax 
leave 
ret 
.LFE2: 
.size main, .-main 
.section .eh_frame,"a",@progbits 
.Lframe1: 
.long .LECIE1-.LSCIE1 
.LSCIE1: 
.long 0x0 
.byte 0x1 
.string "zR" 
.uleb128 0x1 
.sleb128 -8 
.byte 0x10 
.uleb128 0x1 
.byte 0x3 
.byte 0xc 
.uleb128 0x7 
.uleb128 0x8 
.byte 0x90 
.uleb128 0x1 
.align 8 
.LECIE1: 
.LSFDE1: 
.long .LEFDE1-.LASFDE1 
.LASFDE1: 
.long .LASFDE1-.Lframe1 
.long .LFB2 
.long .LFE2-.LFB2 
.uleb128 0x0 
.byte 0x4 
.long .LCFI0-.LFB2 
.byte 0xe 
.uleb128 0x10 
.byte 0x86 
.uleb128 0x2 
.byte 0x4 
.long .LCFI1-.LCFI0 
.byte 0xd 
.uleb128 0x6 
.align 8 
.LEFDE1: 
.ident "GCC: (Ubuntu 4.3.3-5ubuntu4) 4.3.3" 
.section .note.GNU-stack,"",@progbits

Rispetto:

 .file "test.c" 
.text 
.globl main 
.type main, @function 
main: 
leal 4(%esp), %ecx 
andl $-16, %esp 
pushl -4(%ecx) 
pushl %ebp 
movl %esp, %ebp 
pushl %ecx 
movl $0, %eax 
popl %ecx 
popl %ebp 
leal -4(%ecx), %esp 
ret 
.size main, .-main 
.ident "GCC: (Ubuntu 4.3.3-5ubuntu4) 4.3.3" 
.section .note.GNU-stack,"",@progbits

su x86.

C'è un modo per rendere GCC -S sull'assemblaggio di uscita x86_64 senza il fluff?

+0

GCC 4.8 produce ora un'uscita più chiara di default. Sarebbe anche bello riassumere cosa intendi per pulito: le cose che rimuovi genererebbero un output ELF diverso ;-) –

risposta

5

La parte che entra nella sezione .eh_frame è descrittori di unwind, che è necessario solo per srotolare lo stack (ad esempio con GDB). Durante l'apprendimento dell'assemblaggio, puoi semplicemente ignorarlo. Ecco un modo per eseguire la "pulizia" desiderata:

gcc -S -o - test.c | sed -e '/^\.L/d' -e '/\.eh_frame/Q' 
     .file "test.c" 
     .text 
.globl main 
     .type main,@function 
main: 
     pushq %rbp 
     movq %rsp, %rbp 
     movl $0, %eax 
     leave 
     ret 
     .size main,.Lfe1-main 
+0

Fantastico! Grazie :-) – John

+0

Perché non usare solo -fno-exceptions -fno-rtti? – Trass3r

+2

Rimuovere tutte le etichette locali '.L' non sarà molto buono per le funzioni con loop o rami: / –

5

È possibile provare a inserire il codice che si desidera studiare in una funzione.

Es .:

int ftest(void) 
{ 
    return 0; 
} 

int main(void) 
{ 
    return ftest(); 
} 

Se si guarda alla catena di montaggio fonte per la prova sarà pulito come è necessario.

..snip.. 
test: 
.LFB2: 
     pushq %rbp 
.LCFI0: 
     movq %rsp, %rbp 
.LCFI1: 
     movl $0, %eax 
     leave 
     ret 
..snip.. 
+0

L'assembly per main è già abbastanza pulito ... –

+0

Sì, ma sta imparando (come me) e meno "confusione", meglio è. – slashmais

3

ho trovato che utilizzando il flag -Os rende le cose più chiare. Ho provato il tuo piccolo esempio, ma ha fatto poca differenza.

Detto questo, ricordo che è stato utile quando stavo imparando l'assemblaggio (su una Sparc).