什么是.seh_*gcc输出的汇编命令?

Jos*_*osh 13 assembly gcc x86-64

我使用gcc -S作为hello world程序.什么是5 .seh_命令?当我搜索时,我似乎无法找到关于它们的更多信息.

    .file   "hi.c"
    .def    __main; .scl    2;  .type   32; .endef
    .section .rdata,"dr"
.LC0:
    .ascii "Hello World\0"
    .text
    .globl  main
    .def    main;   .scl    2;  .type   32; .endef
    .seh_proc   main
main:
    pushq   %rbp
    .seh_pushreg    %rbp
    movq    %rsp, %rbp
    .seh_setframe   %rbp, 0
    subq    $32, %rsp
    .seh_stackalloc 32
    .seh_endprologue
    call    __main
    leaq    .LC0(%rip), %rcx
    call    puts
    movl    $0, %eax
    addq    $32, %rsp
    popq    %rbp
    ret
    .seh_endproc
    .ident  "GCC: (rubenvb-4.8.0) 4.8.0"
    .def    puts;   .scl    2;  .type   32; .endef
Run Code Online (Sandbox Code Playgroud)

Dav*_*erd 9

这些是gasMASM的帧处理伪的实现,用于生成可执行文件的.pdata和.xdata部分(结构化异常处理的东西).还可以查看Raw Pseudo Operations.显然,如果您的代码在SEH展开操作期间可能在堆栈中,您应该使用这些代码.

我发现轻微的更多信息https://sourceware.org/ml/binutils/2009-08/msg00193.html.这个线程似乎是gas为所有.set_*伪操作添加支持的原始签到.

我想通过气体显示.pdata和.xdata生成pe-coff目标的补丁,并获得一些反馈.此补丁包括对arm,ppc,arm,sh(3&4),mips和x64的支持.至于x86,没有OS支持运行时功能信息,我没有这部分.它只会增加x86 PE的可执行文件大小,并且此目标没有实际增益.

简短概述:
目前有三种不同的功能输入格式预设.

第一个是MIPS.第二个版本适用于ARM,PPC,SH3和SH4,主要用于Windows CE.第三个是IA64和x64版本.注意,IA64尚未实现,但要查找有关它的信息,请参阅http://download.intel.com/design/Itanium/Downloads/245358.pdf文件中有关IA64的规范 .

第一个版本只有pdata部分中的条目:BeginAddress,EndAddress,ExceptionHandler,HandlerData和PrologueEndAddress.每个值都是指向相应数据的指针,大小为4个字节.

第二个变体在pdata部分中包含以下条目.BeginAddress,PrologueLength(8位),EndAddress(22位),Use-32位指令(1位)和Exception-Handler-Exists(1位).如果FunctionLength为零,或者Exception-Handler-Exists位为true,则在函数输入之前直接放置DATA_EH块.

第三个版本具有BeginAddress(RVA),EndAddress(RVA)和UnwindData(RVA)的功能输入块.序言,excepetion-handler和其他SEH数据的描述存储在xdata部分的UNWIND_DATA字段中.

.seh_proc <fct_name>
这指定SEH块开始于函数<fct_name>.这适用于所有目标.

.seh_endprologue
这个伪的序言结束地址的位置(由这个伪的外观的当前代码地址采用).适用于所有目标.

.seh_handler <handler> [,<handler-data>]
这个伪指定要使用的处理函数.对于版本2,handler-data字段指定用户可选数据块.对于版本3,handler-data字段可以是rva到用户数据(对于FHANDLER),如果名称为@unwind,则生成UHANDLER展开块,如果是@except(或根本未指定),则为EHANDLER异常块生成.

.seh_eh
此伪用于版本2以指示函数在汇编中开始的位置.这里PDATA_EH数据可以存储到.

.seh_32/.seh_no32
这个伪仅用于版本2(参见上面的描述).目前,如果未指定,则默认为no32.

.seh_endproc
通过此伪指定SEH块的结尾.

.seh_setframe <reg>,<offset>
通过此伪,可以指定帧寄存器和偏移量(0-240之间的值,16字节对齐).这只是版本3使用的.

.seh_stackalloc <size>
通过此代码堆栈分配在版本3中进行了描述.

.seh_pushreg <reg>
通过这个版本3描述了通用寄存器推送代码.

.seh_savereg <reg>
这样就可以在版本3中描述通用寄存器保存到代码中的内存.

.seh_savemm <mm>
由此在版本3中描述了代码中的mm寄存器保存到存储器.

.seh_savexmm
由此在版本3中描述了代码中的xmm寄存器保存到内存.

.seh_pushframe
有关条目类型的信息可以在版本3中描述.

.seh_scope <begin>,<end>,<handler>,<jump>
通过此SCOPED条目可以为版本3指定展开或异常.这仅对UHANDLE和EHANDLER xdata描述符有效,并且必须指定全局处理程序.对于处理程序和跳转参数,可以使用@ 1,@ 0和@null的名称,它们指定必须使用常量而不是rva.

https://sourceware.org/ml/binutils/2009-04/msg00181.html上还有一些关于.xdata和.pdata(以及一堆链接)的核心讨论.


Jos*_*osh 6

我使用以下方法阻止他们输出:

gcc -S -fno-asynchronous-unwind-tables hi.c
Run Code Online (Sandbox Code Playgroud)

所以我可以看一下.但我很高兴再也没有输出了.