assembly - GAS ELF何时需要使用.type,.thumb,.size和.section指令?

标签 assembly arm gnu elf gas

我正在使用GNU作为针对基于ARM Cortex-M3的微控制器(缩略图2指令集)的汇编程序。

在某些示例代码中,我发现诸如.size.section.type之类的指令,据我所知是ELF指令。举个例子:

    .section    .text.Reset_Handler
    .weak       Reset_Handler
    .type       Reset_Handler, %function  
Reset_Handler:
    bl      main
    b       Infinite_Loop    
    .size   Reset_Handler, .-Reset_Handler


据说.type指令设置符号的类型-通常设置为%object(意味着数据?)或%function。我不知道这有什么区别。它并不总是包含在内,因此我不确定何时需要使用它。

也与此相关的是.thumb_func指令。从我阅读的内容来看,它可能等同于:

.thumb 
.type Symbol_Name, %function


还是完全不同?
.size应该设置与符号关联的大小。当需要时,我不知道。这是默认计算得出的,但可以用此伪指令覆盖吗?如果是这样-您什么时候要覆盖?

.section较容易找到文档,我想我对它的用途有一个很清楚的了解,但是我仍然不确定用法。以我的理解,它会在不同的ELF部分之间切换(对于代码,使用text,对于可写数据使用data,对于未初始化的数据使用bss,对于常量使用rodata,等等),并在需要时定义新的。我猜您会根据是否定义代码,数据,未初始化的数据等在这些之间切换。但是,为什么要像上面的示例那样为函数创建一个子节?

任何与此有关的帮助表示赞赏。如果您可以找到指向教程或文档的链接,这些链接可以更详细地说明这一点-对于新手来说最好理解-我将不胜感激。

到目前为止,Using as手册已经有所帮助-也许您可以比我更多地从中学到更多的知识。

最佳答案

多年来,我一直在为arm / thumb编程,很多汇编器,而那里的许多指令却很少。

正如另一个响应者所指出的,.thumb_func非常重要。

例如

.globl _开始
_开始:
b重置

重启:

。臂

.globl一
之一:
加r0,r0,#1
bx lr

。拇指

.globl二
二:
加r0,r0,#2
bx lr

.thumb_func
.globl三
三:
加r0,r0,#3
bx lr


.word二
.word三



.arm或曾经是.code32或.code 32之类的东西告诉它这是arm代码,而不是拇指代码,对于您的cortex-m3,您不需要使用。

同样,.thumb曾经是.code 16或可能仍然有效,相同的处理使下面的代码无法使用。

如果您使用的标签不是您需要从其他文件或间接​​分支到的全局标签,则不需要.thumb_func。但是为了正确计算到这些全局标签之一的分支地址(lsbit是thumb为1,arm为0),您需要将其标记为thumb或arm标签,而thumb_func这样做,否则必须在分支添加更多代码之前将该位置1,并且不能从C调用该标签。


00000000 <_开始>:
0:eaffffff b 4 <一个>

00000004 <一个>:
4:e2800001加r0,r0,#1
8:e12fff1e bx lr

0000000c <两个>:
c:3002将r0,#2
e:4770 bx lr

00000010 <三>:
10:3003加r0,#3
12:4770 bx lr
14:0000000c andeq r0,r0,ip
18:00000011 andeq r0,r0,r1,lsl r0



直到.thumb为止,汇编器都是所需的arm代码。

根据需要,两个和三个标签/功能都是拇指代码,但是两个标签的地址为偶数,而三个标签的地址为奇数。

最新的代码源工具用于汇编,链接和转储以上示例。

现在对于一切都是thumb(/ thumb2)的cortex-m3来说,thumb_func可能并不那么重要,它可能仅适用于命令行开关(非常容易进行实验以找出答案)。这是一个好习惯,以防万一您从仅拇指的处理器转移到普通的手臂/拇指核心。

汇编程序通常喜欢添加所有这些指令以及使事物看起来/感觉更像高级语言的其他方式。我只是说您不必使用它们,我为arm切换了汇编程序,并为许多不同的处理器使用了许多不同的汇编程序,并且宁愿少即是多的方法,这意味着着重于汇编本身,并使用尽可能少的工具特定项。我通常是例外,但不是规则,因此您可以通过查看编译器输出生成的指令来找出更常用的指令(并通过文档进行验证)。

unsigned int一个(unsigned int x)
{
return(x + 1);
}


.arch armv5te
.fpu softvfp
.eabi_attribute 20,1
.eabi_attribute 21,1
.eabi_attribute 23,3
.eabi_attribute 24,1
.eabi_attribute 25,1
.eabi_attribute 26,2
.eabi_attribute 30,2
.eabi_attribute 18,4
.file“ bob.c”
。文本
.align 2
.global一
。类型一,%功能
之一:
.fnstart
.LFB0:
@ args = 0,假装= 0,框架= 0
@ frame_needed = 0,uses_anonymous_args = 0
@链接寄存器保存消除。
加r0,r0,#1
bx lr
.fnend
.size一,.- one
.ident“ GCC:(Sourcery G ++ Lite 2010.09-50)4.5.1”
.section .note.GNU-stack,“”,%progbits



当将arm和thumb汇编程序或数据与汇编器混合使用时,我确实使用.align,您希望此类平台的汇编程序知道一些明显的信息,例如Thumb指令位于半字边界上,而arm指令则位于字边界上。这些工具并不总是那么聪明。洒.aligns不会受伤

.text是默认值,因此有点多余,但不会造成伤害。 .text和.data是标准属性(不是特定于arm的),如果您要在目标上针对rom和ram的组合进行编译(取决于您对链接脚本的处理方式),那么.text将适用于所有内容。

.size显然是该指令的函数大小。汇编器无法自行解决此问题,因此,如果此函数的大小对您的代码,链接程序脚本,调试器,加载器很重要,那么无论什么情况都需要正确处理,否则就不必费心了。无论如何,函数是一个高级概念,汇编器实际上并不需要函数,而无需声明其大小。而且C编译器当然不在乎,它只是在寻找要分支的标签,而对于arm系列,则是拇指代码或分支的arm代码。

如果您在较长的代码段上不喜欢即时数(ldr rx,= 0x12345678),可能会发现.pool指令(有一个更新的等效项)很有用。有时候,您有时告诉他们,这些工具并不总是足够聪明,无法将这些数据放在无条件分支之后。我认真地说一句懒惰,做标签总是很痛苦的。.word一直都在做,我相信arm和gcc工具都允许该快捷方式,所以我会像其他人一样使用它。

还要注意,llvm向binutils输出一个或多个附加的.eabi_attribute或两个,该代码源的版本/ mods支持该附加.eabi_attribute,但gnu发布的binutils不支持(也许尚未)。两种可行的解决方案是,修改llvm的asm打印功能,使其不编写eabi_attributes或至少不带注释(@)的形式,或者从代码源获取binutils源/ mod,并以这种方式构建binutils。代码源往往倾向于引导gnu(例如,支持thumb2),或者可能会向后移植新功能,因此我认为这些llvm属性不久就会出现在主线binutils中。通过修剪llvm编译代码中的eabi_attributes,我没有遭受任何不良影响。

这是上面相同功能的llvm输出,显然这是我修改以注释掉eabi_attributes的llc。

.syntax统一
@ .eabi_attribute 20,1
@ .eabi_attribute 21,1
@ .eabi_attribute 23,3
@ .eabi_attribute 24,1
@ .eabi_attribute 25,1
@ .eabi_attribute 44,1
.file“ bob.bc”
。文本
.globl一
.align 2
类型一,%功能
一一
@ BB#0:@%entry
加r0,r0,#1
bx lr
.Ltmp0:
.size一,.Ltmp0-一


如果您想真正了解elf专用指令(如果有)的作用,则elf文件格式有充分的文档记录,并且非常容易解析。这些指令中的许多指令对链接器的帮助最大。例如.thumb_func,.text,.data。

关于assembly - GAS ELF何时需要使用.type,.thumb,.size和.section指令?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4423211/

相关文章:

linux - GNU find -exec 命令 {} ; vs -exec 命令 {} +

c++ - 代码块显示错误 : This file requires support for the ISO C++ 2011 standard

assembly - x86 汇编中端口 I/O 后 jmp 短接的用途

c - 'switch' 比 'if' 快吗?

c - GCC 认为 int 指针在 ARM 上未对齐

linux - 安全模式如何访问安全/非安全内存?

assembly - 如何在保持一个值不变的情况下翻转 SSE 中的范围?

linux - 如何用Fedora16测试汇编语言的LIDT指令?

c - SPI_IOC_MESSAGE 返回 EINVAL

linux - Hook bash 命令?