目录
参考书籍:《ARM体系结构与编程(第2版)》
ARM指令分类及其寻址
ARM指令集介绍
ARM汇编语言程序设计
伪操作
ARM
汇编语言源程序中,语句由指令、伪操作和宏指令组成,主要分为:符号定义、数据定义、汇编控制、数据帧描述、信息报告和其他伪操作
符号定义
符号定义伪操作用于定义ARM
汇编程序中的变量,对变量进行赋值以及寄存器名称
GBLA、GBLL及GBLS
:声明全局变量LCLA、LCLL及LCLS
:声明局部变量SETA、SETL及SETS
:给变量赋值RLIST
:为通用寄存器列表定义名称CN
:为协处理器的寄存器定义名称CP
:为协处理器定义名称DN 及SN
:为VFP的寄存器定义名称FN
:为FPA的浮点寄存器定义名称
GBLA、GBLL及GBLS
GBLA
:声明一个全局的算术变量,并将其初始化成0
。GBLL
:声明一个全局的逻辑变量,并将其初始化成{FALSE}
。GBLS
:声明一个全局的串变量,并将其初始化成空串""
。
语法格式:<gblx> variable
GBLA objectsize ; 声明一个全局的算术变量
GBLL statusB ; 声明一个全局的逻辑变量statusB,默认为{
Flase}
statusB SETL {
TRUE} ; 设置为TRUE
LCLA、LCLL及LCLS
LCLA
:占明一个局部的算术变量,并将其初始化成0
。LCLL
:声明一个局部的逻辑变量,并将其初始化成{FALSE}
。LCLS
:声明一个局部的串变量,并将其初始化成空串""
。
语法格式:<lclx> variable
# 同全局变量
SETA、SETL及SETS
:
SETA
:给一个算术变量赋值。SETL
:给一个逻辑变量赋值。SETS
:给一个串变量赋值。
语法格式:<setx> variable expr
LCLA tmp
tmp SETA 2 ; 给tmp变量赋值为2
RLIST
:为一个通用寄存器列表定义名称。
语法格式:name RLIST {list-of-registers}
在LDM/STM 指令中,寄存器列表中的寄存器的访问次序总是先访问编号较低的寄存器,再访问编号较高的寄存器,而不管寄存器列表中各寄存器的排列顺序。
context RLIST {
r0-r6,r8,r10-r12,r15}
CN
:为一个协处理器的寄存器定义名称。
语法格式:name CN expr
expr
为协处理器的编号,数值范围0-15
power CN 6
CP
:为一个协处理器定义名称。
# 同上
DN 及SN
DN
:为一个双精度的VFP寄存器定义名称。SN
:为一个单精度的VFP寄存器定义名称。
语法格式:name DN/SN expr
expr为VFP双精度寄存器编号(0-15)或者VFP单精度寄存器编号(0-31)
FN
:为一个FPA浮点寄存器定义名称。
语法格式:name FN expr
expr为浮点寄存器的编号,数值范围为0-7。
数据定义
数据定义(Data Definition)伪操作包括以下具体的伪操作。
LTORG
:声明一个数据缓冲池(Literal Pool)的开始。MAP
:定义一个结构化的内存表(Storage Map)的首地址。FIELD
:定义结构化的内存表中的一个数据域(Field)。SPACE
:分配一块内存单元,并用0初始化。DCB
:分配一段字节的内存单元,并用指定的数据初始化。DCD及 DCDU
:分配一段字的内存单元,并用指定的数据初始化。DCDO
:分配一段字的内存单元,并将各单元的内容初始化成该单元相对于静态基值寄存器的偏移量。DCFD 及 DCFDU
:分配一段双字的内存单元,并用双精度的浮点数据初始化。DCFS 及 DCFSU
:分配一段字的内存单元,并用单精度的浮点数据初始化。DCI
:分配一段字节的内存单元,用指定的数据初始化,指定内存单元中存放的是代码,而不是数据。DCQ 及 DCQU
:分配一段双字的内存单元,并用64位的整数数据初始化。DCW 及 DCWU
:分配一段半字的内存单元,并用指定的数据初始化。DATA
:在代码段中使用数据。现已不再使用,仅用于保持向前兼容。
LTORG
:声明一个数据缓冲池(Literal Pool)的开始。
语法格式:LTORG
通常,ARM 汇编编译器把数据缓冲池放在代码段的最后面,即下一个代码段开始之前,或者END伪操作之前。
...
LTORG
data SPACE 4200 ;从当前位置开始分配4200字节的内存单元
END
MAP
:定义一个结构化的内存表(Storage Map)的首地址
语法格式:MAP expr {,base-register}
FIELD
:定义结构化的内存表中的一个数据域(Field)。
语法格式:{lable} FIELD expr
SPACE
:分配一块内存单元,并用0初始化
语法格式:{label} SPACE expr
data SPACE 500 ;分配500字节的内存单元,并将内存单元内容初始化成0
汇编控制伪操作
汇编控制(Assembly Control)伪操作包括下面的伪操作:
IF、ELSE 及ENDIF
WHILE 及 WEND
MACRO及MEND
MEXIT
IF、ELSE 及ENDIF
:根据条件把一段源代码包括在汇编语言程序内或者将其排除在程序之外
IF Version = "1.0"
; 指令
ENDIF
WHILE 及 WEND
:根据条件重复汇编相同的或者几乎相同的一段源代码
count SETA 1
WHILE count <= 4
count SETA count+1
;code
WEND
MACRO及MEND
:用MACRO及MEND定义的一段代码,称为宏定义体,这样,在程序中就可以通过宏指令多次调用该代码段了。
语法格式
MACRO
{
$label} macroname {
$parameter{
,$parameter}...}
;code
...
;code
MEND
MACRO
$label xmac $p1, $p2 ; 宏的名称为xmac,有两个参数$p1、$p2
MEND
;调用宏
abc xmac subr1, de
MEXIT
:用于从宏中跳转出去。
数据帧描述
主要用于调试
信息报告
信息报告(Reporting)伪操作包括下列具体的伪操作:
ASSERT
INFO
OPT
TTL及SUBT
ASSERT
:在汇编编译器对汇编程序的第二遍扫描中,如果其中的条件不成立,ASSERT伪操作将报告该错误信息。
INFO
:INFO伪操作支持在汇编处理过程的第一遍扫描或者第二遍扫描时报告诊断信息。
OPT
:通过OPT伪操作,可以在源程序中设置列表选项。
TTL及SUBT
:
- TTL伪操作在列表文件的每一页的开头插入一个标题。该TTL伪操作将作用在其后的每一页,直到遇到新的TTL伪操作。
- SUBT伪操作在列表文件的每一页的开头插入一个子标题。该SUBT伪操作将作用在其后的每一页,直到遇到新的SUBT伪操作。
其他的伪操作
CODE16和CODE32
:
- CODE16伪操作告诉汇编编译器后面的指令序列为16位的Thumb指令。
- CODE32伪操作告诉汇编编译器后面的指令序列为32位的ARM 指令。
CODE16
CODE32
EQU
:EQU伪操作为数字常量、基于寄存器的值和程序中的标号(基于PC 的值)定义一个字符名称。
ancd EQU 2 ; 定义abcd符号的值为2
ancd EQU 0x1c, CODE32 ;定义addrl符号的值为绝对地址0x1c,而且该处为ARM指令
AREA
:定义一个代码段或者数据段。
语法格式
AREA sectionname{
,attr}{
,attr}...
AREA mycode, CODE, READONLY
ENTRY
:指定程序的入口点。
ENTRY
END
:告诉编译器已经到了源程序结尾。
AREA mycode, CODE, READONLY
;code
END
ALIGN
:通过添加补丁字节使当前位置满足一定的对齐方式。
EXPORT和GLOBAL
EXPRORT
声明一个符号可以被其他文件引用。相当于声明了一个全局变量。GLOBAL
是EXPORT
的同义词。
语法格式
EXPORT symbol
IMPORT
:IMPORT
伪操作告诉编译器当前的符号不是在本源文件中定义的,而是在其他源文件中定义的,在本源文件中可能引用该符号,而且不论本源文件是否实际引用该符号,该符号都将被加入到本源文件的符号表中。
语法格式
IMPORT symbol
EXTERN
:EXTERN
伪操作告诉编译器当前的符号不是在本源文件中定义的,而是在其他源文件中定义的,在本源文件中可能引用该符号。如果本源文件没有实际引用该符号,该符号将不会被加入到本源文件的符号表中。
语法格式
EXTERN symbol
GET和INCLUDE
:GET
伪操作将一个源文件包含到当前源文件中,并将被包含的文件在其当前位置进行汇编处理。INCLUDE
是 GET
的同义词。
语法格式
GET filename
GET c:\file.s
INCBIN
:INCBIN
伪操作将一个文件包含到(INCLUDE
)当前源文件中,被包含的文件不进行汇编处理。
语法格式
INCBIN filename
INCBIN data.txt
KEEP
:告诉编译器将局部符号包含在目标文件的符号表中。
语法格式
KEEP symbol
NOFP
:可禁止源程序中包含浮点运算指令。
语法格式
NOFP
REQUIRE
:指定段之间的相互依赖关系。
语法格式
REQUIRE label
当进行连接处理时,若遇到包含有REQUIRE label 伪操作的源文件,则定义label 的源文件也将被包含。
RN
:为一个特定的寄存器定义名称。
语法格式
name RN expr
ROUT
:用于定义局部变量的有效范围。
语法格式
{
name} ROUT
当没有使用ROUT 伪操作定义局部变量的作用范围时,局部变量的作用范围为其所在的段(AREA)。ROUT伪操作作用的范围为本 ROUT伪操作和下一个ROUT伪操作(指同一个段中的 ROUT伪操作)之间。
ARM汇编语言伪指令
ADR
:该指令将基于PC的地址值或基于寄存器的地址值读取到寄存器中。
语法格式
ADR{
cond} register, expr