我使用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
答案 0 :(得分:8)
这些是gas
对MASM frame handling pseudos的实施,用于生成可执行文件的.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没有操作系统支持运行时功能信息,我幸免 这部分。它只会增加x86 PE的可执行文件大小 这个目标并没有真正的好处。
简短概述:
目前有三种不同的功能输入格式预设。第一个是MIPS版。第二个版本适用于ARM,PPC,SH3, 和SH4主要用于Windows CE。第三个是IA64和x64版本。 注意,IA64尚未实现,但要查找有关的信息 请参阅关于IA64的规格 http://download.intel.com/design/Itanium/Downloads/245358.pdf档案。
第一个版本只包含pdata部分中的条目:BeginAddress, EndAddress,ExceptionHandler,HandlerData和PrologueEndAddress。 每个值都是指向相应数据的指针,大小为4 字节。
第二个变体在pdata部分中包含以下条目。 BeginAddress,PrologueLength(8位),EndAddress(22位), 使用-32位指令(1位)和Exception-Handler-Exists(1位)。 如果FunctionLength为零,或者Exception-Handler-Exists位为 如果是,则在函数输入之前直接放置DATA_EH块。
第三个版本有一个BeginAddress(RVA)的函数入口块, EndAddress(RVA)和UnwindData(RVA)。的描述 prologue,excepetion-handler和其他SEH数据存储在其中 xdata部分中的UNWIND_DATA字段。
.seh_proc< fct_name>
这指定SEH块开始用于函数&lt; fct_name&gt;。这对所有人都有效 目标<强> .seh_endprologue 强>
通过这个伪的序言结束地址的位置(由当前代码地址的外观采取 这个伪)。适用于所有目标。.seh_handler&lt; handler&gt; [,&lt; handler-data&gt;]
此伪指定要使用的处理函数。对于版本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&lt; reg&gt;,&lt; offset&gt;
通过这个伪帧的寄存器和偏移量(0-240之间的值与16字节 对齐)可以指定。这只是版本3使用。.seh_stackalloc&lt; size&gt;
通过这种方式,代码中的堆栈分配是针对版本3进行描述的。.seh_pushreg&lt; reg&gt;
通过这种方式,对于版本3描述了通用寄存器推入代码。.seh_savereg&lt; reg&gt;
通过这种方式,在版本3中描述了代码中的通用寄存器保存到存储器。.seh_savemm&lt; mm&gt;
通过这种方式,版本3中描述了代码中的mm寄存器保存到存储器。<强> .seh_savexmm 强>
通过这个,在版本3中描述了代码中的xmm寄存器保存到存储器。<强> .seh_pushframe 强>
有关条目类型的信息可以在版本3中进行描述。.seh_scope&lt; begin&gt;,&lt; end&gt;,&lt; handler&gt;,&lt; jump&gt;
通过此SCOPED条目可以指定展开或异常 版本3.这对UHANDLE和EHANDLER xdata有效 必须指定描述符和全局处理程序。对于处理程序和 可以使用跳转参数,@ 1,@ 0和@null的名称,它们是 指定必须使用常量而不是rva。
在https://sourceware.org/ml/binutils/2009-04/msg00181.html还有一些关于.xdata和.pdata(以及一堆链接)的核心讨论。
答案 1 :(得分:5)
我使用以下方法阻止他们输出:
gcc -S -fno-asynchronous-unwind-tables hi.c
所以我可以看一下。但我很高兴再也没有让它们输出了。
答案 2 :(得分:2)