我正在研究基于ARM Cortex-M3的微控制器(Thumb 2指令集)的汇编程序,使用GNU as。
在一些示例代码中,我发现.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
指令设置符号的类型 - 通常是%对象(表示数据?)或%函数。我不知道它有什么不同。它并不总是包括在内,所以我不确定何时需要使用它。
与此相关的还有.thumb_func
指令。根据我的阅读,似乎可能等同于:
.thumb
.type Symbol_Name, %function
或者是完全不同的东西?
.size
假定设置与符号关联的大小。如果需要,我不知道。这是默认计算的,但可以使用此指令覆盖吗?如果是这样 - 你想什么时候覆盖?
.section
更容易找到文档,我想我对做什么有一个很好的想法,但我是对使用情况仍然有点不确定。我理解它的方式是,它在不同的ELF部分之间切换(text
表示代码,data
表示可写数据,bss
表示未初始化数据,rodata
表示常量,以及其他部分) ,并在需要时定义新的。我猜你会根据你是否定义代码,数据,未初始化的数据等来切换它们。但是为什么要为函数创建一个子部分,如上例所示?
到目前为止,Using as手册已经提供了一些帮助 - 也许你可以通过更多的知识获得更多信息。
答案 0 :(得分:10)
答案 1 :(得分:5)
程序的各个部分与ELF格式密切相关,大多数系统(Linux,BSD,...)存储其对象和可执行文件。 This article应该让您对ELF的工作方式有一个很好的了解,这将有助于您了解各部分的原因。
简单地说,部分允许您将程序组织到具有不同属性的不同内存区域,包括地址,执行和写入权限等。在最后的链接阶段,链接器使用通常的linker script将所有相同名称的部分组合在一起(例如,所有编译单元中的所有代码在一起,......)并在内存中为它们分配最终地址。
对于嵌入式系统,它们的使用尤为明显:首先,必须将引导代码(通常包含在.text
部分中)加载到固定地址才能执行。然后,只读数据可以被分组为专用的只读部分,该部分将被映射到设备的ROM区域。最后一个例子:操作系统具有初始化函数,这些函数只被调用一次,然后从未使用过,浪费了宝贵的内存空间。如果将所有这些初始化函数组合在一起称为.initcode
的专用部分,并且如果将此部分设置为程序的最后一部分,则操作系统可以在初始化完成后轻松回收此内存通过降低自己记忆的上限。例如Linux已知使用该技巧,并且GCC允许您通过使用__attribute__ ((section ("MYSECTION")))
.type
和.size
实际上对我来说仍然不太清楚。我将它们视为链接器的助手,并且从未在汇编程序生成的代码之外看到它们。
.thumb_func
,以便允许与Arm代码互通。除非您使用旧的工具链,否则您可能不必担心它。
答案 2 :(得分:5)
我试图弄清楚为什么ARM和Thumb互通与最近的binutils打破了(用2.21.53(MacPorts)验证,也验证了2.22(Yagarto 4.7.1))。
根据我的经验,.thumb_func
与早期的binutils一起工作正常,可以生成正确的交互操作胶合代码。但是,随着最近的发布,
需要.type *name*, %function
指令来确保正确生成单板。
我懒得挖掘旧版本的binutils以检查.type
指令是否足以代替.thumb_func
以用于早期的binutils。我想在你的代码中包含这两个指令没有坏处。
编辑:更新了在代码中使用.thumb_func
的评论,显然它适用于ARM-> Thumb互通以标记Thumb例程以生成胶合代码,但Thumb-> ARM互通失败,除非{{1 }}指令用于标记ARM函数。