x86_64 salida de montaje limpia con gcc? [duplicar]
Pregunta
Esta pregunta ya tiene una respuesta aquí:
He estado enseñando a mí mismo GNU Asamblea desde hace un tiempo escribiendo declaraciones en C, compilar con "gcc -S" y el estudio de la salida. Esto funciona bien en x86 (y compilar con -m32), pero en mi caja de AMD64, para este código (sólo como ejemplo):
int main()
{
return 0;
}
GCC me da:
.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
En comparación con:
.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
en x86.
¿Hay una manera de hacer GCC -S en la Asamblea de salida x86_64 sin la pelusa?
Solución
El material que entra en la sección .eh_frame
es descriptores de desenrollado, que sólo tendrá que descansar pila (por ejemplo, con el BGF). Mientras que el conjunto de aprendizaje, usted podría simplemente ignorarlo. Aquí es una manera de hacer la "limpieza" que desee:
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
Otros consejos
Puede intentar colocar el código que desea estudiar en una función.
por ejemplo:.
int ftest(void)
{
return 0;
}
int main(void)
{
return ftest();
}
Si nos fijamos en el conjunto de código para la prueba será tan limpio como sea necesario.
..snip..
test:
.LFB2:
pushq %rbp
.LCFI0:
movq %rsp, %rbp
.LCFI1:
movl $0, %eax
leave
ret
..snip..
He encontrado que el uso de la bandera -Os
hace las cosas más claras. Lo probé su pequeño ejemplo, pero hizo muy poca diferencia.
Dicho esto, recuerdo que es muy útil cuando estaba aprendiendo de montaje (en un Sparc).