ARM程序设计基础 1
1 ARM汇编器所支撑的伪指令 1
2 ARM汇编器所支撑的伪指令 10
3 汇编言语的句子格局 16
4 汇编言语的程序结构 19
ARM编译器一般都支撑汇编言语的程序设计和C/C++言语的程序设计,以及两者的混合编程。本章介绍ARM程序设计的一些根本概念,如ARM汇编言语的伪指令、汇编言语的句子格局和汇编言语的程序结构等,一起介绍C/C++和汇编言语的混合编程等问题。
本章的主要内容:
- ARM编译器所支撑的伪指令
- 汇编言语的句子格局
- 汇编言语的程序结构
- 相关的程序示例
1ARM汇编器所支撑的伪指令
在ARM汇编言语程序里,有一些特别指令助记符,这些助记符与指令体系的助记符不同,没有相对应的操作码,一般称这些特别指令助记符为伪指令,他们所完结的操作称为伪操作。伪指令在源程序中的效果是为完结汇编程序作各种准备作业的,这些伪指令仅在汇编进程中起效果,一旦汇编完毕,伪指令的任务就完结。
在ARM的汇编程序中,有如下几种伪指令:符号界说伪指令、数据界说伪指令、汇编操控伪指令、宏指令以及其他伪指令。
1.1 符号界说(Symbol Definition)伪指令
符号界说伪指令用于界说ARM汇编程序中的变量、对变量赋值以及界说寄存器的别号等操作。常见的符号界说伪指令有如下几种:
— 用于界说大局变量的GBLA、GBLL和GBLS。
— 用于界说部分变量的LCLA、LCLL和LCLS。
— 用于对变量赋值的SETA、SETL、SETS。
— 为通用寄存器列表界说称号的RLIST。
1、 GBLA、GBLL和GBLS
语法格局:
GBLA(GBLL或GBLS) 大局变量名
GBLA、GBLL和GBLS伪指令用于界说一个ARM程序中的大局变量,并将其初始化。其间:
GBLA伪指令用于界说一个大局的数字变量,并初始化为0;
GBLL伪指令用于界说一个大局的逻辑变量,并初始化为F(假);
GBLS伪指令用于界说一个大局的字符串变量,并初始化为空;
因为以上三条伪指令用于界说大局变量,因而在整个程序规模内变量名有必要仅有。
运用示例:
GBLA Test1 ;界说一个大局的数字变量,变量名为Test1
Test1 SETA 0xaa ;将该变量赋值为0xaa
GBLL Test2 ;界说一个大局的逻辑变量,变量名为Test2
Test2 SETL {TRUE} ;将该变量赋值为真
GBLS Test3 ;界说一个大局的字符串变量,变量名为Test3
Test3 SETS “Testing” ;将该变量赋值为“Testing”
2、 LCLA、LCLL和LCLS
语法格局:
LCLA(LCLL或LCLS) 部分变量名
LCLA、LCLL和LCLS伪指令用于界说一个ARM程序中的部分变量,并将其初始化。其间:
LCLA伪指令用于界说一个部分的数字变量,并初始化为0;
LCLL伪指令用于界说一个部分的逻辑变量,并初始化为F(假);
LCLS伪指令用于界说一个部分的字符串变量,并初始化为空;
以上三条伪指令用于声明部分变量,在其效果规模内变量名有必要仅有。
运用示例:
LCLA Test4 ;声明一个部分的数字变量,变量名为Test4
Test3 SETA 0xaa ;将该变量赋值为0xaa
LCLL Test5 ;声明一个部分的逻辑变量,变量名为Test5
Test4 SETL {TRUE} ;将该变量赋值为真
LCLS Test6 ;界说一个部分的字符串变量,变量名为Test6
Test6 SETS “Testing” ;将该变量赋值为“Testing”
3、 SETA、SETL和SETS
语法格局:
变量名 SETA(SETL或SETS) 表达式
伪指令SETA、SETL、SETS用于给一个现已界说的大局变量或部分变量赋值。
SETA伪指令用于给一个数学变量赋值;
SETL伪指令用于给一个逻辑变量赋值;
SETS伪指令用于给一个字符串变量赋值;
其间,变量名为现已界说过的大局变量或部分变量,表达式为即将赋给变量的值。
运用示例:
LCLA Test3 ;声明一个部分的数字变量,变量名为Test3
Test3 SETA 0xaa ;将该变量赋值为0xaa
LCLL Test4 ;声明一个部分的逻辑变量,变量名为Test4
Test4 SETL {TRUE} ;将该变量赋值为真
4、RLIST
语法格局:
称号 RLIST {寄存器列表}
RLIST伪指令可用于对一个通用寄存器列表界说称号,运用该伪指令界说的称号可在ARM指令LDM/STM中运用。在LDM/STM指令中,列表中的寄存器拜访次第为依据寄存器的编号由低到高,而与列表中的寄存器摆放次第无关。
运用示例:
RegList RLIST {R0-R5,R8,R10} ;将寄存器列表称号界说为RegList,可在ARM指令LDM/STM中经过该称号拜访寄存器列表。
1.2 数据界说(Data Definition)伪指令
数据界说伪指令一般用于为特定的数据分配存储单元,一起可完结已分配存储单元的初始化。常见的数据界说伪指令有如下几种:
— DCB 用于分配一片接连的字节存储单元并用指定的数据初始化。
— DCW(DCWU) 用于分配一片接连的半字存储单元并用指定的数据初始化。
— DCD(DCDU) 用于分配一片接连的字存储单元并用指定的数据初始化。
— DCFD(DCFDU)用于为双精度的浮点数分配一片接连的字存储单元并用指定的数据初始化。
— DCFS(DCFSU) 用于为单精度的浮点数分配一片接连的字存储单元并用指定的数据初始化。
— DCQ(DCQU) 用于分配一片以8字节为单位的接连的存储单元并用指定的数据初始化。
— SPACE 用于分配一片接连的存储单元
— MAP 用于界说一个结构化的内存表首地址
— FIELD 用于界说一个结构化的内存表的数据域
1、 DCB
语法格局:
标号 DCB 表达式
DCB伪指令用于分配一片接连的字节存储单元并用伪指令中指定的表达式初始化。其间,表达式能够为0~255的数字或字符串。DCB也可用“=”替代。
运用示例:
Str DCB “This is a test!” ;分配一片接连的字节存储单元并初始化。
2、 DCW(或DCWU)
语法格局:
标号 DCW(或DCWU) 表达式
DCW(或DCWU)伪指令用于分配一片接连的半字存储单元并用伪指令中指定的表达式初始化。其间,表达式能够为程序标号或数字表达式。。
用DCW分配的字存储单元是半字对齐的,而用DCWU分配的字存储单元并不严厉半字对齐。
运用示例:
DataTest DCW 1,2,3 ;分配一片接连的半字存储单元并初始化。
3、 DCD(或DCDU)
语法格局:
标号 DCD(或DCDU) 表达式
DCD(或DCDU)伪指令用于分配一片接连的字存储单元并用伪指令中指定的表达式初始化。其间,表达式能够为程序标号或数字表达式。DCD也可用“&”替代。
用DCD分配的字存储单元是字对齐的,而用DCDU分配的字存储单元并不严厉字对齐。
运用示例:
DataTest DCD 4,5,6 ;分配一片接连的字存储单元并初始化。
4、 DCFD(或DCFDU)
语法格局:
标号 DCFD(或DCFDU) 表达式
DCFD(或DCFDU)伪指令用于为双精度的浮点数分配一片接连的字存储单元并用伪指令中指定的表达式初始化。每个双精度的浮点数占有两个字单元。
用DCFD分配的字存储单元是字对齐的,而用DCFDU分配的字存储单元并不严厉字对齐。
运用示例:
FDataTest DCFD 2E115,-5E7 ;分配一片接连的字存储单元并初始化为指定的双精度数。
5、 DCFS(或DCFSU)
语法格局:
标号 DCFS(或DCFSU) 表达式
DCFS(或DCFSU)伪指令用于为单精度的浮点数分配一片接连的字存储单元并用伪指令中指定的表达式初始化。每个单精度的浮点数占有一个字单元。
用DCFS分配的字存储单元是字对齐的,而用DCFSU分配的字存储单元并不严厉字对齐。
运用示例:
FDataTest DCFS 2E5,-5E-7 ;分配一片接连的字存储单元并初始化为指定的单精度数。
6、 DCQ(或DCQU)
语法格局:
标号 DCQ(或DCQU) 表达式
DCQ(或DCQU)伪指令用于分配一片以8个字节为单位的接连存储区域并用伪指令中指定的表达式初始化。
用DCQ分配的存储单元是字对齐的,而用DCQU分配的存储单元并不严厉字对齐。
运用示例:
DataTest DCQ 100 ;分配一片接连的存储单元并初始化为指定的值。
7、 SPACE
语法格局:
标号 SPACE 表达式
SPACE伪指令用于分配一片接连的存储区域并初始化为0。其间,表达式为要分配的字节数。SPACE也可用“%”替代。
运用示例:
DataSpace SPACE 100 ;分配接连100字节的存储单元并初始化为0。
8、 MAP
语法格局:
MAP 表达式{,基址寄存器}
MAP伪指令用于界说一个结构化的内存表的首地址。MAP也可用“^”替代。
表达式能够为程序中的标号或数学表达式,基址寄存器为可选项,当基址寄存器选项不存在时,表达式的值即为内存表的首地址,当该选项存在时,内存表的首地址为表达式的值与基址寄存器的和。
MAP伪指令一般与FIELD伪指令合作运用来界说结构化的内存表。
运用示例:
MAP 0x100,R0 ;界说结构化内存表首地址的值为0x100+R0。
9、 FILED
语法格局:
标号 FIELD 表达式
FIELD伪指令用于界说一个结构化内存表中的数据域。FILED也可用“#”替代。
表达式的值为当时数据域在内存表中所占的字节数。
FIELD伪指令常与MAP伪指令合作运用来界说结构化的内存表。MAP伪指令界说内存表的首地址,FIELD伪指令界说内存表中的各个数据域,并能够为每个数据域指定一个标号供其他的指令引证。
留意MAP和FIELD伪指令仅用于界说数据结构,并不实践分配存储单元。
运用示例:
MAP 0x100 ;界说结构化内存表首地址的值为0x100。
A FIELD 16 ;界说A的长度为16字节,方位为0x100
B FIELD 32 ;界说B的长度为32字节,方位为0x110
S FIELD 256 ;界说S的长度为256字节,方位为0x130
1.3 汇编操控(Assembly Control)伪指令
汇编操控伪指令用于操控汇编程序的履行流程,常用的汇编操控伪指令包含以下几条:
— IF、ELSE、ENDIF
— WHILE、WEND
— MACRO、MEND
— MEXIT
1、 IF、ELSE、ENDIF
语法格局:
IF 逻辑表达式
指令序列1
ELSE
指令序列2
ENDIF
IF、ELSE、ENDIF伪指令能依据条件的建立与否决议是否履行某个指令序列。当IF后边的逻辑表达式为真,则履行指令序列1,不然履行指令序列2。其间,ELSE及指令序列2能够没有,此刻,当IF后边的逻辑表达式为真,则履行指令序列1,不然持续履行后边的指令。
IF、ELSE、ENDIF伪指令能够嵌套运用。
运用示例:
GBLL Test ;声明一个大局的逻辑变量,变量名为Test
……
IF Test =TRUE
指令序列1
ELSE
指令序列2
ENDIF
2、 WHILE、WEND
语法格局:
WHILE 逻辑表达式
指令序列
WEND
WHILE、WEND伪指令能依据条件的建立与否决议是否循环履行某个指令序列。当WHILE后边的逻辑表达式为真,则履行指令序列,该指令序列履行完毕后,再判别逻辑表达式的值,若为真则持续履行,一直到逻辑表达式的值为假。
WHILE、WEND伪指令能够嵌套运用。
运用示例:
GBLA Counter ;声明一个大局的数学变量,变量名为Counter
Counter SETA 3 ;由变量Counter操控循环次数
……
WHILE Counter< 10
指令序列
WEND
3、 MACRO、MEND
语法格局:
$标号 宏名 $参数1,$参数2,……
指令序列
MEND
MACRO、MEND伪指令能够将一段代码界说为一个全体,称为宏指令,然后就能够在程序中经过宏指令屡次调用该段代码。其间,$标号在宏指令被打开时,标号会被替换为用户界说的符号,
宏指令能够运用一个或多个参数,当宏指令被打开时,这些参数被相应的值替换。
宏指令的运用办法和功用与子程序有些相似,子程序能够供给模块化的程序设计、节约存储空间并进步运转速度。但在运用子程序结构时需求维护现场,然后添加了体系的开支,因而,在代码较短且需求传递的参数较多时,能够运用宏指令替代子程序。
包含在MACRO和MEND之间的指令序列称为宏界说体,在宏界说体的榜首行应声明宏的原型(包含宏名、所需的参数),然后就能够在汇编程序中经过宏名来调用该指令序列。在源程序被编译时,汇编器将宏调用打开,用宏界说中的指令序列替代程序中的宏调用,并将实践参数的值传递给宏界说中的形式参数。
MACRO、MEND伪指令能够嵌套运用。
4、 MEXIT
语法格局:
MEXIT
MEXIT用于从宏界说中跳转出去。
1.4 其他常用的伪指令
还有一些其他的伪指令,在汇编程序中常常会被运用,包含以下几条:
— AREA
— ALIGN
— CODE16、CODE32
— ENTRY
— END
— EQU
— EXPORT(或GLOBAL)
— IMPORT
— EXTERN
— GET(或INCLUDE)
— INCBIN
— RN
— ROUT
1、 AREA
语法格局:
AREA 段名 特点1,特点2,……
AREA伪指令用于界说一个代码段或数据段。其间,段名若以数字最初,则该段名需用“|”括起来,如|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 {表达式{,偏移量}}
ALIGN伪指令可经过添加填充字节的办法,使当时方位满意必定的对其办法|。其间,表达式的值用于指定对齐办法,或许的取值为2的幂,如1、2、4、8、16等。若未指定表达式,则将当时方位对齐到下一个字的方位。偏移量也为一个数字表达式,若运用该字段,则当时方位的对齐办法为:2的表达式次幂+偏移量。
运用示例:
AREA Init,CODE,READONLY,ALIEN=3 ;指定后边的指令为8字节对齐。
指令序列
END
3、 CODE16、CODE32
语法格局:
CODE16(或CODE32)
CODE16伪指令告诉编译器,这以后的指令序列为16位的Thumb指令。
CODE32伪指令告诉编译器,这以后的指令序列为32位的ARM指令。
若在汇编源程序中一起包含ARM指令和Thumb指令时,可用CODE16伪指令告诉编译器这以后的指令序列为16位的Thumb指令,CODE32伪指令告诉编译器这以后的指令序列为32位的ARM指令。因而,在运用ARM指令和Thumb指令混合编程的代码里,可用这两条伪指令进行切换,但留意他们只告诉编译器这以后指令的类型,并不能对处理器进行状况的切换。
运用示例:
AREA Init,CODE,READONLY
……
CODE32 ;告诉编译器这以后的指令为32位的ARM指令
LDR R0,=NEXT+1 ;将跳转地址放入寄存器R0
BX R0 ;程序跳转到新的方位履行,并将处理器切换到Thumb作业状况
……
CODE16 ;告诉编译器这以后的指令为16位的Thumb指令
NEXT LDR R3,=0x3FF
……
END ;程序完毕
4、 ENTRY
语法格局:
ENTRY
ENTRY伪指令用于指定汇编程序的进口点。在一个完好的汇编程序中至少要有一个ENTRY(也能够有多个,当有多个ENTRY时,程序的真实进口点由链接器指定),但在一个源文件里最多只能有一个ENTRY(能够没有)。
运用示例:
AREA Init,CODE,READONLY
ENTRY ;指定应用程序的进口点
……
5、 END
语法格局:
END
END伪指令用于告诉编译器现已到了源程序的结束。
运用示例:
AREA Init,CODE,READONLY
……
END ;指定应用程序的结束
6、 EQU
语法格局:
称号 EQU 表达式{,类型}
EQU伪指令用于为程序中的常量、标号等界说一个等效的字符称号,相似于C言语中的#define。其间EQU可用“*”替代。
称号为EQU伪指令界说的字符称号,当表达式为32位的常量时,能够指定表达式的数据类型,能够有以下三种类型:
CODE16、CODE32和DATA
运用示例:
Test EQU 50 ;界说标号Test的值为50
Addr EQU 0x55,CODE32 ;界说Addr的值为0x55,且该处为32位的ARM指令。
7、 EXPORT(或GLOBAL)
语法格局:
EXPORT 标号{[WEAK]}
EXPORT伪指令用于在程序中声明一个大局的标号,该标号可在其他的文件中引证。EXPORT可用GLOBAL替代。标号在程序中区别大小写,[WEAK]选项声明其他的同名标号优先于该标号被引证。
运用示例:
AREA Init,CODE,READONLY
EXPORT Stest ;声明一个可大局引证的标号Stest
……
END
8、 IMPORT
语法格局:
IMPORT 标号{[WEAK]}
IMPORT伪指令用于告诉编译器要运用的标号在其他的源文件中界说,但要在当时源文件中引证,并且不管当时源文件是否引证该标号,该标号均会被加入到当时源文件的符号表中。
标号在程序中区别大小写,[WEAK]选项表明当一切的源文件都没有界说这样一个标号时,编译器也不给出错误信息,在大都情况下将该标号置为0,若该标号为B或BL指令引证,则将B或BL指令置为NOP操作。
运用示例:
AREA Init,CODE,READONLY
IMPORT Main ;告诉编译器当时文件要引证标号Main,但Main在其他源文件中界说
……
END
9、 EXTERN
语法格局:
EXTERN 标号{[WEAK]}
EXTERN伪指令用于告诉编译器要运用的标号在其他的源文件中界说,但要在当时源文件中引证,假如当时源文件实践并未引证该标号,该标号就不会被加入到当时源文件的符号表中。
标号在程序中区别大小写,[WEAK]选项表明当一切的源文件都没有界说这样一个标号时,编译器也不给出错误信息,在大都情况下将该标号置为0,若该标号为B或BL指令引证,则将B或BL指令置为NOP操作。
运用示例:
AREA Init,CODE,READONLY
EXTERN Main ;告诉编译器当时文件要引证标号Main,但Main在其他源文件中界说
……
END
10、GET(或INCLUDE)
语法格局:
GET 文件名
GET伪指令用于将一个源文件包含到当时的源文件中,并将被包含的源文件在当时方位进行汇编处理。能够运用INCLUDE替代GET。
汇编程序中常用的办法是在某源文件中界说一些宏指令,用EQU界说常量的符号称号,用MAP和FIELD界说结构化的数据类型,然后用GET伪指令将这个源文件包含到其他的源文件中。运用办法与C言语中的“include”相似。
GET伪指令只能用于包含源文件,包含方针文件需求运用INCBIN伪指令
运用示例:
AREA Init,CODE,READONLY
GET a1.s ;告诉编译器当时源文件包含源文件a1.s
GE T C:\a2.s ;告诉编译器当时源文件包含源文件C:\ a2.s
……
END
11、INCBIN
语法格局:
INCBIN 文件名
INCBIN伪指令用于将一个方针文件或数据文件包含到当时的源文件中,被包含的文件不作任何变化的存放在当时文件中,编译器从这以后开端持续处理。
运用示例:
AREA Init,CODE,READONLY
INCBIN a1.dat ;告诉编译器当时源文件包含文件a1.dat
INCBIN C:\a2.txt ;告诉编译器当时源文件包含文件C:\a2.txt
……
END
12、RN
语法格局:
称号 RN 表达式
RN伪指令用于给一个寄存器界说一个别号。选用这种办法能够便利程序员回忆该寄存器的功用。其间,称号为给寄存器界说的别号,表达式为寄存器的编码。
运用示例:
Temp RN R0 ;将R0界说一个别号Temp
13、ROUT
语法格局:
{称号} ROUT
ROUT伪指令用于给一个部分变量界说效果规模。在程序中未运用该伪指令时,部分变量的效果规模为地点的AREA,而运用ROUT后,部分变量的作为规模为当时ROUT和下一个ROUT之间。
2ARM汇编器所支撑的伪指令
ARM微处理器的指令集能够分为跳转指令、数据处理指令、程序状况寄存器(PSR)处理指令、加载/存储指令、协处理器指令和反常发生指令六大类。
2.1 指令的条件域
当处理器作业在ARM状况时,简直一切的指令均依据CPSR中条件码的状况和指令的条件域有条件的履行。当指令的履行条件满意时,指令被履行,不然指令被疏忽。
每一条ARM指令包含4位的条件码,坐落指令的最高4位[31:28]。条件码共有16种,每种条件码可用两个字符表明,这两个字符能够添加在指令助记符的后边和指令一起运用。
2.2 寻址办法
n当即寻址
n寄存器寻址
n寄存器直接寻址
n基址变址寻址
n多寄存器寻址
n相对寻址
n仓库寻址
1当即寻址
当即寻址也叫当即数寻址,这是一种特别的寻址办法,操作数自身就在指令中给出,只需取出指令也就取到了操作数。这个操作数被称为当即数,对应的寻址办法也就叫做当即寻址。
ADDR0,R0,#1 ;R0←R0+1
ADDR0,R0,#0x3f ;R0←R0+0x3f
2寄存器寻址
寄存器寻址便是运用寄存器中的数值作为操作数,这种寻址办法是各类微处理器常常选用的一种办法,也是一种履行功率较高的寻址办法。
ADDR0,R1,R2 ;R0←R1+R2
3寄存器直接寻址
寄存器直接寻址便是以寄存器中的值作为操作数的地址,而操作数自身存放在存储器中。
ADDR0,R1,[R2] ;R0←R1+[R2]
LDRR0,[R1] ;R0←[R1]
STRR0,[R1] ;[R1]←R0
4基址变址寻址
基址变址寻址便是将寄存器(该寄存器一般称作基址寄存器)的内容与指令中给出的地址偏移量相加,然后得到一个操作数的有用地址。变址寻址办法常用于拜访某基地址邻近的地址单元。
LDR R0,[R1,#4] ;R0←[R1+4]
LDR R0,[R1,#4]! ;R0←[R1+4]、R1←R1+4
LDR R0,[R1] ,#4 ;R0←[R1]、R1←R1+4
LDR R0,[R1,R2] ;R0←[R1+R2]
5多寄存器寻址
选用多寄存器寻址办法,一条指令能够完结多个寄存器值的传送。这种寻址办法能够用一条指令完结传送最多16个通用寄存器的值。
LDMIA R0,{R1,R2,R3,R4}
;R1←[R0],R2←[R0+4],R3←[R0+8],R4←[R0+12]
该指令的后缀IA表明在每次履行完加载/存储操作后,R0按字长度添加,因而,指令可将接连存储单元的值传送到R1~R4。
6相对寻址
与基址变址寻址办法相相似,相对寻址以程序计数器PC的当时值为基地址,指令中的地址标号作为偏移量,将两者相加之后得到操作数的有用地址。以下程序段完结子程序的调用和回来,跳转指令BL选用了相对寻址办法:
BL NEXT ;跳转到子程序NEXT处履行
……
NEXT:
……
MOV PC,LR ;从子程序回来
7 仓库寻址
操作次序为“后进先出” 。仓库寻址是隐含的,它运用一个专门的寄存器(仓库指针)指向一块存储区域(仓库),指针所指向的存储单元便是仓库的栈顶。存储器仓库可分为两种:
-
- 向上成长:向高地址方向成长,称为递加仓库
- 向下成长:向低地址方向成长,称为递减仓库
仓库指针指向最终压入的仓库的有用数据项,称为满仓库;仓库指针指向下一个待压入数据的空方位,称为空仓库。
四种类型的仓库办法:
- 满递加:仓库向上添加,仓库指针指向内含有用数据项的最高地址。指令如LDMFA、STMFA等;
- 空递加:仓库向上添加,仓库指针指向仓库上的榜首个空方位。指令如LDMEA、STMEA等;
- 满递减:仓库向下添加,仓库指针指向内含有用数据项的最低地址。指令如LDMFD、STMFD等;
- 空递减:仓库向下添加,仓库指针向仓库下的榜首个空方位。指令如LDMED、STMED等。
8块复制寻址
多寄存器传送指令用于将一块数据从存储器的某一方位复制到另一方位。如:
STMIA R0!,{R1-R7};将R1~R7的数据保存到存储器中。
;存储指针在保存榜首个值之后添加,
;添加方向为向上添加。
STMIB R0!,{R1-R7} ;将R1~R7的数据保存到存储器中。
;存储指针在保存榜首个值之前添加,
;添加方向为向上添加。
留意:
1)IA:每次传送后地址加4
2)IB:每次传送前地址加4
3)DA:每次传送后地址减4
4)DB:每次传送前地址减4
5)FD:满递减仓库
6)ED:空递减仓库
7)FA:满递加仓库
8)EA:空递加仓库
R0!后缀“!”表明最终的地址回写到R0中。
LDMIAR0!,{R2—R3}履行进程剖析:
当把R0指向的地址0xFF00中的数据加载到R2后,地址加4,变为0xFF04;接着把0xFF04中的数据加载到R3,地址变为0xFF08。最终把该地址回写到R0。
2.3 ARM指令集
n跳转指令
n数据处理指令
n程序状况寄存器处理指令
n加载/存储指令
n协处理器指令
n反常发生指令
1跳转指令
n在ARM程序中完结程序流程的跳转有两种办法
v运用专门的跳转指令
v直接向程序计数器PC写入跳转地址值
nARM指令会集的跳转指令包含以下4条指令
vB 跳转指令
vBL 带回来的跳转指令
vBLX 带回来和状况切换的跳转指令
vBX 带状况切换的跳转指令
留意:一旦遇到一个B指令,ARM 处理器将当即跳转到给定的方针地址履行。存储在跳转指令中的实践值是相对当时PC值的一个偏移量,由汇编器来核算。
BL 带回来的跳转指令
跳转之前,会在寄存器R14中保存PC的当时内容,因而,能够经过将R14 的内容从头加载到PC中,来回来到跳转指令之后的那个指令处履行。该指令是完结子程序调用的一个根本手法。
2数据处理指令
n数据处理指令可分为数据传送指令、算术逻辑运算指令和比较指令等。
n数据传送指令用于在寄存器和存储器之间进行数据的双向传输。
n算术逻辑运算指令完结常用的算术与逻辑的运算,该类指令不光将运算成果保存在意图寄存器中,一起更新CPSR中的相应条件标志位。
n比较指令不保存运算成果,只更新CPSR中相应的条件标志位。
MOV{条件}{S} 意图寄存器,源操作数
MVN{条件}{S} 意图寄存器,源操作数
与MOV指令不同之处是在传送之前按位被取反了,即把一个被取反的值传送到意图寄存器中。
CMP{条件} 操作数1,操作数2
CMP指令用于比较一个寄存器的内容和另一个寄存器的内容或当即数,一起更新CPSR中条件标志位的值。该指令进行一次减法运算,但不存储成果,只更改条件标志位。
CMN{条件} 操作数1,操作数2
CMN指令用于把一个寄存器的内容和另一个寄存器的内容或当即数取反后进行比较,一起更新CPSR中条件标志位的值。该指令实践完结操作数1和操作数2相加,并依据成果更改条件标志位。
TST{条件} 操作数1,操作数2
TST指令用于把一个寄存器的内容和另一个寄存器的内容或当即数进行按位的与运算,并依据运算成果更新CPSR中条件标志位的值。操作数1是要测验的数据,而操作数2是一个位掩码,该指令一般用来检测是否设置了特定的位。
TEQ{条件} 操作数1,操作数2
用于把一个寄存器的内容和另一个寄存器的内容或当即数进行按位的异或运算,并依据运算成果更新CPSR中条件标志位的值。该指令一般用于比较操作数1和操作数2是否持平。
ADD{条件}{S} 意图寄存器,操作数1,操作数2
ADC{条件}{S} 意图寄存器,操作数1,操作数2
ADC指令用于把两个操作数相加,再加上CPSR的C条件标志位的值,并将成果存放到意图寄存器中。
SUB{条件}{S} 意图寄存器,操作数1,操作数2
SBC{条件}{S} 意图寄存器,操作数1,操作数2
SBC指令用于把操作数1减去操作数2,再减去CPSR的C条件标志位的反码,并将成果存放到意图寄存器中。