使用gcc清理x86_64程序集输出?

使用gcc清理x86_64程序集输出?,gcc,assembly,x86-64,Gcc,Assembly,X86 64,我自学GNU汇编已经有一段时间了,我用C编写语句,用“gcc-S”编译语句,并研究输出。这在x86(以及使用-m32编译)上可以正常工作,但在我的AMD64机器上,对于这段代码(仅作为示例): GCC给了我: .file "test.c" .text .globl main .type main, @function main: .LFB2: pushq %rbp .LCFI0: movq %rsp, %rbp .LCFI1: movl $0, %eax leave ret .LF

我自学GNU汇编已经有一段时间了,我用C编写语句,用“gcc-S”编译语句,并研究输出。这在x86(以及使用-m32编译)上可以正常工作,但在我的AMD64机器上,对于这段代码(仅作为示例):

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” .文本 格洛博梅因酒店 .type main,@函数 主要内容: .LFB2: pushq%rbp .LCFI0: movq%rsp,%rbp .LCFI1: movl$0,%eax 离开 ret .LFE2: .主要尺寸,.-主要尺寸 .section.eh_帧,“a”@progbits .1: .long.LECIE1-.LSCIE1 .LSCIE1: .long 0x0 .字节0x1 .字符串“zR” .uleb128 0x1 .sleb128-8 .字节0x10 .uleb128 0x1 .字节0x3 .字节0xc .uleb128 0x7 .uleb128 0x8 .字节0x90 .uleb128 0x1 .对齐8 .LECIE1: .LSFDE1: .long.lefte1-.LASFDE1 .LASFDE1: .long.LASFDE1-.Lframe1 .long.LFB2 .long.LFE2-.LFB2 .uleb128 0x0 .字节0x4 .long.LCFI0-.LFB2 .字节0xe .uleb128 0x10 .字节0x86 .uleb128 0x2 .字节0x4 .long.LCFI1-.LCFI0 .字节0xd .uleb128 0x6 .对齐8 .Lefte1: .ident“GCC:(Ubuntu 4.3.3-5ubuntu4)4.3.3” .section.note.GNU堆栈,“,@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 .file“test.c” .文本 格洛博梅因酒店 .type main,@函数 主要内容: leal 4(%esp),%ecx andl$-16%,特别是 PUSH-4(%ecx) 推力%ebp 移动%esp,%ebp pushl%ecx movl$0,%eax popl%ecx popl%ebp leal-4(%ecx),%esp ret .主要尺寸,.-主要尺寸 .ident“GCC:(Ubuntu 4.3.3-5ubuntu4)4.3.3” .section.note.GNU堆栈,“,@progbits 在x86上


有没有一种方法可以在x86_64输出程序集上生成GCC-S而不产生绒毛?

您可以尝试将要学习的代码放入函数中

例如:

如果您查看用于测试的程序集源代码,它将尽可能干净

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

我发现使用
-Os
标志可以让事情更清楚。我试过了你的小例子,但没什么不同


也就是说,我记得当我学习汇编(在Sparc上)时,它很有用。

进入
部分的内容是展开描述符,您只需要展开堆栈(例如,使用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

main的程序集已经相当干净了……是的,但他正在学习(和我一样)&越少的“混乱”越好。为什么不使用-fno exceptions-fno rtti呢?删除所有
.L
本地标签对于带有循环或分支的函数来说不是很好:/GCC 4.8现在默认情况下会产生更清晰的输出。总结一下“干净”是什么意思也很酷:删除的东西会产生不同的ELF输出;-)
..snip..
test:
.LFB2:
        pushq   %rbp
.LCFI0:
        movq    %rsp, %rbp
.LCFI1:
        movl    $0, %eax
        leave
        ret
..snip..
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