[工学]ARM教材第5章ARM汇编程序设计_第1页
[工学]ARM教材第5章ARM汇编程序设计_第2页
[工学]ARM教材第5章ARM汇编程序设计_第3页
[工学]ARM教材第5章ARM汇编程序设计_第4页
[工学]ARM教材第5章ARM汇编程序设计_第5页
已阅读5页,还剩11页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、第5章 ARM汇编程序设计ARM编译器,如ADS集成开发环境,一般都支持汇编语言的程序设计。本章介绍ARM程序设计的一些基本概念,如ARM汇编语言的伪指令、汇编语言的语句格式和汇编语言的程序结构等到,并在些基础上介绍一些常用的ARM汇编子程序的设计。4.1 ARM伪指令ARM汇编程序由汇编指令、伪指令和宏指令组成,伪指令不介汇编指令那样在处理器的运行期间执行,而是在汇编器对汇编程序进行汇编时处理。宏是一段独立的汇编程序代码,它是通过伪指令定义的,在程序中宏指令即调用宏指令。当程序被汇编时,汇编程序对每个宏调用进行展开,用宏定义代汇编程序中的宏指令。由于指令也发球汇编伪指令的一部分,因此本书将宏

2、指令放在汇编伪一起介绍。与单片机汇编程序设计一样,在ARM汇编语言程序里,有一些特殊指令助记符,这些助记符与指令系统的助记符不同,它们没有相对应的操作友码,通常称这些特殊指令助记符为伪指令,它们所完成的操作称为伪操作。伪指令在源程序中的作用是为完成汇编程序做各种准备工作,这些伪指令仅在汇编过程中起作用,一旦汇编结束,伪指令的使命就完成了。在ARM的光荣称号程序中,有如下几种伪指令:符号定义伪指令、数据定义伪指令、汇编控制伪指令以及其他伪指令。4.1.1 符号定义(Symbol Definition)伪指令符号定义伪指令用于定义ARM汇编程序中的变量、对变量赋值以及定义寄存器的别名等。常见的符号

3、定义伪指令有以下几种:l 用于宝玉局变量的GBLA、GBLL和GBLS;l 用于定义局部变量的LCLA、SETL、LCLS;l 用于对变量赋值的SETA、SETL、SETS;l 为通用寄存器列表定义名称的RLIST;l 为一个协处理器的寄存器定义名称的伪指令CN;l 为一个协处理器定义名称的伪指令CP;l 为一个CFP寄存器定义名称的伪指令DN和SN;l 为一个FPA浮点寄存器定义名称的伪指令FN。1. GBLA、GBLL和GBLS语法格式:GBLA(GBLL或GBLS) 全局变量名GBLA、GBLL和GBLS伪指令用于定义一个ARM程序中的全局变量,并半其初始化。其中:GBLA伪指令用于定义

4、一个全局的数字变量,并初始化为0;GBLL伪指令用于定义一个全局的逻辑变量,并初始化为F(假);GBLS伪指令用于定义一个全局的字符串变量,并初始化为空。由于以上三条伪指令用于定义全局变量,因此在整个程序范围内变量名必须唯一。使用示例:GBLA Number1 ;定义一个全局的数字变量,变量名为Number1Number1 SETA 0xaa ;将Number1变量赋值为0xaaGBLL True1 ;定义一个全局的逻辑变量,变量名为True1True1 SETLTRUE;将True1变量赋值为真GBLS String1 ;定义一个全局的字符串变量,变量名为String1 String1 SE

5、TS“Testing” ;将String1变量赋值为“Testing”2. LCLA、LCLL和 LCLS语法格式:LCLA(LCLL或LCLS) 局部变量名LCLA、LCLL和LCLS伪指令用于定义一个ARM程序中的局部变量,并将其初始化,其中:l LCLA伪指令用于定义一个局部的数字变量,并初始化为0;l LCLL伪指令用于定义一个局部的逻辑变量,并初始化为F(假);l LCLS伪指令用于定义一个局部的字符串变量,并初始化为空。以上三条伪指令用于声明局部变量,在其作用范围内变量名必须唯一。使用示例:LCLA Number2 ;声明一个局部的数字变量,变量名为Number2 Number2

6、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用于给一个已经定义的全局变量或局部变量赋值。l SETA伪指令用于给一个数学变量赋值;l SETL伪指令用于给一个逻辑变量

7、赋值;l 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、几种:l DCB用于分配一片连续的字节存储单元并用指定的数据初始化;l DCW(DCWU)用于分配一片连续的半字节存储单元并用指定的数据初始 化;l DCD(DCDU)用于分配一片连续的字存储单元并用指定的数据初始 化;l DCFS(DCFSU)用于为双精度的浮点数分配一片连续的字存储单元并用指定的数据初始化;l DCQ(DCQU)用于分配一片以8字节个为单位的连续的存储单元并用指定的数据初始化;l DCDO用于分配一段字的内存单元,将每个单元的内容初始化为该单元相对于基址寄存器的偏移量;l DCI用于分配一段字的内丰单元,并用单精度的浮点数据初始化,指定内存单元存放的是代码,而不是数据;l

10、SPACE用于分配一片连续的存储单元;l MAP用于定义一个结构化的内存表首地址;l FIELD用于定义一个结构化的内在表的数据域;l LTORG用于声明一个文字池。1.语法格式:标号 DCB 表达式DCB伪指令用于分配一片连续的字节存储单元并用伪指令中的表达式初始化。其中,表达式可以为0255的数字或字符吕,DC也可用“=”代替。使用示例:标号 DCB 表达式DCB伪指令用于分配一片连续的字节存储单元并用伪指令中指定的表达式初始化。其中,表达式可以为0255的数字或字符串,DCB也可用“=”代替。使用示例:String DCB “This is a test!” ;分配一片连续的字节存储单元

11、并初始化Parameter 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(或DC

12、FSU) 表达式DCFS(或DCFSU)伪指令用于为单精度的浮点数分配一片连续的字存储单元,并用伪指令中指定的表达式初始化。每个单精度的浮点数占据一个字单元,用DCFS分配的字存储单元是字对齐的,而用DCFSU分配的字存储单元并不严格对齐。使用示例:Sdata DCFS 1,2E5,-5E7 ;分配一片连续的字存储单元并初始化为指定的单精度数6. DCQ(或DCQU)语法格式:标号 DCQ(或DCQU) 表达式DCQ(或DCQU)伪指令用于分配一片以8个字节为单位的连续存储区域,并用伪指令中指定的表达式初始化。用DCQ分配的存储单元是字对齐的,而用DCQU分配的存储单元并不严格对齐。使用示例:

13、Data DCQ 100,1000 ;分配一片连续的存储单元并初始化为指定的值7. DCDO语法格式:标号 DCDO 表达式DCDO用于分配一段字内存单元,并将每个单元的内容初始化为该单元相对于表态基址寄存器的偏移量。DCDO伪指令作为表态基址寄存器R9的偏移量分配内在单元,该指令需要内在字对齐。使用示例:IMPORT externsysData DCDO externnsys ;分配32位的字单元,其值勤为标号externnsys 基于R9的偏移量8. DCI语法格式:标号 DCI 表达式DCI用于分配一段字节的内在单元,并用伪指令中指定的表达式初始化。指定内在单元存放的是代码而不是数据,在

14、Thumb代码中,DCI分配的是半字节的内存代码单元。使用示例: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伪指令配合使用来定义结

16、构化的内存表,MAP伪指令定义内存表的首地址,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用于声明一

17、个文字池。在使用LDR伪指令时,要在适当的地址加入LTORG声明文字池,这样就会把要加载的数据保存在文字池中,再用ARM的加载指令读出数据。如果没有使用LTORG声明文字池,则汇编器会在程序末尾自动声明,使用LTORG声明文字池的目的可以在程序代码的任何位置存储加载的数据。使用示例:LDR R0,=0x12345ADD R1,R1,R0MOV PC,LRLTORG ;声明文字池,此处存放0x12345 ;其他代码4.1.3 汇编控制(Assembly Control)伪指令汇编控制伪指令用于控制汇编程序的执行流程,包括以下常用的汇编控制伪指令:l IF、ELSE、ENDIFl WHILE、WE

18、NDl MACRO、MENDl MEXIT1.IF、ELSE、ENDIF语法格式:IF 逻辑表达式 指令序列1ELSE 指令序列2ENDIFIF、ELSE、ENDIF伪指令能够根据条件的成立与否决定是否执行某个指令序列。若IF后面的逻辑表达式为真,则执行指令序列1,否则执行指令序列2。其中,ELSE及指令序列2可以没有,此时,若IF后面的逻辑表达式为真,则执行指令序列1,否则继续执行后面的指令。IF、ELSE、ENDIF伪指令可以嵌套使用。使用示例:GBLS Version ;定义一个全局的字符串变量,变量名为VersionIF Version=“V1” 指令序列1ELSE 指令序列2ENDI

19、F2. WHILE、WEND语法格式:WHILE 逻辑表达式 指令序列WENDWHILE、WEND伪指令能够根据条件的成立与否决定是否循环执行某个指令序列。若WHILE后面的逻辑表达式为真,则执行指令序列,该指令序列执行完毕后,再判断逻辑表达式的值,若为真则继续执行,一直到逻辑表达式的值为假。WHILE、WEND伪指令可以嵌套使用。使用示例如下:GBLA Counter ;声明一个全局的的数字变量,变量名为Counter,作为循环计数器WHILE Counter<10 指令序列WEND3. MACRO、MEND语法格式:$标号 宏名$参数1,$参数2,指令序列MENDMACRO、MEND

20、伪指令可以将一段代码定义为一个整体,称为宏指令,然后就可以在程序中通过宏指令多次调用该段代码。其中,$标号在宏指令被展开时,标号会被替换为用户定义的符号,宏指令可以使用一个或多个参数,当宏指令被展开时,这些参数被相应的值替换。宏指令的使用方式和功能与子程序相似,子程序可以提供模块化的程序设计,节省存储空间并提高运行速度。包含在MAMEND之间的指令序列称为宏定义体,在宏定义的第一行应声明宏的原型(包含宏名、所需的参数),然后就可以在汇编程序中通过宏名来调用该指令序列。MACRO、MEND可以嵌套使用。使用示例如下:MACRO CODE_1 ;宏名为CODE_1,无参数 LDR R0,=rPDA

21、TG ;读取PG0口的值 LDR R1,R0 ORR R1,R1,#0X01 ;CSI置位 SRT R1,R0MEND4. MEXIT语法格式:MEXITMEXIT用于从宏定义中跳转出去4.1.4 其他常用的伪指令还有一些其他的伪指令,在汇编程序中经常会被使用,下面是一些使用比较频繁的伪指令:l AREAl ALIGNl CODE16、CODE32l ENTRYl ENDl EQUl EXPORT(GLOBAL)l IMPORTl EXTERNl GET(INCLUDE)l INCBINl RNl ROUT4.2 汇编语法4.2.1 汇编程序源文件ARM汇编源程序文件是文本文件格式,可以使用任

22、意一种文本编辑器编写程序代码。通常情况下,ARM项目中的源程序文件具有如表4.1所示的扩展名。表4.1 ARM项目中的源程序文件及扩展名源程序文件扩展名汇编源程序.s包含文件.incC文件.c头文件.h在一个项目设计中,至少需要有一个汇编源文件或C程序文件,可以有多个汇编文件、多个C程序文件或者C语言和汇编语言混合编程的文件。4.2.2 汇编语句语法1. 汇编语句格式ARM(Thumb)汇编语言的语句格式为:标号 指令或伪指令 ;注释在汇编语言程序设计中,每一条指令的助记符可以全部用大写或全部用小写,但不允许一条指令中大、小写混用。同时,如果一条语句太长,可半该长语句分为若干行来书写,在行的末

23、尾用“”表示下一行与本行为同一条语句。汇编语句的注释用“;”,注释内容由“;”开始到此行结束,注释可以在一行的顶头书写。对于变量的设置、常量的定义,其标识符必须在一行的顶头书写。源程序中允许有空行,适当的插入空行可以提高程序的可读性。汇编语句正确的例子和错误的例子如下:String1 SETS"My string1"Count RN R0USR_STRACK EQU 64START LDR R0,=0x12345 MOV R1,#0LOOP MOV R2,#3错误的例子:START MOV R0,#1 ;标号START没有顶头写(START前有空格)ABC: MOV R1,

24、#2 ;标号ABC后不能带“:”MOV R2,#3 ;MOV指令不允许顶头写(MOV前要有空格)Loop MOV R2,#3 ;指令中有大、小写混合B loop ;无法跳转到loop去(loop与Loop有区别)2. 标号在ARM汇编中,标号代表一个地址,段内标号的地址在汇编时确定,而段外标号的地址在连接时确定,根据标号的生成方式,可以有以下3种方式:1) 基于PC的标号基于PC的标号是位于目标指令前的标号或程序中的数据定义伪指令前的标号,这种标号在汇编时被处理成PC值加上或减去一个数字常量,它常用于跳转指令的目标地址,或代码段中所嵌入的少量数据。2) 基于寄存器的标号基于寄存器的标号通常由M

25、AP和FIELD伪指令定义,也可以用EQU伪指令定义。这种标号在汇编时被处理成寄存器的值加上或减去一个数字常量。它通常用于访问位于数据段中的数据。3) 绝对地址绝对地址是一个32位的数字,它可以寻址的范围是02321,可以直接寻址整个内存空间。3. 常用符号在汇编语言程序设计中,经常使用各种符号代替地址、变量和常量等,以增加程序的可读性。尽管符号的命名由编程者决定,但并不是任意的,必须遵循以下的决定:l 符号由大、小写字母、数字以及下划线组成;l 除局部标号以数字开头外,其他的符号不能以数字开头;l 符号区分大、小写,同名的大、小写符号会被编译器认为是两个不同的符号;l 符号在其作用范围内必须

26、唯一;l 自定义的符号不能与系统的保留子相同;l 符号名不应与指令或伪指令同名。1)程序中的变量程序中的变量是指其值在程序的运行过程中可以改变的量。ARM汇编程序所支持的变量有数字变量、逻辑变量和字符串变量。2) 程序中的常量程序中的常量是指其值在程序的运行过程中不能被改变的量。ARM汇编程序所支持的常量有数字常量、逻辑常量和字符串常量。数字常量一般为32位的整数,其取值范围为2312311。数字常量有3种表示方式:l 十进制数,如12,4,2,4等;l 十六进制数,如0x32,0xFF,0x0等;l n进制数,用n-XXX表示,其中n为为9,XXX为具体的数,如2-0100101,8-432

27、13等。逻辑常量(又叫布尔常量)只有两种取值情况:真TRUE或假FALSE。比如:Isright SETSFALSE字符串常量为一个固定的字符串,一般用于程序运行时的信息提示,比如:Hello SETS"Hello World!"Error SETS"The parameter is error"4. 程序中的变量代换程序中的变量可通过代换操作取得一个常量,代换操作符为“”。如果在数字变量前面有一个代换操作符“”,编译器会将该数字变量的值转换为十六进制的字符串,并将“”后的数字变量用该十六进制的字符串代换。如果在逻辑变量前面有一个代换操作符“”,编译器会

28、将“”后的字符串变量用该字符串变量的值代换。使用示例:GBLS STR1GBLS STR2STR1 SETS“test”STR2 SETS“This is a STR1” ;汇编后,STR2的值为This is a test5. 表达式和运算符在汇编语言程序设计中,也经常使用各种表达式,表达式一般由变量、常量、运算符和括号构成。常用的表达式有数字表达式、逻辑表达式和字符串表达式,其运算次序遵循如下的优先级:l 优先级相同的双目运算符的运算顺序为从左到右;l 相邻的单目运算符的运算顺序为从右到左,且单目运算符的优先级高于其他运算符;l 括号运算符的优先级最高1)数字表达式及运算符数字表达式一般由

29、数字常量、数字变量、数字运算符和括号构成。与数字表达式相关的运算符如下:l “”、“”、“×”、“”及“MOD”算术运算符以上的算术运算任分别代表加、减、乘、除和取余运算。例如,以X和Y表示两个数字表达式,则:XY 表示X与Y的和XY 表示X与Y的差X×Y 表示X与Y的乘积XY 表示X与Y的商X:MOD:Y 表示X除以Y的余数l “ROL”、“ROR”“SHL”及“SHR”移位运算符以X和Y表示两个数字表达式,则:X:ROL:Y 表示将X循环左移Y位X:ROR:Y 表示将X循环右移Y位X:SHL:Y 表示将X左移Y位X:SHR:Y 表示将X右移Y位l “AND”、“OR”、

30、“NOT”及“EOR”按位逻辑运算符以X和Y表示两个数字表达式,则:X:AND:Y 表示将X和Y作逻辑与的操作X:OR:Y 表示将X和Y作逻辑或的操作:NOT:Y 表示将将Y作逻辑非的操作X:EOR:Y 表示将X和Y按位作逻辑异或的操作2) 逻辑表达式及运算符逻辑表达式一般由逻辑量、逻辑运算符和括号构成,其表达式的运算结果为真或假。与逻辑表达式相关的运算符如下:l “=”、“>”、“<”、“>=”、“/=”“<>”运算符以X和Y表示两个逻辑表达式,以上的运算符代表运算如下:X=Y 表示X等于YX>Y 表示X大于YX<Y 表示X小于YX>=Y 表示

31、X大于等于YX<=Y 表示X小于等于YX/=Y 表示X不等于YX<>Y 表示X不等于Yl “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。常用的字符串表达式相关的运算符如下:l LEN运算符LEN运算符返回字的长

32、度(字符数),以X表示字符串表达式,其语法格式如下:LEN:Xl CHR运算符CHR运算符将0255之间的整数转换为一个字符,以M表示某一个整数,其语法格式如下:CHR:Ml STR运算符STR运算符将一个数字表达式或逻辑表达式转换为一个字符串。对于数字表达式,STR运算符将其转换为一个十六进制格式的字符串;对于逻辑表达式,STR运算符将其转换为字符串T或F,其语法格式如下:STR:X其中,X为一个数字表达式或逻辑表达式。l LEFT运算符LEFT运算符返回某个字符串左端的规定长度的一个子串,其语法格式如下:X:LEFT:Y其中,X为源字符串,Y为一个整数,表示要返回的字符个数。l CC运算符

33、CC运算符用于将两个字符串连接成一个字符串,其语法格式如下:X:CC:Y其中,X为源字符串1,Y为源字符串2,CC运算符将Y连接到X的后面。4) 与寄存器和程序计数器(PC)相关的表达式及运算符如下:l BASE运算符BASE运算符返回基于寄存器的表达式中寄存器的编号,其语法格式如下:BASE:X其中,X为与寄存器相关的表达式。l INDEX运算符INDEX运算符返回基于寄存器的表达式中相对于其基址寄存器的偏移量,其语法格式如下:INDEX:X其中,X为与寄存器相关的表达式。55) 其他常用运算符l ?运算符?运算符返回基某代码行所生成的可执行代码的长度,例如:?X返回定义符号X的代码行所生成

34、的可执行代码的字节数。l DEF运算符DEF运算符判断是否定义某个符号,例如:DEF:X如果符号X已经定义,则结果为真,否则为假。4.3 汇编语言程序设计4.3.1 汇编语言的程序结构在ARM(Thumb)汇编语言程序中,以程序段为单位组织代码。段是相对独立的指令或数据序列,具有特定的名称。段可以分为代码段和数据段,代码段的内容为执行代码,数据段存放代码运行时需要用到的数据。一个汇编程序至少应该有一个代码段,当程序较长时,可以分割为多个代码段和数据段,多个段在程序编译外链接时最终形成一个可执行的映象文件。可执行映象文件通常由以下几部分构成:l 一个或多个代码段,代码段的属性为可读/写。l 零个

35、或我个包含初始化数据的数据段,数据段的属性为可读/写。l 零个或我个不包含初始化数据的数据段,数据段的属性为可读/写。链接器系统默认或用户设定的规则,将各个段安排在存储器中的相应位置。因此源程序中段之间的相对位置与可执行的映象文件中段的相对位置一般不会相同。以下是一个汇编语言源程序的基本结构:AREA Init,CODE,READONLYENTRYStartLDR R0,=0x3FF5000LDR R1,0xFFSTR R1,R0LDR R0,=0x3FF5008LDR R1,0x01STR R1,R0END在汇编语言程序中,用AREA伪指令定义一个段,并说明所定义段的相关属性,本例定义一个名

36、为Init的代码段,属性为只读。ENTRY伪指令标识程序的入口点,接下来是指令序列,程序的末尾为END伪指令,该伪指令告诉编译器源文件的结束,每一个汇编程序段都必须有一条END伪指令,指示代码段的结束。4.3.2 汇编语言的子程序调用在ARM汇编语言程序中,子程序的调用一般都是通过BL指令来实现的。在程序中,使用指令“BL子程序名”即可完成子程序的调用。该指令在执行时完成如下操作:将子程序的返回地址存放在链接寄存器LR中,同时将程序计数器PC指向子程序的入口点,当子程序执行完毕返回调用处时,只需要将存放在LR中的返回地址重新复制给程序计数器PC即可。在调用子的同时,也可以完成参数的传递和从子程

37、序返回运算的结果,通常可以使用寄存器R0R3完成。以下是使用BL指令调用子程序的汇编语言程序的基本结构:AREA Init,CODE,READONLYENTRYStartLDR R0,=0x3FF5000LDR R1,0xFFSTR R1,R0LDR R0,=0x3FF5008LDR R1,0x01STR R1,R0BL PRINT_TEXTPRINT_TEXTMOV PC,BLEND4.3.3 宏定义及其作用使用宏定义可以提高程序的可读性,简化程序代码和同步修改。ARM宏定义与标准C语言的#define相似,只在源程序中进行字符的简单替代。宏定义从MACRO伪指令开始,到MEND结束,并可以

38、使用参数。宏首先要定义,然后才能使用。使用时直接书写宏名,并根据对应的宏定义格式设置输入参数或书写桔等。当源程序被汇编时,汇编器将展开每一个宏调用,用宏定义代替程序中的宏调用,并使用实际的参数值取代宏定义时的形参。下面的例子是一个宏调用,程序中定义了一个宏CALL,用于调用子程序,调用时设置所需要调用的子程序名Function及两个入口参数dat1和dat2。由于宏定义体中使用的是MOV指令,所以dat1参数只能为8位的立即数或通用寄存器。MACRO ;宏定义CALLSubfunction Function,dat1,dat2 ;宏名为CALLSubfunction,带3个参数LMPORT F

39、unction ;声明外子程序名MOV R0,dat1 ;设置子程序参数R0=dat1MOV R1,dat2BL Function ;调用子程序MENDCALL FADD1,#3,#2 ;宏调用汇编处理后,宏调用将被展开,程序如下:IMPORT FADD1MOV R0,#3MOV R1,#2BL FADD14.3.4 数据比较跳转汇编程序可以使用CMP指令进行两个数的比较,然后根据比较结果实现程序的跳转,代码如下:CMP R5,#10 BEQ BRANCH1 ;如果R5为10,则跳转到BRANCH1CMP R1,R2ADDHI R1,R1,#1 ;如果R1>R2,则R1=R1+1ADDLS R1,R1,#2 ;如果R1<=R2,则R1=R1+2ANDS R1,R1,#0x80 ;R1=R1&0x80,并设置相应的标志位BNE WAIT ;如果R1的第7位0,则跳转到WAIT4.3.5 循环下面的程序代码为汇编循环程序的例子,指定了循环的次数,每循环一次进行减1操作,并判断结果是否为0,如果为0则退出循环。MOV R0,#10LOOPSUBS R0,R0,#1BEN LOOP4.3. 6 数据块复制可以使用存储器访问指令LDM/STM进行读取和存储,进行数据块的复制,示例代码如下: LDR R0,=DATA_DST ;指向数据的目标地址 LD

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论