好记性不如铅笔头

ARM, 操作系统, 编程

《RealView编译工具汇编器指南》摘录:其他指令

CONTENTS

备注:

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

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

7.8. 其他指令

7.8.1. ALIGN

ALIGN 指令通过用零或 NOP 指令进行填充将当前位置对齐到指定边界。

语法

ALIGN {expr{,offset{,pad{,padsize}}}}
其中:
expr
    是一个数值表达式,取值为 20 到 231 范围内的 2 的任何次幂
offset
    可以是任何数值表达式
pad
    可以是任何数值表达式
padsize
    可为 1、2 或 4。

操作

使当前位置对齐到如下形式的下一地址:
offset + n * expr
如果未指定 expr,则 ALIGN 会将当前位置设置到下一个字(四字节)边界处。 前一个位置和当前新位置之间的未用空间用以下内容填充:
    如果指定了 pad,则用 pad 的副本填充
    满足以下所有条件时,用 NOP 指令填充:
        未指定 pad
        ARM 或 Thumb 指令后面是 ALIGN 指令
        在当前节中,AREA 指令设置了 CODEALIGN 属性
    其他情况用零填充。
根据 padsize 值的情况,pad 将被分别视为一个字节、半字或字。 如果未指定 padsize,则 pad 在数据节中缺省为字节,在 Thumb 代码中缺省为半字,在 ARM 代码中缺省为字。

用法

使用 ALIGN 可确保数据和代码对齐到适当的边界上。 在下列情况下,这通常是必须的:
    ADR Thumb 伪指令只能加载字对齐的地址,但 Thumb 代码内的标签可能不是字对齐的。 使用 ALIGN 4 可确保 Thumb 代码内的地址是四字节对齐的。
    使用 ALIGN 可利用有些 ARM 处理器上的高速缓存。 例如,ARM940T 带有一个含 16 字节行的高速缓存。 使用 ALIGN 16 可在 16 字节边界上对齐函数入口点,并使高速缓存的效率最高。
    LDRD 和 STRD 双字数据传送必须是八字节对齐的。 如果要用 LDRD 或 STRD 访问数据,则应在内存分配指令(如 DCQ)之前使用 ALIGN 8(请参阅数据定义指令)。
    只有标签的行可以是任意对齐的。 随后的 ARM 代码是字对齐的(Thumb 代码是半字对齐的)。 因此标签不能正确寻址代码。 在标签前使用 ALIGN 4(或对 Thumb 代码使用 ALIGN 2)。
对齐相对于例程所在的 ELF 节的起始位置。 节必须对齐到相同的或更近似的边界上。 AREA 指令中的 ALIGN 属性以不同方式指定(请参阅AREA 和示例)。

示例

        AREA    cacheable, CODE, ALIGN=3
rout1   ; code              ; aligned on 8-byte boundary
        ; code
        MOV     pc,lr       ; aligned only on 4-byte boundary
        ALIGN   8           ; now aligned on 8-byte boundary
rout2   ; code

        AREA    OffsetExample, CODE
        DCB     1           ; This example places the two
        ALIGN   4,3         ; bytes in the first and fourth
        DCB     1           ; bytes of the same word.

        AREA    Example, CODE, READONLY
start   LDR     r6,=label1
        ; code
        MOV     pc,lr
label1  DCB     1           ; pc now misaligned
        ALIGN               ; ensures that subroutine1 addresses
subroutine1                 ; the following instruction.
        MOV r5,#0x5

7.8.2. AREA

AREA 指令指示汇编器汇编新的代码节或数据节。 节是不可分的已命名独立代码或数据块,由链接器处理。 有关详细信息,请参阅ELF 节和 AREA 指令。

语法

AREA sectionname{,attr}{,attr}…
其中:
sectionname
    是为节指定的名称。
    可以为节选择任何名称。 但是,以非字母字符开头的名称必须包含在竖杠内,否则会生成缺失节名错误。 例如,|1_DataArea|。
    有些名称是习惯性的名称。 例如,|.text| 用于表示由 C 编译器生成的代码节,或以某种方式与 C 库关联的代码节。
attr
    是一个或多个用逗号分隔的节属性。 有效的属性有:
    ALIGN=expression
        缺省情况下,ELF 节在四字节边界上对齐。expression 可以取 0 到 31 之间的任何整数值。节在 2expression 字节边界上对齐。 例如,如果 expression 是 10,则节在 1KB 边界上对齐。
        这与 ALIGN 指令所指定的方式不同。 请参阅ALIGN。
       Note
        不要对 ARM 代码节使用 ALIGN=0 或 ALIGN=1。
        不要对 Thumb 代码节使用 ALIGN=0。
    ASSOC=section
        section 指定一个关联的 ELF 节。sectionname 必须包含在含有 section 的任何链接中
    CODE
        包含机器指令。READONLY 是缺省值。
    CODEALIGN
        当在节内的 ARM 或 Thumb 指令后使用 ALIGN 指令时,该属性导致汇编器插入 NOP 指令,除非 ALIGN 指令指定了其他填充方式。
    COMDEF
        是一个公共节定义。 此 ELF 节可以包含代码或数据。 它必须等同于其他源文件中拥有相同名称的任何其他节。
        名称相同的同一 ELF 节在内存的同一节中被链接器覆盖。 如果有任何不同,则链接器会生成一个警告,并且不覆盖这些节。 请参阅《链接器用户指南》中第 3 章 使用基本链接器功能。
    COMGROUP=symbol_name
        是一个公共组节。 公共组中的所有节都是公共的。 当对象被链接后,其他对象文件可能具有带有 symbol_name 签名的一个 GROUP。 最终映像中只包含一个组。
    COMMON
        是一个公共数据节。 不能在其中定义任何代码或数据。 它由链接器初始化为零。 名称相同的所有公共节在内存的同一节中被链接器覆盖。 它们并不都必须具有相同大小。 链接器按每个名称的最大公共节的需要分配空间。
    DATA
        包含数据,不包含指令。READWRITE 是缺省值。
    FINI_ARRAY
        将当前区域的 ELF 类型设置为 SHT_FINI_ARRAY。
    GROUP=symbol_name
        是组的签名,它必须由源文件或源文件中包含的文件定义。 具有相同 symbol_name 签名的所有 AREAS 都被置于同一组中。 组内的各节同时保存或显现。
    INIT_ARRAY
        将当前区域的 ELF 类型设置为 SHT_INIT_ARRAY。
    LINKORDER=section
        指定映像中当前节的相对位置。 这可确保具有 LINKORDER 属性的所有节彼此之间的顺序与映像中相应的已命名 sections 的顺序相同。
    MERGE=n
        指示链接器可以将当前节与具有 MERGE=n 属性的其他节合并。n 为节中元素的大小,例如 n 为 1 表示字符。 绝不能认定将会合并此节,因为该属性不会强制链接器合并节。
    NOALLOC
        指示在目标系统上不为此区域分配内存。
    NOINIT
        指示数据节未初始化,或初始化为零。 它只包含空间保留指令 SPACE 或初始化值为零的 DCB、DCD、DCDU、DCQ、DCQU、DCW 或 DCWU。 您可以在链接时决定某区域是未初始化还是初始化为零。 请参阅《链接器用户指南》中第 3 章 使用基本链接器功能。
    PREINIT_ARRAY
        将当前区域的 ELF 类型设置为 SHT_PREINIT_ARRAY。
    READONLY
        指示不应向此节写入。 这是代码区域的缺省值。
    READWRITE
        指示可以读写此节。 这是数据区域的缺省值。
    SECFLAGS=n
        将一个或多个(由 n 指定)ELF 标记添加到当前节。
    SECTYPE=n
        将当前节的 ELF 类型设置为 n。
    STRINGS
        将 SHF_STRINGS 标记添加到当前节。 要使用 STRINGS 属性,必须同时使用 MERGE=1 属性。 节的内容必须是使用 DCB 指令空终止的字符串。

用法

使用 AREA 指令可将源文件细分为 ELF 节。 可以在多个 AREA 指令中使用相同的名称。 名称相同的所有区域都放在相同的 ELF 节中。 只有特定名称的第一个 AREA 指令的属性才会被应用。
通常应对代码和数据使用不同的 ELF 节。 大型程序通常可方便地划分为多个代码节。 大量独立的数据集通常也最好放在不同的节中。
局部标签的范围是由 AREA 指令定义的,并可选择用 ROUT 指令进行细分(请参阅局部标签和ROUT)。
一组汇编代码必须至少有一个 AREA 指令。

示例

下列示例定义名为 Example 的只读代码节。

    AREA    Example,CODE,READONLY   ; An example code section.
            ; code

7.8.3. ATTR

ATTR 设置指令可设置 ABI 生成属性的值。
ATTR 范围指令可指定应用设置值的范围。

语法

ATTR FILESCOPE
ATTR SCOPE name
ATTR settype, tagid, value
其中:
name
    为节名或符号名。
settype
    可以是下列项之一:
        SETVALUE
        SETSTRING
        SETCOMPATIBLEWITHVALUE
        SETCOMPATIBLEWITHSTRING
tagid
    是在 ARM 体系结构的 ABI 中定义的属性标记名(或其数值)。
value
    取决于 settype:
        当 settype 为 SETVALUE 或 SETCOMPATIBLEWITHVALUE 时为 32 位整数值
        当 settype 为 SETSTRING 或 SETCOMPATIBLEWITHSTRING 时为空终止的字符串

用法

ATTR FILESCOPE 指令后的 ATTR 设置指令应用于整个对象文件。 ATTR SCOPE name 指令后的 ATTR 设置指令仅应用于已命名的节或符号。
对于需要整数的标记,必须使用 SETVALUE 或 SETCOMPATIBLEWITHVALUE。 对于需要字符串的标记,必须使用 SETSTRING 或 SETCOMPATIBLEWITHSTRING。 有关标记名称列表,请参阅《ARM 体系结构的 ABI 附录和勘误表》。
使用 SETCOMPATIBLEWITHVALUE 和 SETCOMPATIBLEWITHSTRING 可设置对象文件也可兼容的标记值。

示例

        ATTR  SETSTRING Tag_CPU_raw_name, "Cortex-A8"
        ATTR  SETVALUE  Tag_VFP_arch, 3   ; VFPv3 instructions were permitted.
        ATTR  SETVALUE  10, 3             ; 10 is the numerical value of
                                          ; Tag_VFP_arch.

7.8.4. END

END 指令通知汇编器它已到达源文件的末尾。

语法

END

用法

每个汇编语言源文件都必须以单独一行 END 结束。
如果源文件已被 GET 指令包含在父文件中,则汇编器会返回到父文件,并在 GET 指令后的第一行继续汇编。 有关详细信息,请参阅GET 或 INCLUDE。
如果在第一轮汇编时到达顶层源文件的 END 指令而没有出现任何错误,则开始第二轮汇编。
如果在第二轮汇编时到达顶层源文件的 END 指令,则汇编器完成汇编,并写入适当的输出。

7.8.5. ENTRY

ENTRY 指令声明程序的入口点。

语法

ENTRY

用法

必须为一个程序指定至少一个 ENTRY 点。 如果不存在 ENTRY,则链接时会产生一个警告。
在一个源文件内不能使用多个 ENTRY 指令。 并非每个源文件都必须包含 ENTRY 指令。 如果在一个源文件内有多个 ENTRY 指令,则汇编时会产生错误消息。

示例

        AREA    ARMex, CODE, READONLY
        ENTRY                 ; Entry point for the application

7.8.6. EQU

EQU 指令为数值常数、寄存器相对的值或程序相对的值指定一个符号名称。 * 是 EQU 的同义词。

语法

name EQU expr{, type}
其中:
name
    是要为值指定的符号名称。
expr
    是一个寄存器相对的地址、程序相对的地址、绝对地址或 32 位整型常数。
type
    是可选的。type 可为下列值之一:
        ARM
        THUMB
        CODE32
        CODE16
        DATA
    仅当 expr 是一个绝对地址时,才能使用 type。 如果导出了 name,则会根据 type 的值,将对象文件的符号表中的 name 条目标记为 ARM、THUMB、CODE32、CODE16 或 DATA。 这些信息可由链接器使用。

用法

使用 EQU 可定义常数。 这类似于在 C 中使用 #define 定义常数。
有关导出符号的信息,请参阅KEEP 和EXPORT 或 GLOBAL。

示例

abc EQU 2               ; assigns the value 2 to the symbol abc.
xyz EQU label+8         ; assigns the address (label+8) to the
                        ; symbol xyz.
fiq EQU 0x1C, CODE32    ; assigns the absolute address 0x1C to
                        ; the symbol fiq, and marks it as code

7.8.7. EXPORT 或 GLOBAL

EXPORT 指令声明一个符号,链接器可以使用该符号解析不同对象和库文件中的符号引用。 GLOBAL 是 EXPORT 的同义词。

语法

EXPORT {[WEAK]}
EXPORT symbol {[type]}
EXPORT symbol [attr{,type}]
EXPORT symbol [WEAK{,attr}{,type}]
其中:
symbol
    是要导出的符号名称。 符号名区分大小写。 如果省略了 symbol,则导出所有符号。
WEAK
    仅当没有其他源导出另一个 symbol 时,才应将此 symbol 导入其他源中。 如果使用了不带 symbol 的 [WEAK],则所有导出的符号都是处于次要地位的。
attr
    可以是下列项之一:
    DYNAMIC
        将 ELF 符号可见性设置为 STV_DEFAULT。
    PROTECTED
        将 ELF 符号可见性设置为 STV_PROTECTED。
    HIDDEN
        将 ELF 符号可见性设置为 STV_HIDDEN。
    INTERNAL
        将 ELF 符号可见性设置为 STV_INTERNAL。
type
    指定符号类型。
    DATA
        对源进行汇编和链接时,symbol 将被视为数据。
    CODE
        对源进行汇编和链接时,symbol 将被视为代码。
    ELFTYPE=n
        symbol 将被视为由 n 值指定的特定 ELF 符号,其中 n 可以是 0 到 15 之间的任何数字。
    如果未指定,则由汇编器确定最适合的类型。

用法

使用 EXPORT 可使其他文件中的代码能够访问当前文件中的符号。
使用 [WEAK] 属性可通知链接器,如果可以使用其他源中的不同 symbol 实例,则不同实例将优先于此实例。 [WEAK] 属性可与任何符号可见性属性一起使用。
另请参阅IMPORT 和 EXTERN。
有关符号可见性的详细信息,请参阅 www.infocenter.arm.com 上的《ARM 体系结构的 ELF》ABI 文档。

示例

        AREA    Example,CODE,READONLY
        EXPORT  DoAdd           ; Export the function name
                                ; to be used by external
                                ; modules.
DoAdd   ADD     r0,r0,r1

重复导出可覆盖符号可见性。 在以下示例中,最后一个 EXPORT 在绑定和可见性上优先:
        EXPORT  SymA[WEAK]      ; Export as weak-hidden
        EXPORT  SymA[DYNAMIC]   ; SymA becomes non-weak dynamic.

7.8.8. EXPORTAS

EXPORTAS 指令允许将符号导出到对象文件中,该符号对应于源文件中的不同符号。

语法

EXPORTAS symbol1, symbol2
其中:
symbol1
    是源文件中的符号名称。symbol1 必须已定义。 它可以是任何符号,包括区域名、标签或常数。
symbol2
    是希望在对象文件中出现的符号名称。
符号名区分大小写。

用法

使用 EXPORTAS 可更改对象文件中的符号,而不必更改源文件中的每个实例。
另请参阅EXPORT 或 GLOBAL。

示例

    AREA data1, DATA       ; starts a new area data1
    AREA data2, DATA       ; starts a new area data2
    EXPORTAS data2, data1  ; the section symbol referred to as data2 will
                           ; appear in the object file string table as data1.
one EQU  2
    EXPORTAS one, two
    EXPORT one             ; the symbol 'two' will appear in the object
                           ; file's symbol table with the value 2.

7.8.9. GET 或 INCLUDE

GET 指令在被汇编的文件内包含一个文件。 所包含的文件在 GET 指令的位置进行汇编。 INCLUDE 是 GET 的同义词。

语法

GET filename
其中:
filename
    是要在汇编中包含的文件的名称。 汇编器接受 UNIX 或 MS-DOS 格式的路径名。

用法

GET 对在汇编代码中包含宏定义、EQU 指令和存储器映射很有用。 当完成所包含文件的汇编后,在 GET 指令后的下一行继续汇编。
缺省情况下,汇编器在当前位置搜索所包含的文件。 当前位置即调用文件所在的目录。 使用 -i 汇编器命令行选项可向搜索路径添加目录。 包含空格的文件名和目录名不能括在双引号 ( ” ” ) 内。
所包含的文件可包含其他 GET 指令以包含其他文件(请参阅嵌套指令)。
如果所包含的文件位于与当前位置不同的目录中,则该目录就成为当前位置,直到所包含的文件结束。 原先的当前位置随后恢复。
GET 不能用于包含对象文件(请参阅INCBIN)。

示例

    AREA    Example, CODE, READONLY
    GET     file1.s               ; includes file1 if it exists
                                  ; in the current place.
    GET     c:\project\file2.s    ; includes file2
    GET     c:\Program files\file3.s  ; space is permitted

 

7.8.10. IMPORT 和 EXTERN

这些指令为汇编器提供一个未在当前汇编中定义的名称。

语法

directive symbol {[type]}
directive symbol [attr{,type}]
directive symbol [WEAK{,attr}{,type}]
其中:
directive
    可为以下指令之一:
    IMPORT
        无条件导入符号。
    EXTERN
        仅导入在当前汇编中引用的符号。
symbol
    是在单独汇编的源文件、对象文件或库中定义的一个符号名称。 符号名区分大小写。
WEAK
    防止链接器在符号未在其他地方定义时产生错误消息。 同时防止链接器搜索还未包含的库。
attr
    可以是下列项之一:
    DYNAMIC
        将 ELF 符号可见性设置为 STV_DEFAULT。
    PROTECTED
        将 ELF 符号可见性设置为 STV_PROTECTED。
    HIDDEN
        将 ELF 符号可见性设置为 STV_HIDDEN。
    INTERNAL
        将 ELF 符号可见性设置为 STV_INTERNAL。
type
    指定符号类型。
    DATA
        对源进行汇编和链接时,symbol 将被视为数据。
    CODE
        对源进行汇编和链接时,symbol 将被视为代码。
    ELFTYPE=n
        symbol 将被视为由 n 值指定的特定 ELF 符号,其中 n 可以是 0 到 15 之间的任何数字。
    如果未指定,则由链接器确定最适合的类型。

用法

在链接时,名称被解析为在其他对象文件中定义的符号。 该符号被当作程序地址。 如果未指定 [WEAK] 且在链接时没有找到相应的符号,则链接器会产生错误。
如果指定了 [WEAK] 且在链接时没有找到相应的符号:
    如果该引用是 B 或 BL 指令的目标,则将下一指令的地址作为该符号的值。 这样做的效果是将 B 或 BL 指令变成了 NOP。
    否则,该符号的值取将为零。
有关符号可见性的详细信息,请参阅 www.infocenter.arm.com 上的《ARM 体系结构的 ELF》ABI 文档。

示例

    AREA    Example, CODE, READONLY
    EXTERN  __CPP_INITIALIZE[WEAK]  ; If C++ library linked, gets the address of
                                    ; __CPP_INITIALIZE function.
    LDR     r0,=__CPP_INITIALIZE    ; If not linked, address is zeroed.
    CMP     r0,#0                   ; Test if zero.
    BEQ     nocplusplus             ; Branch on the result.

此示例测试是否已链接 C++ 库,并根据结果执行条件跳转。

7.8.15. REQUIRE8 和 PRESERVE8

REQUIRE8 指令指定当前文件要求堆栈八字节对齐。 它设置 REQ8 生成属性以通知链接器。
PRESERVE8 指令指定当前文件保持堆栈八字节对齐。 它设置 PRES8 编译属性以通知链接器。
链接器检查要求堆栈八字节对齐的任何代码是否仅由保持堆栈八字节对齐的代码直接或间接地调用。

语法

REQUIRE8 {bool}
PRESERVE8 {bool}
其中:
bool
    是一个可选布尔常数,取值为 {TRUE} 或 {FALSE}。

用法

如果您的代码保持堆栈八字节对齐,在需要时,可使用 PRESERVE8 设置文件的 PRES8 编译属性。 如果您的代码不保持堆栈八字节对齐,则可使用 PRESERVE8 {FALSE} 确保不设置 PRES8 编译属性。
Note
如果您省略 PRESERVE8 和 PRESERVE8 {FALSE},汇编器会检查修改 sp 的指令,以决定是否设置 PRES8 编译属性。 ARM 建议明确指定 PRESERVE8。
您可以通过以下方式启用警告:
armasm –diag_warning 1546
有关详细信息,请参阅命令语法。
您将会收到类似以下警告:
“test.s”, line 37: Warning: A1546W: Stack pointer update potentially
                                breaks 8 byte stack alignment
       37 00000044         STMFD    sp!,{r2,r3,lr}

示例

REQUIRE8
REQUIRE8     {TRUE}      ; equivalent to REQUIRE8
REQUIRE8     {FALSE}     ; equivalent to absence of REQUIRE8
PRESERVE8    {TRUE}      ; equivalent to PRESERVE8
PRESERVE8    {FALSE}     ; NOT exactly equivalent to absence of PRESERVE8

发表评论

12 − 10 =

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