1、ARM教材第5章ARM汇编程序设计第5章 ARM汇编程序设计ARM编译器,如ADS集成开发环境,一般都支持汇编语言的程序设计。本章介绍ARM程序设计的一些基本概念,如ARM汇编语言的伪指令、汇编语言的语句格式和汇编语言的程序结构等到,并在些基础上介绍一些常用的ARM汇编子程序的设计。4.1 ARM伪指令ARM汇编程序由汇编指令、伪指令和宏指令组成,伪指令不介汇编指令那样在处理器的运行期间执行,而是在汇编器对汇编程序进行汇编时处理。宏是一段独立的汇编程序代码,它是通过伪指令定义的,在程序中宏指令即调用宏指令。当程序被汇编时,汇编程序对每个宏调用进行展开,用宏定义代汇编程序中的宏指令。由于指令也发
2、球汇编伪指令的一部分,因此本书将宏指令放在汇编伪一起介绍。与单片机汇编程序设计一样,在ARM汇编语言程序里,有一些特殊指令助记符,这些助记符与指令系统的助记符不同,它们没有相对应的操作友码,通常称这些特殊指令助记符为伪指令,它们所完成的操作称为伪操作。伪指令在源程序中的作用是为完成汇编程序做各种准备工作,这些伪指令仅在汇编过程中起作用,一旦汇编结束,伪指令的使命就完成了。在ARM的光荣称号程序中,有如下几种伪指令:符号定义伪指令、数据定义伪指令、汇编控制伪指令以及其他伪指令。4.1.1 符号定义(Symbol Definition)伪指令符号定义伪指令用于定义ARM汇编程序中的变量、对变量赋值
3、以及定义寄存器的别名等。常见的符号定义伪指令有以下几种: 用于宝玉局变量的GBLA、GBLL和GBLS; 用于定义局部变量的LCLA、SETL、LCLS; 用于对变量赋值的SETA、SETL、SETS; 为通用寄存器列表定义名称的RLIST; 为一个协处理器的寄存器定义名称的伪指令CN; 为一个协处理器定义名称的伪指令CP; 为一个CFP寄存器定义名称的伪指令DN和SN; 为一个FPA浮点寄存器定义名称的伪指令FN。1.GBLA、GBLL和GBLS语法格式:GBLA(GBLL或GBLS) 全局变量名GBLA、GBLL和GBLS伪指令用于定义一个ARM程序中的全局变量,并半其初始化。其中:GBL
4、A伪指令用于定义一个全局的数字变量,并初始化为0;GBLL伪指令用于定义一个全局的逻辑变量,并初始化为F(假);GBLS伪指令用于定义一个全局的字符串变量,并初始化为空。由于以上三条伪指令用于定义全局变量,因此在整个程序范围内变量名必须唯一。使用示例:GBLA Number1 ;定义一个全局的数字变量,变量名为Number1Number1 SETA 0xaa ;将Number1变量赋值为0xaaGBLL True1 ;定义一个全局的逻辑变量,变量名为True1True1 SETLTRUE ;将True1变量赋值为真GBLS String1 ;定义一个全局的字符串变量,变量名为String1 S
5、tring1 SETS“Testing” ;将String1变量赋值为“Testing”2.LCLA、LCLL和 LCLS语法格式:LCLA(LCLL或LCLS) 局部变量名LCLA、LCLL和LCLS伪指令用于定义一个ARM程序中的局部变量,并将其初始化,其中: LCLA伪指令用于定义一个局部的数字变量,并初始化为0; LCLL伪指令用于定义一个局部的逻辑变量,并初始化为F(假); LCLS伪指令用于定义一个局部的字符串变量,并初始化为空。以上三条伪指令用于声明局部变量,在其作用范围内变量名必须唯一。使用示例:LCLA Number2 ;声明一个局部的数字变量,变量名为Number2 Num
6、ber2 SETA 0xaa ;将Number2 变量赋值为0xaaLCLL Logic2 ;声明一个局部的逻辑变量,变量名为Logic2Logic2 SETLTRUE ;将Logic2变量赋值为真LCLS String2 ;定义一个局部的字符串变量,变量名为String2String2 SETS“Testing” ;将String2变量赋值为“Testing”3.SETA、SETL和SETS语法格式:变量名 SETA(SETL或SETS) 表达式伪指令SETA、SETL、SETS用于给一个已经定义的全局变量或局部变量赋值。 SETA伪指令用于给一个数学变量赋值; SETL伪指令用于给一个逻辑
7、变量赋值; SETS伪指令用于给一个字符串变量赋值。其中,变量名是已经定义地的全局变量或局部变量,表达式是将要赋给变量的值。使用示例:LCLA Number3 ;声明一个局部的数字变量,变量名为Number3Number3 SETA 0xaa ;将Number3变量赋值为0xaaLCLL Logic3 ;声明一个局部的逻辑变量,变量名为Logic3Logic3 SETLTRUE了 ;将Logic3变量赋值为真4.RLIST语法格式:名称 RLIST 寄存器列表RLIST伪指令可用于对一个通用寄存器列表定义名称,使用该伪指令定义的名称可在ARM指令LDM/STM中使用。在LDM/STM指令中,列
8、表中的寄存器访问次序为根据寄存器的编号由低到高,而与列表中的寄存器排列次序无关。使用示例:RegList RLIST R0-R5,R8,R10 ;将寄存器列表名称定义为RegList,可在ARM ;指令LDM/STM中通过该名称访问寄存器列表STMD SP!,RegList ;保存寄存器列表RegList 到堆栈由于在编程过程中,协处理器汇编伪指令使用的情况比较少,因此本书不对CP、DN和SN以及FN等协处理器伪指令进行介绍。4.1.2 数据定义(DATA Definition)伪指令数据定义伪指令一般用于为特定的数据分配存储单元,同时可完成对已分配存储单元的初始化。常见的数据定义伪指令有如下
9、几种: DCB用于分配一片连续的字节存储单元并用指定的数据初始化; DCW(DCWU)用于分配一片连续的半字节存储单元并用指定的数据初始 化; DCD(DCDU)用于分配一片连续的字存储单元并用指定的数据初始 化; DCFS(DCFSU)用于为双精度的浮点数分配一片连续的字存储单元并用指定的数据初始化; DCQ(DCQU)用于分配一片以8字节个为单位的连续的存储单元并用指定的数据初始化; DCDO用于分配一段字的内存单元,将每个单元的内容初始化为该单元相对于基址寄存器的偏移量; DCI用于分配一段字的内丰单元,并用单精度的浮点数据初始化,指定内存单元存放的是代码,而不是数据; SPACE用于分
10、配一片连续的存储单元; MAP用于定义一个结构化的内存表首地址; FIELD用于定义一个结构化的内在表的数据域; LTORG用于声明一个文字池。1.语法格式:标号 DCB 表达式DCB伪指令用于分配一片连续的字节存储单元并用伪指令中的表达式初始化。其中,表达式可以为0255的数字或字符吕,DC也可用“=”代替。使用示例:标号 DCB 表达式DCB伪指令用于分配一片连续的字节存储单元并用伪指令中指定的表达式初始化。其中,表达式可以为0255的数字或字符串,DCB也可用“=”代替。使用示例:String DCB “This is a test!” ;分配一片连续的字节存储单元并初始化Paramet
11、er DCB 0x33,0x44,0x55DCB -1,-2,0,1,2, ;分配一片连续的字节存储单元并初始化2.DCW(或DCWU)语法格式:标号 DCW(或DCWU) 表达式DCW(或DCWU)伪指令用于为双精度的浮点数分配一片连续的字节存储单元,并用伪指令中指定的表达式初始化。每个双精度的浮点数占据两个字单元,用DCFD分配的字存储单元是字对齐的,而用DCFDU分配的字存储单元并不严格字对齐。使用示例:Fdata DCFD 0,2E115。-5E7 ;分配一片连续的字存储单元并初始化为指定的双精度数5.DCFS(或DCFSU) 语法格式:标号 DCFS(或DCFSU) 表达式DCFS(
12、或DCFSU)伪指令用于为单精度的浮点数分配一片连续的字存储单元,并用伪指令中指定的表达式初始化。每个单精度的浮点数占据一个字单元,用DCFS分配的字存储单元是字对齐的,而用DCFSU分配的字存储单元并不严格对齐。使用示例:Sdata DCFS 1,2E5,-5E7 ;分配一片连续的字存储单元并初始化为指定的单精度数6.DCQ(或DCQU)语法格式:标号 DCQ(或DCQU) 表达式DCQ(或DCQU)伪指令用于分配一片以8个字节为单位的连续存储区域,并用伪指令中指定的表达式初始化。用DCQ分配的存储单元是字对齐的,而用DCQU分配的存储单元并不严格对齐。使用示例:Data DCQ 100,1
13、000 ;分配一片连续的存储单元并初始化为指定的值7.DCDO语法格式:标号 DCDO 表达式DCDO用于分配一段字内存单元,并将每个单元的内容初始化为该单元相对于表态基址寄存器的偏移量。DCDO伪指令作为表态基址寄存器R9的偏移量分配内在单元,该指令需要内在字对齐。使用示例:IMPORT externsysData DCDO externnsys ;分配32位的字单元,其值勤为标号externnsys 基于R9的偏移量8.DCI语法格式:标号 DCI 表达式DCI用于分配一段字节的内在单元,并用伪指令中指定的表达式初始化。指定内在单元存放的是代码而不是数据,在Thumb代码中,DCI分配的是
14、半字节的内存代码单元。使用示例:MACRO ;这个宏指令将指令 newinstr Rd,Rm定义为相应的机器指令Newinstr $Rd,$RmDCI 0Xe15f0f10:CR:(8$Rd:SHL:12):OR;$Rm ;这是存放的是指令MEND9.SPACE语法格式:标号 SPACE 表达式SPACE伪指令用于分配一片连续的存储区域并初始化为0。其中,表达式是要分配的字节数,SPACE也可用“%”代替。使用示例:DataSpace SPACE 1000 ;分配连续1000B的存储单元并初始化为010.MAP语法格式:MAP 表达式,基址寄存器MAP伪指令用于定义一个结构化的内存表的首地址,
15、MAP也可用“”代替。表达式可以是程序中的标号或数学表达式,基址寄存器为可选项,当基址寄存器选项不存在时,表达式的值即为内存表的首地址,当该选项存在时,内存表的首地址为表达式的值与基址寄存器的和。MAP伪指令通常与FIELD伪指令配合使用来定义结构化的内存表。使用示例:MAP 0x10,R0 ;定义结构化内存表首地址的值为0x10+R011.FIELD语法格式:标号 FIELD 表达式FIELD伪指令用于定义一个结构化内存表中的数据域。FIELD也可用“#”代替,表达式的值是当前数据域在内存表中所占的字节数。FIELD伪指令常与MAP伪指令配合使用来定义结构化的内存表,MAP伪指令定义内存表的
16、首地址,FIELD伪指令定义内存表中的各个数据域,并可以为每个数据域指定一个标号供其他的指令引用。注意MAP和FIELD伪指令仅用于定义数据结构,并不实际分配存储单元。使用示例:MAP 0x100 ;定义结构化内存表首地址的值为为0x100A FIELD 16 ;定义A的长度为16B,位置为0x100B FIELD 32 ;定义B的长度为32B,位置为 0x110(0x100的存放了 ;16个字节) S FIELD 256 ;定义S的长度为256B,位置为0x130(0x100后存放了 ;32个字节)12.LTORG语法格式:LTORGLTORG用于声明一个文字池。在使用LDR伪指令时,要在适
17、当的地址加入LTORG声明文字池,这样就会把要加载的数据保存在文字池中,再用ARM的加载指令读出数据。如果没有使用LTORG声明文字池,则汇编器会在程序末尾自动声明,使用LTORG声明文字池的目的可以在程序代码的任何位置存储加载的数据。使用示例:LDR R0,=0x12345ADD R1,R1,R0MOV PC,LRLTORG ;声明文字池,此处存放0x12345 ;其他代码4.1.3 汇编控制(Assembly Control)伪指令汇编控制伪指令用于控制汇编程序的执行流程,包括以下常用的汇编控制伪指令: IF、ELSE、ENDIF WHILE、WEND MACRO、MEND MEXIT1.
18、IF、ELSE、ENDIF语法格式:IF 逻辑表达式 指令序列1ELSE 指令序列2ENDIFIF、ELSE、ENDIF伪指令能够根据条件的成立与否决定是否执行某个指令序列。若IF后面的逻辑表达式为真,则执行指令序列1,否则执行指令序列2。其中,ELSE及指令序列2可以没有,此时,若IF后面的逻辑表达式为真,则执行指令序列1,否则继续执行后面的指令。IF、ELSE、ENDIF伪指令可以嵌套使用。使用示例:GBLS Version ;定义一个全局的字符串变量,变量名为VersionIF Version=“V1” 指令序列1ELSE 指令序列2ENDIF2.WHILE、WEND语法格式:WHILE
19、 逻辑表达式 指令序列WENDWHILE、WEND伪指令能够根据条件的成立与否决定是否循环执行某个指令序列。若WHILE后面的逻辑表达式为真,则执行指令序列,该指令序列执行完毕后,再判断逻辑表达式的值,若为真则继续执行,一直到逻辑表达式的值为假。WHILE、WEND伪指令可以嵌套使用。使用示例如下:GBLA Counter ;声明一个全局的的数字变量,变量名为Counter,作为循环计数器WHILE Counter”、“=”、“/=”“”运算符以X和Y表示两个逻辑表达式,以上的运算符代表运算如下:X=Y 表示X等于YXY 表示X大于YX=Y 表示X大于等于YX=Y 表示X小于等于YX/=Y 表
20、示X不等于YXY 表示X不等于Y “LAND”、“LOR”、“LNOT”及“LEOR”运算符以X和Y表示两个逻辑表达式,以上的逻辑运算符代表运算如下:X:LAND:Y 表示将X和Y作逻辑与的操作X:LOR:Y 表示将X和Y作逻辑或的操作:LNOT:Y 表示将将Y作逻辑非的操作X:LEOR:Y 表示将X和Y按位作逻辑异或的操作3)字符串表达式及运算符字符串表达式一般由字符串常量、字符串变量、运算符和括号构成,编译器所支持的字符串最大长度为512B。常用的字符串表达式相关的运算符如下: LEN运算符LEN运算符返回字的长度(字符数),以X表示字符串表达式,其语法格式如下:LEN:X CHR运算符CHR运算符将0255之间的整数转换为一个
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1