我想知道 GCC 如何为 C++ 程序实现异常处理。我在 Web 上找不到易于理解且不言自明的文章(尽管有很多针对 Visual C++ 的此类文章)。我所知道的是 GCC 的实现被称为 DWARF 异常处理。
我编写了一个小型 C++ 程序并使用以下命令将其转换为程序集:
g++ main.cpp -S -masm=intel -fno-dwarf2-cfi-asm
这里给出了main.cpp和main.s文件。谁能解释一下 main.s 文件的内容,尤其是部分.gcc_except_table
和.eh_frame
逐行?(我的操作系统是 Ubuntu 13.04 32 位。)谢谢!
主.cpp:
void f()
{
throw 1;
}
int main()
{
int j;
try {
f();
} catch (int i) {
j = i;
}
return 0;
}
电源:
.file "main.cpp"
.intel_syntax noprefix
.text
.globl _Z1fv
.type _Z1fv, @function
_Z1fv:
.LFB0:
push ebp
.LCFI0:
mov ebp, esp
.LCFI1:
sub esp, 24
mov DWORD PTR [esp], 4
call __cxa_allocate_exception
mov DWORD PTR [eax], 1
mov DWORD PTR [esp+8], 0
mov DWORD PTR [esp+4], OFFSET FLAT:_ZTIi
mov DWORD PTR [esp], eax
call __cxa_throw
.LFE0:
.size _Z1fv, .-_Z1fv
.globl main
.type main, @function
main:
.LFB1:
push ebp
.LCFI2:
mov ebp, esp
.LCFI3:
and esp, -16
sub esp, 32
.LEHB0:
call _Z1fv
.LEHE0:
.L7:
mov eax, 0
jmp .L9
.L8:
cmp edx, 1
je .L6
mov DWORD PTR [esp], eax
.LEHB1:
call _Unwind_Resume
.LEHE1:
.L6:
mov DWORD PTR [esp], eax
call __cxa_begin_catch
mov eax, DWORD PTR [eax]
mov DWORD PTR [esp+24], eax
mov eax, DWORD PTR [esp+24]
mov DWORD PTR [esp+28], eax
call __cxa_end_catch
jmp .L7
.L9:
leave
.LCFI4:
ret
.LFE1:
.globl __gxx_personality_v0
.section .gcc_except_table,"a",@progbits
.align 4
.LLSDA1:
.byte 0xff
.byte 0
.uleb128 .LLSDATT1-.LLSDATTD1
.LLSDATTD1:
.byte 0x1
.uleb128 .LLSDACSE1-.LLSDACSB1
.LLSDACSB1:
.uleb128 .LEHB0-.LFB1
.uleb128 .LEHE0-.LEHB0
.uleb128 .L8-.LFB1
.uleb128 0x1
.uleb128 .LEHB1-.LFB1
.uleb128 .LEHE1-.LEHB1
.uleb128 0
.uleb128 0
.LLSDACSE1:
.byte 0x1
.byte 0
.align 4
.long _ZTIi
.LLSDATT1:
.text
.size main, .-main
.section .eh_frame,"a",@progbits
.Lframe1:
.long .LECIE1-.LSCIE1
.LSCIE1:
.long 0
.byte 0x1
.string "zPL"
.uleb128 0x1
.sleb128 -4
.byte 0x8
.uleb128 0x6
.byte 0
.long __gxx_personality_v0
.byte 0
.byte 0xc
.uleb128 0x4
.uleb128 0x4
.byte 0x88
.uleb128 0x1
.align 4
.LECIE1:
.LSFDE1:
.long .LEFDE1-.LASFDE1
.LASFDE1:
.long .LASFDE1-.Lframe1
.long .LFB0
.long .LFE0-.LFB0
.uleb128 0x4
.long 0
.byte 0x4
.long .LCFI0-.LFB0
.byte 0xe
.uleb128 0x8
.byte 0x85
.uleb128 0x2
.byte 0x4
.long .LCFI1-.LCFI0
.byte 0xd
.uleb128 0x5
.align 4
.LEFDE1:
.LSFDE3:
.long .LEFDE3-.LASFDE3
.LASFDE3:
.long .LASFDE3-.Lframe1
.long .LFB1
.long .LFE1-.LFB1
.uleb128 0x4
.long .LLSDA1
.byte 0x4
.long .LCFI2-.LFB1
.byte 0xe
.uleb128 0x8
.byte 0x85
.uleb128 0x2
.byte 0x4
.long .LCFI3-.LCFI2
.byte 0xd
.uleb128 0x5
.byte 0x4
.long .LCFI4-.LCFI3
.byte 0xc5
.byte 0xc
.uleb128 0x4
.uleb128 0x4
.align 4
.LEFDE3:
.ident "GCC: (Ubuntu/Linaro 4.7.3-1ubuntu1) 4.7.3"
.section .note.GNU-stack,"",@progbits