|
ARM伪指令 整理时间:2008/01/25 整理人:张绍言 功能:为完成汇编程序作各种准备工作,仅在汇编过程中起作用. 1.符号定义伪指令(Symbol Definition) 用于定义ARM汇编程序中的变量,对变量赋值以及定义寄存器的别名等操作. (1)定义全局变量:GBLA,GBLL,GBLS (Global Arithmetic)GBLA用于定义全局的数字变量并初始化为0 (Global Logic)GBLL用于定义全局的逻辑变量并初始化为F(假) (Global String)GBLS用于定义全局的字符变量并初始化为空 例: GBLA Test1 //定义全局数字变量 Test1 SETA 0xaa //赋值 GBLL Test2 //定义全局逻辑变量 Test2 SETL {TRUE} //赋为真 GBLS Test3 //定义全局字符串变量 Test3 SETS "Testing" //赋字符串值 (2)定义局部变量:LCLA,LCLL,LCLS (Local Arithmetic)LCLA定义一个局部的数字变量并初始化为0 (Local Logic)LCLL定义一个局部的逻辑变量并初始化F(假) (Local String)LCLS定义一个局部的字符串变量并初始化为空 例: LCLA Test1 //定义一个局部数字变量 Test1 SETA 0xaa //赋值 LCLL Test2 //定义一个局部逻辑变量 Test2 SETL {TRUE} //赋为真 LCLS Test3 //定义一个局部的字符串变量 Test3 SETS "Testing" //赋值 (3)对变量赋值:SETA,SETL,SETS (Set Arithmetic)SETA给一个数字变量赋值 (Set Logic)SETL给一个逻辑变量赋值 (Set String)SETS给一个字符串赋值 (4)RLIST定义通用寄存器列表 名称 RLIST {寄存器列表} 说明:使用该指令定义的名称可在LDM/STM中使用,并且列表中寄存器访问次序与排列次序无关,而是根据寄存器编号由低到高的顺序访问. 例: DataRegister RLIST {R0-R5,R8,R10} 将寄存器列表名称定义为DataRegister可在LDM/STM指定中通过该指令访问寄存器列表. 2.数据定义伪指令(Data Definition) 数据定义伪指令用于为特定的数据分配存储单元同时完成对已分配存储单元的初始化. (1)DCB (Byte)分配一片连续的字节存储单元并用指定的数据初始化. 标号 DCB 表达式 标号 = 表达式 表达式可以为0~255的数字或字符串 例: Str DCB "This is a test!" //分配一片连续的字节存储单元并初始化 (2)DCW/DCWU (Word)分配一片连续的半字存储单元并用指定的数据初始化. 标号 DCW 表达式 标号 DCWU 表达式 表达式可以为程序标号或数字表达式 用DCW分配的字存储单元是半字对齐的 用DCWU分配的字存储单元并不严格半字对齐 例: DataTest DCW 1,2,3 //分配一片连续的半字存储单元并初始化 (3)DCD/DCDU 分配一片连续的字存储单元并用指定的数据初始化. 标号 DCD 表达式 标号 DCDU 表达式 表达式可以为程序标号或数字表达式,DCD也可用&代替 用DCD分配的字存储单元是字对齐的 用DCDU分配的字存储单元并不严格字对齐 例: DataTest DCD 4,5,6 //分配一片连续的字存储单元并初始化 (4)DCFD/DCFDU (Double)分配一片连续的双精度浮点数存储单元并用指定的数据初始化. 标号 DCFD 表达式 标号 DCFDU 表达式 每个双精度的浮点数占据两个字单元 用DCFD分配的字存储单元是字对齐的 用DCFDU分配的字存储单元并不严格字对齐 例: FDataTest DCFD 2E115,-5E7 //分配一片连续的字存储单元并初始化为指定的双精度数 (5)DCFS/DCFSU 分配一片连续的单精度浮点数存储单元并用指定的数据初始化. 标号 DCFS 表达式 标号 DCFSU 表达式 每个单精度的浮点数占据一个字单元 用DCFS分配的字存储单元是字对齐的 用DCFSU分配的字存储单元并不严格字对齐 例: FDataTest DCFS 2E5,-5E-7 //分配一片连续的字存储单元并初始化为指定的单精度数 (6)DCQ/DCQU 分配一片以8字节为单位的连续的存储单元并且指定的数据初始化. 标号 DCQ 表达式 标号 DCQU 表达式 用DCQ分配的存储单元是字对齐的 用DCQU分配的存储单元并不严格字对齐 例: DataTest DCQ 100 //分配一片连续的存储单元并初始化为指定的值 (7)SPACE 分配一片连续的存储单元并初始化为0. 标号 SPACE 表达式 标号 % 表达式 表达式为要分配的字节数 例: DataSpace SPACE 100 //分配连续100字节的存储单元并初始化为0 (8)MAP 定义一个结构化的内存表首地址 ^/MAP 表达式 {,基址寄存器} 表达式可以为程序中的标号或数学表达式,基址寄存器为可选项 当基址寄存器选项不存在时,表达式的值即为内存表的首地址 当该选项存在时,内存表的首地址为表达式的值与基址寄存器的和 MAP 伪指定通常与FIELD伪指令配合使用来定义 例: MAP 0x100,R0 //定义结构化内存表首地址的值勤0x100+R0 (9)FIELD 定义一个结构化的内存表的数据域 标号 FIELD/# 表达式 表达式的值为当前数据域在内存表中所占的字节数 MAP伪指令定义内存表的首地址 FIELD伪指令定义内存表中的各个数据域,并可以为每个数据域指定一个标号供其他指令引用 例: MAP 0x100 //定义结构化内存表首地址的值为0x100 A FIELD 16 //定义A的长度为16字节位置为0x100 B FIELD 32 //定义B的长度为32字节位置为0x110 S FIELD 256 //定义S的长度为256字节位置为0x130 3.汇编控制伪指令 汇编控制伪指令用于控制汇编程序的执行流程 (1)if,else,endif if 逻辑表达式 指令序列1 else 指令序列2 endif 例: GBLL Test //声明一个全局的逻辑变量 IF Test=TRUE 指令1 ELSE 指令2 ENDIF (2)while,wend while 逻辑表达式 指令序列 wend 例: GBLA Counter //声明一个全局的数字变量 Counter SETA 3 WHILE Counter<10 指令序列 Counter SETA Counter+1 WEND (3)宏定义macro,mend,mexit $ 标号 宏名 $ 参数1,$ 参数2,... 指令序列 MEND MEXIT用于从宏定义体中跳转出去 4.其他常用汇编伪指令 (1)AREA用于定义一个代码段或数据段 AREA 段名 属性1,属性2,... 如果段名以数字开头则要用|括起来如|1_test|. 属性字段表示该段的相关属性,用逗号分隔 CODE:用于定义代码段,默认为READONLY DATA:用于定义数据段,默认为READWRITE READONLY:指定本段为只读,代码段默认为READONLY READWRITE:指定本段为可读可写,数据段默认为READWRITE ALIGN:格式 ALIGN 表达式 默认ELF(可执行连接文件)的代码段和数据段是按字对齐的,表达式取值范围为0~31,相应的对齐方式为2表达式次方 COMMON:定义一个通用段,不包含任何的用户代码和数据,各源文件中同名的COMMON段共享同一段存储单元 注:一个汇编程序至少要包含一个段,当程序太长时,也可以分为多个代码段和数据段. 例: AREA Init,CODE,READONLY //定义一个代码段段名为Init属性为只读 (2)ALIGN指定对齐方式 ALIGN {表达式{,偏移量}} 通过添加填充字节的方式,使当前位置满足一定的对齐方式 表达式值用于指定对齐方式,可能的取值为2的幂如1,2,4,8,16等 若未指定表达式则将当前位置对齐到下一个字的位置 偏移量指定当前位置的对齐方式为:2的表达式次幂+偏移量 例: AREA Init,CODE,READONLY,ALIGN=3 //指定后面的指令为8字节对齐(2的3次方) (3) CODE16 通知编译器,其后的指令序列为16位的Thumb指令 CODE32 通知编译器,其后的指令序列为32位的ARM指令 注:在混合使用ARM指令和Thumb指令编程时,可用这两条指令进行切换,但注意它们只通知编译器其后指令的类型,并不能对处理器进行状态切换 例: AREA Init,CODE,READONLY CODE32 LDR R0,=NEXT+1 BX R0 ... CODE16 NEXT LDR R3,=0x3FF ... END (4)ENTRY ENTRY 用于指定汇编程序的入口点 在一个源文件中最多只能有一个ENTRY指令 例: AREA Init,CODE,READONLY ENTRY //指定应用程序的入口点 ... END (5)END END 用于通知编译器已经到了源程序的结尾 (6)EQU (equal) 名称 EQU 表达式{,类型} 用于为程序中的常量,标号等定义一个等效的字符名称,类似于C语言中的#define. 当表达式为32位的常量时可以指定表达式的数据类型CODE16,CODE32,DATA 例: Test EQU 50 //定义标号Test的值为50 Addr EQU 0x55 //定义Addr值为0x55且该处为32位的ARM指令 (7)EXPORT/GLOBAL EXPORT 标号 {[WEAK]} 用于在程序中声明一个全局的标号可以在其他文件中引用 [WEAK]声明其他的同名标号优先于该标号被引用 例: AREA Init,CODE,READONLY EXPORT Stest //声明一个可全局引用的标号 ... END (8)IMPORT IMPORT 标号 {[WEAK]} 通知编译器要使用的标号在其他的源文件中定义 但要在当前源文件中引用而且无论当前源文件是否引用该标号该标号均会被加入到当前源文件中符号表中. [WEAK]表达当所有的源文件都没有定义这样一个标号时编译器也不给出错误信息 (9)EXTERN EXTER 标号 {[WEAK]} 通知编译器要使用的标号在其他的源文件中定义 但要在当前源文件中引用,如果当前源文件实际并未引用该标号该标号就不会被加入到当前源文件的符号表中 [WEAK]表达当所有的源文件中都没有定义这样一个标号时,编译器也不给出错误信息 (10)GET/INCLUDE GET 文件名 用于将一个源文件包含到当前的源文件中 GET指令只能用于包含源文件,包含目标文件需要使用INCBIN伪指令 例: AREA Init,CODE,READONLY GET a1.s //包含源文件a1.s GET C:\a2.s //包含源文件C:\a2.s END (11)INCBIN(Include Binary) INCBIN 文件名 用于将一个目标文件或数据文件包含到当前源文件中 例: AREA Init,CODE,READONLY INCBIN a1.dat INCBIN C:\a2.txt END (12)RN(Rename) 名称 RN 表达式 用于给一个寄存器定义别名,这样可以方便程序员记忆该寄存器的功能 例: Temp RN R0 (13)ROUT {名称} ROUT 用于给一个局部变量定义作用范围 在程序中未使用该伪指令时局部变量的作用范围为所在的AREA,而使用ROUT后,局部变量的作为范围为当前ROUT和下一个ROUT之间.
|