我正在使用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/