Очистить сборку сборки x86_64 с помощью gcc?

Я уже некоторое время преподаю себе сборку GNU, написав инструкции на C, компилируя их с помощью "gcc -S" и изучая вывод. Это хорошо работает на x86 (и компилируется с -m32), но на моем ящике AMD64 для этого кода (как пример):

int main()
{
    return 0;
}

GCC дает мне:

 .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

По сравнению с:

 .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

на x86.

Есть ли способ сделать GCC -S на выходе x86_64 Сборка без пуха?

Ответ 1

Материал, который входит в раздел .eh_frame, - это разматывать дескрипторы, которые вам нужно только для разворачивания стека (например, с помощью GDB). Изучая сборку, вы можете просто проигнорировать ее. Вот способ сделать "очистку", которую вы хотите:

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

Ответ 2

Вы можете попробовать разместить код, который хотите изучить, в функции.

например:.

int ftest(void)
{
    return 0;
}

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

Если вы посмотрите на источник сборки для теста, он будет таким же чистым, насколько вам нужно.

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

Ответ 3

Я обнаружил, что использование флага -Os делает вещи более ясными. Я попробовал это на вашем крошечном примере, но это сделало очень мало.

Тем не менее, я помню, что это было полезно, когда я изучал сборку (на Sparc).