什么时候需要 GAS ELF 指令 .type、.thumb、.size 和 .section? [英] When are GAS ELF the directives .type, .thumb, .size and .section needed?

查看:24
本文介绍了什么时候需要 GAS ELF 指令 .type、.thumb、.size 和 .section?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用 GNU 作为基于 ARM Cortex-M3 的微控制器(Thumb 2 指令集)的汇编程序.

在一些示例代码中,我发现像 .size.section.type 这样的指令是 ELF 指令.举个例子:

 .section .text.Reset_Handler.weak Reset_Handler.type Reset_Handler, %function重置处理程序:主要b 无限循环.size Reset_Handler, .-Reset_Handler



据说 .type 指令用于设置符号的类型 - 通常为 %object(表示数据?)或 %function.我不知道它有什么不同.它并不总是包含在内,所以我不确定何时需要使用它.

与此相关的还有 .thumb_func 指令.根据我的阅读,它似乎可能相当于:

.thumb.type Symbol_Name, %function

或者是完全不同的东西?



.size 应该设置与符号关联的大小.什么时候需要,我不知道.这是默认计算的,但可以用这个指令覆盖吗?如果是这样 - 你什么时候想要覆盖?



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


对此的任何帮助表示赞赏.如果您能找到更详细解释这一点的教程或文档的链接——最好是新手可以理解的——我将不胜感激.

到目前为止,使用 as 手册已经提供了一些帮助 - 也许您可以获得比我更擅长,知识更丰富.

解决方案

多年来,我一直在编写 arm/thumb 的许多汇编程序,并且需要的指令很少.

.thumb_func 正如另一位响应者指出的那样非常重要.

例如

<上一页>.globl _start_开始:b 重置重启:.手臂.globl 一一:添加 r0,r0,#1bx lr.拇指.globl 二二:添加 r0,r0,#2bx lr.thumb_func.globl 三三:添加 r0,r0,#3bx lr.字二.word 三

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

.thumb 同样,以前是 .code 16 或者可能仍然有效,同样的处理使以下代码拇指不支持.

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

<上一页>00000000 <_开始>:0: eaffffff b 4 <one>00000004 <一>:4: e2800001 添加 r0, r0, #18:e12fff1e bx lr0000000c <二>:c: 3002 添加 r0, #2e: 4770 bx lr00000010<三>:10: 3003 添加 r0, #312:4770 bx lr14: 0000000c andeq r0, r0, ip18: 00000011 andeq r0, r0, r1, lsl r0

直到 .thumb 为止,汇编器都是根据需要的 arm 代码.

两个和三个标签/功能都是所需的拇指代码,但两个标签具有偶数地址,三个标签具有正确的奇数地址.

使用最新的代码源工具来组装、链接和转储上述示例.

现在对于一切都是 thumb(/thumb2) 的 cortex-m3,thumb_func 可能不那么重要了,它可能只适用于命令行开关(很容易做一个实验来找出).不过,如果您从仅使用拇指的处理器转移到普通的手臂/拇指内核,这是一个好习惯.

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

<上一页>无符号整数一(无符号整数 x){返回(x+1);}.arch armv5te.fpu 软vfp.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鲍勃.c".文本.对齐 2.global 一.type 一,%function一:.fnstart.LFB0:@args = 0,假装 = 0,帧 = 0@frame_needed = 0,使用_anonymous_args = 0@链接寄存器保存消除.添加 r0, r0, #1bx lr.fnend.size 一个,.-one.identGCC:(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 系列的情况下,它是要分支到的 thumb 代码还是 arm 代码.

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

另请注意,llvm 会向 binutils 输出一个或两个额外的 .eabi_attribute,这些 .eabi_attribute 受 code sourcery 的 version/mods 支持,但 gnu 发布的 binutils 不支持(可能还没有).两种可行的解决方案,修改 llvm 的 asm 打印函数以不编写 eabi_attributes 或至少用注释 (@) 编写它们,或者从代码源中获取 binutils 源/模块并以这种方式构建 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 一.对齐 2.type一,%函数一一@BB#0: @%entry添加 r0, r0, #1bx lr.ltmp0:.size 一个,.Ltmp0-one

elf 文件格式有据可查,如果您想真正了解 elf 特定指令(如果有的话)在做什么,那么它很容易解析.其中许多指令对链接器的帮助比什么都大.例如 .thumb_func、.text、.data.

I'm working on an assembly program for an ARM Cortex-M3 based microcontroller (Thumb 2 instruction set), using GNU as.

In some example code I find directives like .size, .section and .type which I understand are ELF directives. As an example:

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



The .type directive is said to set the type of a symbol - usually either to %object (meaning data?) or %function. I do not know what difference it makes. It is not always included, so I am unsure when it needs to be used.

Also related to this is the .thumb_func directive. From what I have read it seems like it might be equivalent of:

.thumb 
.type Symbol_Name, %function

Or is it something completely different?



.size supposedly sets the size associated with a symbol. When this is needed, I have no idea. Is this calculated by default, but overrideable with this directive? If so - when would you want to override?



.section is easier to find docs on, and I think I have a fair idea of what it does, but I am still a little bit unsure about the usage. The way I understand it, it switches between different ELF sections (text for code, data for writable data, bss for uninitialized data, rodata for constants, and others), and defines new ones when desired. I guess you would switch between these depending on whether you define code, data, uninitialized data, etc. But why would you create a subsection for a function, as in the example above?


Any help with this is appreciated. If you can find links to tutorials or docs that explain this in greater detail - preferably understandable for a novice - I would be very grateful.

So far, the Using as manual has been of some help - maybe you can get more out of it than me, with more knowledge.

解决方案

I have been programming arm/thumb for many years lots of assembler and have needed very few of the many directives out there.

.thumb_func is quite important as pointed out by another responder.

for example

.globl _start
_start:
    b   reset

reset:

.arm

.globl one
one:
    add r0,r0,#1
    bx lr

.thumb

.globl two
two:
    add r0,r0,#2
    bx lr

.thumb_func
.globl three
three:
    add r0,r0,#3
    bx lr


.word two
.word three

.arm or used to be something like .code32 or .code 32 tells it this is arm code not thumb code, which for your cortex-m3 you won't need to use.

.thumb likewise, used to be .code 16 or maybe that still works, same deal makes the following code thumb not arm.

If the labels you are using are not global labels that you need to branch to from other files or indirectly, then won't need the .thumb_func. But in order for the address of a branch to one of these global labels to be computed properly (lsbit is a 1 for thumb and 0 for arm) you want to mark it as a thumb or arm label and the thumb_func does that, otherwise you have to set that bit before branching adding more code and the label is not callable from C.


00000000 <_start>:
   0:   eaffffff    b   4 <one>

00000004 <one>:
   4:   e2800001    add r0, r0, #1
   8:   e12fff1e    bx  lr

0000000c <two>:
   c:   3002        adds    r0, #2
   e:   4770        bx  lr

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

Up to the .thumb the assembler is arm code as desired.

Both the two and three labels/functions are thumb code as desired but the two label has an even numbered address and three has the proper odd numbered address.

The latest codesourcery tools were used to assemble, link, and dump the above sample.

Now for the cortex-m3 where everything is thumb(/thumb2) thumb_func may not be as important, it may just work with command line switches (very easy to do an experiment to find out). It is a good habit to have though in case you move away from a thumb only processor to a normal arm/thumb core.

Assemblers generally like to add all of these directive and other ways of making things look/feel more like a high level language. I am just saying you don't have to use them, I switched assemblers for arm and use many different assemblers for many different processors and prefer the less is more approach, meaning focus on the assembly itself and use as few tool specific items as possible. I am usually the exception not the rule though, so you can probably figure out the more often used directives by looking at what directives the compiler output generates (and verify with documentation).

unsigned int one ( 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"
    .text
    .align  2
    .global one
    .type   one, %function
one:
    .fnstart
.LFB0:
    @ args = 0, pretend = 0, frame = 0
    @ frame_needed = 0, uses_anonymous_args = 0
    @ link register save eliminated.
    add r0, r0, #1
    bx  lr
    .fnend
    .size   one, .-one
    .ident  "GCC: (Sourcery G++ Lite 2010.09-50) 4.5.1"
    .section    .note.GNU-stack,"",%progbits

I do use the .align when mixing arm and thumb assembler or data in with assembler, you would expect the assembler for such a platform to know something as obvious as thumb instructions are on halfword boundaries and arm instructions are aligned on word boundaries. The tools are not always that smart. Sprinkling .aligns about won't hurt.

.text is the default so that is a bit redundant, but won't hurt. .text and .data are standard attributes (not specific to arm) if you are compiling for a combination of rom and ram on your target you may care (depends on what you do with your linker script), otherwise .text will work for everything.

.size apparently the size of the function start to that directive. The assembler cannot figure this out on its own, so if the size of this function is important for your code, linker script, debugger, loader, whatever then this needs to be right, otherwise you don't have to bother. A function is a high level concept anyway assembler doesn't really have functions much less a need to declare their size. And the C compiler certainly doesn't care, it is only looking for a label to branch to and in the case of the arm family is it thumb code or arm code that is being branched to.

you may find the .pool directive (there is a newer equivalent) useful if you are lazy with your immediates (ldr rx,=0x12345678) on long stretches of code. Here again the tools are not always smart enough to place this data after an unconditional branch, you sometimes have tell them. I say lazy half seriously, it is painful to do the label: .word thing all the time and I believe both the arm and gcc tools allowed for that shortcut, so I use it as much as anyone else.

Also note llvm outputs an additional .eabi_attribute or two that is supported by code sourcery's version/mods to binutils but not supported (perhaps yet) by the gnu released binutils. Two solutions that work, modify llvm's asm print function to not write the eabi_attributes or at least write them with a comment (@), or get the binutils source/mods from code sourcery and build binutils that way. code sourcery tends to lead gnu (thumb2 support for example) or perhaps backports new features, so I assume these llvm attrubutes will be present in the mainline binutils before long. I have suffered no ill effects by trimming the eabi_attributes off of the llvm compiled code.

Here is the llvm output for the same function above, apparently this is the llc that I modified to comment out the eabi_attributes.

    .syntax unified
@   .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"
    .text
    .globl  one
    .align  2
    .type   one,%function
one:                                    @ @one
@ BB#0:                                 @ %entry
    add r0, r0, #1
    bx  lr
.Ltmp0:
    .size   one, .Ltmp0-one

The elf file format is well documented and very easy to parse if you want to really see what the elf specific directives (if any) are doing. Many of these directives are to help the linker more than anything. .thumb_func, .text, .data for example.

这篇关于什么时候需要 GAS ELF 指令 .type、.thumb、.size 和 .section?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆