好记性不如铅笔头

ARM, 操作系统

《RealView编译工具汇编器指南》摘录:汇编语言模块的结构

备注:

1 本部分文档摘录自ARM网站【 http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0204ic/index.html 】,版权归属于ARM。

2 作者只摘录了部分内容,全面详细的内容清参考ARM网址。

2.3. 汇编语言模块的结构

汇编语言是指 ARM 汇编器 (armasm) 进行分析并汇编生成对象代码的语言。 缺省情况下,汇编器应使用 ARM 汇编语言编写源代码。
armasm 支持用旧版本的 ARM 汇编语言编写的源代码。 在这种情况下,它无需获得相应的通知。
armasm 还可支持用 UAL 以前的 Thumb 汇编语言编写的源代码。 在这种情况下,必须在源代码中使用 –16 命令行选项或 CODE16 指令通知 armasm。 UAL 以前的 Thumb 汇编语言不支持 Thumb-2 指令。

2.3.1. 汇编语言源文件的编排

汇编语言的源代码行的一般格式是:
{label} {instruction|directive|pseudo-instruction} {;comment}

Note

即使没有标签,指令、伪指令和命令前面也必须使用空格或制表符等留出空白。
某些指令不允许使用标签。
源代码行的所有三部分都是可选的。 使用空行可使代码更具可读性。

大小写规则

指令助记符、指令和符号寄存器名称可以用大写或小写,但不能混合使用大小写

行长度

为使源文件更容易阅读,可以在行尾放置反斜杠字符 (\),将较长的源代码行拆分为多个行。 反斜杠后面不得有任何其他字符(包括空格和制表符)。 汇编器将反斜杠后跟行尾序列视为空白。

Note

不要在带引号的字符串内使用反斜杠后跟行尾序列。
行长度的最大值为 4095 个字符,包括使用反斜杠的任何扩展在内。

标签

标签是表示地址的符号。 在汇编期间将计算由标签指定的地址。
汇编器计算标签相对于定义标签的节的原点的地址。 引用同一节内的标签时可以使用 pc 加上或减去偏移量。 这称为程序相对寻址。
其他节中标签的地址是在链接时计算的,此时链接器已在内存中为每一节分配了具体的位置。

局部标签

局部标签是标签的一个子类。 局部标签以 0 到 99 范围内的某个数字开头。与其他标签不同的是,局部标签可以定义多次。 如果用宏生成标签,局部标签就十分有用。 当汇编器找到一个对局部标签的引用时,就会将其链接到该局部标签的相邻实例上。
局部标签的范围由 AREA 指令加以限制。 使用 ROUT 指令可以更严格地限制其范围。
有关下列主题的详细信息,请参阅局部标签:
    局部标签的声明语法
    汇编器如何将对局部标签的引用与其标签相关联

注释

行中的第一个分号标记注释的开始,但不包括出现在字符串常数内的分号。 行的末尾就是注释的结束。 一个注释本身就是一个有效的行。 汇编器将忽略所有注释。

常数

常数可以是:

数字

    可接受下列形式的数字常数:
        十进制数,例如 123
        十六进制数,例如 0x7B
        n_xxx,其中:
        n
            是 2 到 9 之间的基数
        xxx
            是采用该基数的数字
        浮点数,例如 0.02、123.0 或 3.14159
    仅当系统具有使用浮点数的 VFP 或 NEON 时,浮点数才可用。

布尔值

    布尔常数 TRUE 和 FALSE 必须书写为 {TRUE} 和 {FALSE}。

字符

    字符常数由左右单引号组成,中间括有单个字符或一个采用标准的 C 转义字符的转义字符。

字符串

    字符串由用双引号括起的多个字符和空格组成。 如果在一个字符串内使用了双引号或美元符号作为文本字符,则这些符号必须用一对相应的字符来表示。 例如,如果需要在字符串内使用单个 $,则必须书写为 $$。 在字符串常数内可以使用标准 C 转义序列。

2.3.2. ARM 汇编语言模块示例

Example 2.1 显示了汇编语言模块的一些核心成分。 此示例是用 ARM 汇编语言编写的。 在主示例目录 install_directory\RVDS\Examples 中以 armex.s 文件形式提供了该示例。 有关如何汇编、链接和执行该示例的说明,请参阅代码示例。
以下各节详细介绍了此示例的组成部分。
Example 2.1.

        AREA     ARMex, CODE, READONLY
                                ; Name this block of code ARMex
        ENTRY                   ; Mark first instruction to execute
start
        MOV      r0, #10        ; Set up parameters
        MOV      r1, #3
        ADD      r0, r0, r1     ; r0 = r0 + r1
stop
        MOV      r0, #0x18      ; angel_SWIreason_ReportException
        LDR      r1, =0x20026   ; ADP_Stopped_ApplicationExit
        SVC      #0x123456      ; ARM semihosting (formerly SWI)
        END                     ; Mark end of file

ELF 节和 AREA 指令

ELF 节 是独立的、已命名的、不可分割的代码或数据序列。 单个代码节是生成应用程序的最低要求。
汇编或编译的输出内容可包括:
    一个或多个代码节。 它们通常是只读节。
    一个或多个数据节。 它们通常是读写节。 它们可以是零初始化的 (ZI)。
链接器依照节位置规则,将每个节放在一个程序映像中。 在源文件中相邻的节在应用程序映像中不一定相邻。 有关链接器如何放置节的详细信息,请参阅《链接器用户指南》中的第 5 章 使用分散加载描述文件。
在源文件中,AREA 指令标记一节的开始。 该指令对节进行命名并设置其属性。 属性放在名称后面,之间用逗号分隔。 有关 AREA 指令语法的详细描述,请参阅AREA。
可以为节选择任何名称。 但是,以任何非字母字符开头的名称必须括在竖线内,否则会生成 AREA name missing 错误。 例如,|1_DataArea|。
Example 2.1 定义了一个名为 ARMex 的单个节,其中包含代码并被标记为 READONLY。

ENTRY 指令

ENTRY 指令标记要执行的第一个指令。 在包含 C 代码的应用程序中,在 C 库初始化代码中也包含一个入口点。 初始化代码和异常处理程序也包含入口点。
应用程序执行
Example 2.1 中的应用程序代码在标签 start 处开始执行,它在此处将十进制值 10 和 3 加载到寄存器 r0 和 r1 中。 这些寄存器将一起相加,并且结果将存放到 r0 中。
应用程序终止
在执行主代码后,应用程序会将控制权返回调试器,以此来终止执行。 此操作是通过将 ARM 半主机 SVC(缺省为 0x123456)与下列参数结合使用来完成的:
    r0 等于 angel_SWIreason_ReportException (0x18)
    r1 等于 ADP_Stopped_ApplicationExit (0x20026)
请参阅《RVCT 开发指南》中的第 8 章 半主机。

END 指令

此指令指示汇编器停止处理此源文件。 每个汇编语言源模块都必须以单占一行的 END 指令结束。

2.3.3. 调用子例程

若要调用子例程,应使用跳转和链接指令, 其语法是:
    BL  destination
其中,destination 通常是位于子例程的第一个指令处的标签。
destination 也可以是程序相对表达式。 有关详细信息,请参阅B、BL、BX、BLX 和 BXJ。

BL 指令:

    将返回地址存放到链接寄存器中
    将 pc 设置为子例程的地址
在执行子例程代码后,可以使用 BX lr 指令返回。 按照约定,寄存器 r0 到 r3 用于将参数传递给子例程,并且 r0 还用于将结果传递回调用方。

Note

单独汇编或编译的模块之间进行的调用必须符合过程调用标准规定的限制和约定。 有关详细信息,请参阅 install_directory\Documentation\Specifications\… 中的《ARM 体系结构的过程调用标准》规范 aapcs.pdf。
Example 2.2 显示了一个子例程,它将两个参数值相加并将结果返回 r0。 在主示例目录 install_directory\RVDS\Examples 中以 subrout.s 文件形式提供了该示例。 有关如何汇编、链接和执行该示例的说明,请参阅代码示例。
Example 2.2.

        AREA    subrout, CODE, READONLY     ; Name this block of code
        ENTRY                     ; Mark first instruction to execute
start   MOV     r0, #10           ; Set up parameters
        MOV     r1, #3
        BL      doadd             ; Call subroutine
stop    MOV     r0, #0x18         ; angel_SWIreason_ReportException
        LDR     r1, =0x20026      ; ADP_Stopped_ApplicationExit
        SVC     #0x123456         ; ARM semihosting (formerly SWI)
doadd   ADD     r0, r0, r1        ; Subroutine code
        BX      lr                ; Return from subroutine
        END                       ; Mark end of file

 

Leave a Reply

12 − 4 =

此站点使用Akismet来减少垃圾评论。了解我们如何处理您的评论数据