ARM汇编语言伪指令.docx
- 文档编号:16242354
- 上传时间:2023-07-12
- 格式:DOCX
- 页数:8
- 大小:19.02KB
ARM汇编语言伪指令.docx
《ARM汇编语言伪指令.docx》由会员分享,可在线阅读,更多相关《ARM汇编语言伪指令.docx(8页珍藏版)》请在冰点文库上搜索。
ARM汇编语言伪指令
ARM汇编语言伪指令
ARM汇编语言伪指令
ARM中伪指令不是真正的ARM指令或者Thumb指令,这些伪指令在汇编编译时对源程序进行汇编处理时被替换成对应的ARM或Thumb指令(序列。
ARM伪指令包括ADR、ADRL、LDR和NOP等。
1、ADR(小范围的地址读取伪指令
该指令将基于PC的地址值或基于寄存器的地址值读取到寄存器中。
语法格式
ADR{cond}register,expr
其中,cond为可选的指令执行的条件
register为目标寄存器
expr为基于PC或者基于寄存器的地址表达式,其取值范围如下:
当地址值不是字对齐时,其取值范围为-255~255.
当地址值是字对齐时,其取值范围为-1020~1020
当地址值是16字节对齐时,其取值范围将更大
在汇编编译器处理源程序时,ADR伪指令被编译器替换成一条合适的指令。
通常,编译器用一条ADD指令或SUB指令来实现该ADR伪指令的功能。
因为ADR伪指令中的地址是基于PC或者基于寄存器的,所以ADR读取到的地址为位置无关的地址。
当ADR伪指令中的地址是基于PC时,该地址与ADR伪指令必须在同一个代码段中。
示例
startMOVr0,#10;因为PC值为当前指令地址值加8字节
ADRr4,start;本ADR伪指令将被编译器替换成SUBr4,pc,#0xc
2、ADRL(中等范围的地址读取伪指令
该指令将基于PC或基于寄存器的地址值读取到寄存器中。
ADRL伪指令比ADR伪指令可以读取更大范围的地址。
ADRL伪指令在汇编时被编译器替换成两条指令,即使一条指令可以完成该伪指令的功能。
语法格式
ADRL{cond}register,expr
示例
startMOVr0,#10;因为PC值为当前指令地址值加8字节
ADRLr4,start+60000;本ADRL伪指令将被编译器替换成下面两条指令
ADDr4,pc,#0xe800
ADDr4,r4,#0x254
3、LDR(大范围的地址读取伪指令
LDR伪指令将一个32位的常数或者一个地址值读取到寄存器中
语法格式
LDR{cond}register,=[expr|label-expr]
其中,expr为32位的常量。
编译器将根据expr的取值情况,如下处理LDR伪指令:
当expr表示的地址值没有超过MOV或MVN指令中地址的取值范围时,编译器用合适的MOV或MVN指令代替该LDR伪指令
当expr表示的地址值超过了MOV或者MVN指令中地址的取值范围时,编译器将该常数放在数据缓冲区中,同时用一条基于PC的LDR指令读取该常数。
label-expr为基于PC的地址表达式或者是外部表达式。
当label-expr为基于PC的地址表达式时,编译器将label-expr表示的数值放在数据缓冲区(literalpool中,然后将该LDR伪指令处理成一条基于PC到该数据缓冲区单元的LDR指令,从而将该地址值读取到寄存器中。
这时,要求该数据缓冲区单元到PC的距离小于4KB。
当label-expr为外部表达式,或者非当前段的表达式时,汇编编译器将在目标文件中插入一个地址重定位伪操作,这样连接器将在连接时生成该地址。
LDR伪指令主要有以下两种用途:
当需要读取到寄存器中的数据超过了MOV及MVN指令可以操作的范围时,可以使用LDR伪指令将该数据读取到寄存器中。
将一个基于PC的地址值或者外部的地址值读取到寄存器中。
由于这种地址值是在连接时确定的,所以这种代码不是位置无关的。
同时LDR伪指令的PC值到数据缓冲区中的目标数据所在的地址的偏移量要小于4KB。
示例
将0xff0读取到R1中
LDRR1,=0xFF0
汇编后将得到:
MOVR1,0xFF0
将0xfff读取到R1中
LDRR1,=0xFFF
汇编后将得到:
LDRR1,[PC,OFFSET_TO_LPOOL]
…
LPOOLDCD0xFFF
将外部地址ADDR1读取到R1中
LDRR1,=ADDR1
汇编后将得到:
LDRR1,[PC,OFFSET_TO_LPOOL]
…
LPOOLDCDADDR1
4、NOP空操作伪指令
在汇编时将被替换成ARM中的空操作,如MOVR0,R0
NOP伪指令不影响CPSR中的条件标志位
ARM汇编程序中的符号
在ARM汇编语言中,符号(symbols可以代表地址(addresse、变量(variables和数字常量(numericconstants。
当符号代表地址时,又称为标号(lable。
当标号以数字开头时,其作用范围为当前段(当前段没有使用ROUT伪操作时,这种标号又称为局部标号(lacallable。
符号变量包括变量、数字常量、标号和局部标号。
1、变量
在程序中,变量的值在汇编处理过程中可能会发生改变。
在ARM汇编中变量有数字变量、逻辑变量和串变量3种类型。
变量的类型在程序中是不可以改变的。
数字变量的取值范围为数字常量和数字表达式所能表示的数值;逻辑变量的取值范围为{true}和{flash};串变量的取值范围为串表达式可以表达的范围。
在ARM汇编语言中,使用GBLA、GBLL及GBLS声明全局变量;使用LCLA、LCLL及LCLS声明局部变量;使用SETA、SETL及SETS为这些变量赋值。
2、数字常量
数字常量是32位的整数。
在ARM汇编语言中,使用EQU来定义数字常量。
数字常量一经定义就不可修改。
进行大小比较时,认为数字常量都是无符号数。
3、汇编时变量的替换
如果在串变量前有一个$字符,在汇编时编译器将用改串的数值来取代该串变量。
对于数字变量来说,如果该变量前面有一个$字符,在汇编时编译器将该数字变量的数值转换成十六进制的串,然后用该十六进制的串取代$字符后的数字变量。
对于逻辑变量来说,如果该逻辑变量前面有一个$字符,在汇编时编译器将该逻辑变量替换成它的取值(T或者F
如果程序中需要字符$,则用$$来表示,编译器将不进行变量替换,而是将$$当作$.
通常情况下,包含在两个竖线(|之间的$并不表示进行变量替换。
但是如果竖线(|是在双引号内,则将进行变量替换。
使用“.”来表示变量名称的结束。
4、标号
标号是表示程序中的指令或者数据地址的符号。
根据标号的生成方式可分为3种:
基于PC的标号。
基于PC的标号是位于目标指令前或者程序中数据定义伪操作前的标号。
这种标号在汇编时将被处理成PC值加上(或减去一个数字常量。
常用于表示跳转指令的目标地址,或者代码段中所嵌入的少量数据。
基于寄存器的标号。
基于寄存器的标号常用MAP和FIELD未定义操作,也可以该用EQU伪定义。
这种标号在汇编时将被处理成寄存器的值加上(或减去一个数据常量。
常用于访问数据段中的数据。
绝对地址。
绝对地址是一个32位数据。
它可以寻址232-1,即直接可以寻址整个内存空间。
5、局部标号
局部标号主要在局部范围内使用。
它由两部组成:
开头是一个0-99直接的数字,后面紧接一个通常表示该局部变量作用范围的符号。
局部变量的作用范围通常为当前段,也可以用伪操作ROUT来定义局部变量的作用范围。
局部变量定义的语法格式如下:
N{routname},其中,N为0~99之间的数字。
routname为符号,通常为该变量作用范围的名称(用ROUT伪操作定义的。
局部变量引用的语法格式如下:
%{F|B}{A|T}N{routname}
其中,N为局部变量的数字号。
routname为当前作用范围的名称(用ROUT伪操作定义的
%表示引用操作
F指示编译器只向前搜索
B指示编译器只向后搜索
A指示编译器搜索宏的所有嵌套层次
T指示编译器搜索宏的当前层次
如果F和B都没有指定,编译器先向前搜索,再向后搜索
如果A和T都没有指定,编译器搜索所有从当前层次到宏的最高层次,比当前层次低的层次不再搜索。
如果指定了routname,编译器向前搜索最近的ROUT伪操作,若routname与该ROUT伪操作定义的名称不匹配,编译器报告错误,汇编失败。
ARM汇编语言中的表达式
表达式是由符号、数值、单目或多目操作符以及括号组成的。
1、字符串表达式
字符串表达式由字符串、字符串变量、操作符以及括号组成。
字符串的最大长度为512字节,最小长度为0.下面介绍字符串表达式的组成元素。
字符串:
由包含在双引号内的一系列的字符组成。
字符串的长度受到ARM汇编语言语句长度的限制。
当在字符串中包含美元符号$或者引号"时,用$$表示一个$,用""表示一个"。
字符串变量:
用伪操作GBLS或者LCLS声明,用SETS赋值。
操作符:
(1LEN:
返回字符串的长度
:
LEN:
A
其中,A为字符串变量
(2CHR:
可以将0~255之间的整数作为含一个ASCII字符的字符串。
当有些ASCII字符不方便放在字符串中时,可以使用CHR将其放在字符串表达式中。
:
CHR:
A
其中,A为某一字符的ASCII值
(3STR:
将一个数字量或者逻辑表达式转换成串。
对于32位的数字量而言,STR将其转换成8个十六进制数组成的串;对于逻辑表达式而言,STR将其转换成字符串T或者F
:
STR:
A
其中,A为数字量或者逻辑表达式
(4LEFT:
返回一个字符串最左端一定长度的子串
A:
LEFT:
B
其中,A为源字符串,B为数字量,表示LEFT将返回的字符个数
(5RIGHT:
返回一个字符串最右端一定长度的子串
A:
RIGHT:
B
其中,A为源字符串,B为数字量,表示RIGHT将返回的字符个数
(6CC:
用于连接两个字符串。
A:
CC:
B其中,A为第1个源字符串。
B为第2个源字符串。
CC操作符将字符串B连接在字符串A的后面。
2、数字表达式数字表达式由数字常量、数字变量、操作符和括号组成数字变量用伪操作GBLA或者LCLA声明,用SETA赋值,它代表一个32位的数字量。
操作符:
(1)NOT:
按位取反:
NOT:
A其中,A为一个32位数字量
(2)+、—、×、/及MOD算术操作符A+B,A-B,A×B,A/BA:
MOD:
B表示A除以B的余数(3)ROL,ROR,SHL,SHR移位A:
ROL:
B将整数A循环左移B位A:
SHL:
B将整数A左移B位(4)AND、OR及EOR按位逻辑操作符A:
AND:
B将数字表达式A和B按位作逻辑与操作3、基于寄存器和基于PC的表达式基于寄存器的表达式表示了某个寄存器的值加上(或者减去)一个数字表达式基于PC的表达式表示了PC寄存器的值加上(或减去)一个数字表达式。
基于PC的表达式通常由程序中的标号与一个数字表达式组成。
相关的操作符:
(1)BASE:
返回基于寄存器的表达式中的寄存器编号。
:
BASE:
AA为基于寄存器的表达式
(2)INDEX:
返回基于寄存器的表达式相对于其基址寄存器的偏移量。
:
INDEX:
AA为基于寄存器的表达式(3)+、﹣:
正负号,可以放在数字表达式或者基于PC的表达式前面。
+A(﹣A)A为基于PC的表达式或者数字表达式4、逻辑表达式由逻辑量、逻辑操作符、关系操作符以及括号组成,取值范围为{FLASE}和{TRUE}
关系操作符:
用于表示两个同类表达式之间的关系。
关系操作符和它的两个操作数组成一个逻辑表达式,其取值为{FALSE}或{TRUE}如A=B表示A等于BA/=B,A<>B表示A不等于B逻辑操作符:
进行两个逻辑表达式之间的基本逻辑操作。
操作的结果为{FLASE}或{TRUE}:
LNOT:
A逻辑表达式A的值取反A:
LAND:
B逻辑表达式A和B逻辑与5、其他的一些操作符
(1)?
:
返回定义符号A的代码行所生成的可执行代码的字节数?
A其中,A为一个符号
(2)DEF:
判断某个符号是否已定义:
DEF:
A如果符号A已经定义,上述结果为{TRUE},否则为{FLASE}(3)SB_OFFSET_19_12:
SB_OFFSET_19_12:
label其中,label为一个标号返回(label-SB)的bits[19:
12](4)SB_OFFSET_11_0:
SB_OFFSET_11_0:
label返回(label-SB)的bits[11:
0]注:
可以参照ADS目录下的examples中的例子程序理解ARM汇编程序设计
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- ARM 汇编语言 指令