【问题标题】:x86 gcc assembly output help pleasex86 gcc 程序集输出帮助请
【发布时间】:2010-05-24 00:19:40
【问题描述】:

下面粘贴的是“int main(){}”的未优化 GCC 程序集输出。我对 x86 汇编比较熟悉,但其中一些是不熟悉的。有人可以逐行演练这里发生的事情吗?

谢谢!

    .text
.globl _main
_main:
LFB2:
    pushq   %rbp
LCFI0:
    movq    %rsp, %rbp
LCFI1:
    leave
    ret
LFE2:
    .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   LFB2-.
    .set L$set$2,LFE2-LFB2
    .quad L$set$2
    .byte   0x0
    .byte   0x4
    .set L$set$3,LCFI0-LFB2
    .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

【问题讨论】:

    标签: c gcc assembly


    【解决方案1】:

    告诉链接器将其放入可执行文件的.text 部分:

        .text
    

    main 导出为外部符号:

    .globl _main
    

    定义main 函数本身:

    _main:
    LFB2:
    

    保存上一帧指针:

        pushq   %rbp
    LCFI0:
    

    设置新的帧指针:

        movq    %rsp, %rbp
    LCFI1:
    

    恢复旧的帧指针并返回给调用者:

        leave
        ret
    

    以下指令设置了一个 .eh_frame 部分,其中包含 C++ 运行时处理异常所需的信息。

    LFE2:
        .section __TEXT,__eh_frame,coalesced,no_toc+strip_static_syms+live_support
    

    这是公共信息条目表:

    EH_frame1:
    

    它以长度开头,根据LSCIE1LECIE1 标签的差异计算得出:

        .set L$set$0,LECIE1-LSCIE1
        .long L$set$0
    

    .long.byte.ascii.quad 导致适当类型的值由汇编器直接发出)。然后遵循 CIE 表本身:

    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:
    

    另一个外部符号,这个是main函数的Frame Description Entry(仍然是异常处理信息的一部分):

    .globl _main.eh
    _main.eh:
    

    同样,FDE 以长度开头:

    LSFDE1:
        .set L$set$1,LEFDE1-LASFDE1
        .long L$set$1
    

    ..并继续 FDE 表的其余部分。

    LASFDE1:
        .long   LASFDE1-EH_frame1
        .quad   LFB2-.
        .set L$set$2,LFE2-LFB2
        .quad L$set$2
        .byte   0x0
        .byte   0x4
        .set L$set$3,LCFI0-LFB2
        .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
    

    那些异常处理表大多是无趣的,但如果你想知道格式上的信息是available here

    【讨论】:

    • 奇怪的是那里有 C++ 功能。我用 gcc 生成了输出。
    【解决方案2】:

    汇编语言的行数很少。其他是定义(所有以点 (.) 开头)大部分是内存分配,其他的可以在 gcc 文档中轻松找到。

    LFB2:
        pushq   %rbp
    LCFI0:
        movq    %rsp, %rbp
    LCFI1:
        leave
        ret
    

    这是进入/退出堆栈帧。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2010-11-21
      • 2021-08-11
      • 1970-01-01
      • 2013-10-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多