《ARM汇编语言程序设计课件.pptx》由会员分享,可在线阅读,更多相关《ARM汇编语言程序设计课件.pptx(114页珍藏版)》请在taowenge.com淘文阁网|工程机械CAD图纸|机械工程制图|CAD装配图下载|SolidWorks_CaTia_CAD_UG_PROE_设计图分享下载上搜索。
1、1 第1章嵌入式系统基础知识第2章ARM技术概述第3章ARM的指令系统第第4章章 ARM汇编语言程序设计汇编语言程序设计第5章ARMRealviewMDK集成开发环境第6章GPIO编程第7章ARM异常中断处理及编程第8章串行通信接口课程安排课程安排:2 第9章存储器接口第10章定时器第11章A/D转换器第12章LCD接口设计第13章温度监测仪开发实例课程安排课程安排:3 4.1ARM汇编器支持的伪操作4.2ARM汇编器支持的伪指令4.3ARM汇编语言的语句格式4.4ARM汇编语言的程序结构4.5汇编语言与C语言的混合编程4.6小结4.7思考与练习本章课程:本章课程:4 4.1.1伪操作概述在A
2、RM汇编语言程序中,有一些特殊指令助记符,这些助记符与指令系统的助记符不同,没有相对应的操作码,通常称这些特殊指令助记符为伪操作标识符(directive)1,它们所完成的操作称为伪操作。伪操作在源程序中的作用是为了完成汇编程序做各种准备工作的,这些伪操作仅在汇编过程中起作用,一旦汇编结束,伪操作的使命就完成。在ARM的汇编程序中,伪操作主要有符号定义伪操作、数据定义伪操作、汇编控制伪操作及其杂项伪操作等。4.1ARM汇编器支持的伪操作5 4.1.2符号定义伪操作符号定义伪操作用于定义ARM汇编程序中的变量、对变量赋值及定义寄存器的别名等操作。常见的符号定义伪操作有如下几种。(1)用于定义全局
3、变量的GBLA、GBLL和GBLS。(2)用于定义局部变量的LCLA、LCLL和LCLS。(3)用于对变量赋值的SETA、SETL和SETS。(4)为通用寄存器列表定义名称的RLIST。4.1ARM汇编器支持的伪操作6 4.1.2符号定义伪操作1全局变量定义伪操作GBLA、GBLL和GBLS(1)语法格式GBLA、GBLL和GBLS伪操作用于定义一个ARM程序中的全局变量并将其初始化。其中:GBLA伪操作用于定义一个全局的数字变量并初始化为0。GBLL伪操作用于定义一个全局的逻辑变量并初始化为F(假)。GBLS伪操作用于定义一个全局的字符串变量并初始化为空。由于以上3条伪指令用于定义全局变量,
4、因此在整个程序范围内变量名必须唯一。语法格式如下:取值为GBLA、GBLL、GBLS三者中的之一定义的全局变量名,在其作用范围内必须唯一。全局变量的作用范围为包含该变量的源程序4.1ARM汇编器支持的伪操作7 全局变量定义伪操作GBLA、GBLL和GBLS(2)使用说明,如果用这些伪操作重新声明已经声明过的变量,变量的值将被初始化成后一次声明语句中的值。(3)示例使用伪操作声明全局变量。GBLATest1;定义一个全局的数字变量,变量名为Test1Test1SETA0 xaa;将该变量赋值为0 xaaGBLLTest2;定义一个全局的逻辑变量,变量名为Test2Test2SETLTRUE;将该
5、变量赋值为真GBLSTest3;定义一个全局的字符串变量,变量名为Test3Test3SETSTesting;将该变量赋值为“Testing”声明变量Objectsize并设置其值为0 xff,为“SPACE”操作做准备。GBLAobjectsizeObjectsizeSETAoxffSPACEobjectsize下面的例子显示如何使用汇编命令设置变量的值。具体做法是使用“pd”选项ArmasmpdobjectsizeSETAoxffoobjectfilesourcefile4.1ARM汇编器支持的伪操作8 4.1.2符号定义伪操作2局部变量定义伪操作LCLA、LCLL和LCLS(1)语法格式
6、LCLA、LCLL和LCLS伪指令用于定义一个ARM程序中的局部变量并将其初始化。其中:LCLA伪操作用于定义一个局部的数字变量并初始化为0。LCLL伪操作用于定义一个局部的逻辑变量并初始化为F(假)LCLS伪操作用于定义一个局部的字符串变量并初始化为空。以上3条伪操作用于声明局部变量,在其作用范围内变量名必须唯一。语法格式如下:取值为LCLA、LCLL、LCLS三者中的之一。所定义的局部变量名,在其作用范围内必须唯一。局部变量作用范围为包含该局部变量的宏。4.1ARM汇编器支持的伪操作9 局部变量定义伪操作LCLA、LCLL和LCLS(2)使用说明,如果用这些伪操作重新声明已经声明过的变量,
7、则变量的值将被初始化成后一次声明语句中的值。(3)示例使用伪操作声明局部变量。LCLATest4;声明一个局部的数字变量,变量名为Test4Test3SETA0 xaa;将该变量赋值为0 xaaLCLLTest5;声明一个局部的逻辑变量,变量名为Test5Test4SETLTRUE;将该变量赋值为真LCLSTest6;定义一个局部的字符串变量,变量名为Test6Test6SETSTesting;将该变量赋值为“Testing”下面的例子定义一个宏,显示了局部变量的作用范围。MACRO;声明一个宏$labelmessage$a;宏原型LCLSerr;声明局部字符串变量$labelINFO0,er
8、r:CC:STR:$aMEND;宏结束,局部变量不再起作用4.1ARM汇编器支持的伪操作10 4.1.2符号定义伪操作3变量赋值伪操作SETA、SETL和SETS(1)语法格式伪指令SETA、SETL和SETS用于给一个已经定义的全局变量或局部变量赋值。SETA伪操作用于给一个数学变量赋值。SETL伪操作用于给一个逻辑变量赋值。SETS伪操作用于给一个字符串变量赋值。语法格式如下:VariableexprVariable变量名为已经定义过的全局变量或局部变量,表达式为将要赋给变量的值。取值为SETA、SETL、SETS三者中的之一。expr数学、逻辑或字符串表达式,也就是将要赋予变量的值。4.
9、1ARM汇编器支持的伪操作11 变量赋值伪操作SETA、SETL和SETS(2)使用说明,在向变量赋值前必须先声明变量。也可以在汇编指令中预定义变量,如:Armasm-pdobjectsizeSETAoxff-oobjectfilesourcefile(3)示例为预先定义的变量赋值。LCLATest3;声明一个局部的数字变量,变量名为Test3Test3SETA0 xaa;将该变量赋值为0 xaaLCLLTest4;声明一个局部的逻辑变量,变量名为Test4Test4SETLTRUE;将该变量赋值为真LCLSTest6;定义一个局部的字符串变量,变量名为Test6Test6SETSTestin
10、g;将该变量赋值为“Testing”使用变量赋值伪操作,定义一些程序相关内容。GBLAversionNumberVersionNumberSETA21GBLLDebugDebugSETLTRUEGBLSversionStringVersionStringSETSversion1.04.1ARM汇编器支持的伪操作12 4.1.2符号定义伪操作4通用寄存器列表定义伪操作RLIST(1)语法格式RLIST伪操作可用于对一个通用寄存器列表定义名称,使用该伪操作定义的名称可在ARM指令LDM/STM中使用。在LDM/STM指令中,列表中的寄存器访问次序根据寄存器的编号由低到高,与列表中的寄存器排列次序无
11、关。语法格式如下:NameRLISTlist-of-registersName寄存器列表的名称。list-of-registers通用寄存器列表。列表中的寄存器用“,”隔开,如果是编号连续的通用寄存器可以用“”指定寄存器范围。具体用法参见程序示例。4.1ARM汇编器支持的伪操作13 通用寄存器列表定义伪操作RLIST(2)使用说明在使用ARM汇编编译器编译源文件时,可以使用“checkreg”选项来指定汇编器进行寄存器检查。如果汇编器检测到寄存器列表中的寄存器编号非升序排列,将给出编译警告。(3)示例将寄存器列表名称定义为RegList,可在ARM指令LDM/STM中通过该名称访问寄存器列表。
12、RegListRLISTR0-R5,R8,R10使用“”在寄存器列表中,指定寄存器范围。ContextRLISTR0-R6,R8,R10-R12,R154.1ARM汇编器支持的伪操作14 4.1.3数据定义(DataDefinition)伪操作数据定义伪操作一般用于为特定的数据分配存储单元,同时可完成已分配存储单元的初始化。常见的数据定义伪操作有如下几种。(1)DCB用于分配一片连续的字节存储单元并用指定的数据初始化(2)DCW(DCWU)用于分配一片连续的半字存储单元并用指定的数据初始化(3)DCD(DCDU)用于分配一片连续的字存储单元并用指定的数据初始化(4)DCFD(DCFDU)用于为
13、双精度的浮点数分配一片连续的字存储单元并用指定的数据初始化(5)DCFS(DCFSU)用于为单精度的浮点数分配一片连续的字存储单元并用指定的数据初始化(6)DCQ(DCQU)用于分配一片以8字节为单位的连续的存储单元并用指定的数据初始化(7)SPACE用于分配一片连续的存储单元(8)MAP用于定义一个结构化的内存表首地址(9)FIELD用于定义一个结构化的内存表的数据域4.1ARM汇编器支持的伪操作15 4.1.3数据定义(DataDefinition)伪操作1DCB(1)语法格式DCB伪操作用于分配一片连续的字节存储单元并用伪指令中指定的表达式初始化。其中,表达式可以为数字或字符串。DCB也
14、可用“=”代替。语法格式如下。labelDCBexpr,exprlabel,程序标号。expr,可以是128255的数字,也可以是字符串。(2)使用说明在使用DCB伪操作时,其后常跟ALIGN伪操作以保证内存地址对齐。(3)示例分配一片连续的字节存储单元并初始化为指定字符串。StrDCBThisisatest!与C中的字符串不同,ARM汇编中的字符串不以null结尾,下面指令以ARM汇编形成一个C语言风格的字符串。C_stringDCBC_string,04.1ARM汇编器支持的伪操作16 4.1.3数据定义(DataDefinition)伪操作2DCW(DCWU)(1)语法格式DCW(或DC
15、WU)伪操作用于分配一片连续的半字存储单元并用伪指令中指定的表达式初始化。其中,表达式可以为程序标号或数字表达式。用DCW分配的字存储单元是半字对齐的,而用DCWU分配的字存储单元并不严格半字对齐。语法格式:labelDCWexpr,exprlabel,程序标号,可选。expr,数字表达式,取值范围为3276865525。(2)使用说明,DCW可能在分配的内存单元前加一个字节以保证内存半字对齐。当程序对内存对齐方式要求不严格时可以是DCWU伪操作。(3)示例分配一片连续的半字存储单元并初始化。DataTestDCW1,2,3在指定内存单元初始值时可以使用已定义的变量。DataDCW-255,2
16、*numberDCWUnumber+44.1ARM汇编器支持的伪操作17 4.1.3数据定义(DataDefinition)伪操作3DCD(DCWU)(1)语法格式,DCD(或DCDU)伪操作用于分配一片连续的字存储单元并用伪指令中指定的表达式初始化。其中,表达式可以为程序标号或数字表达式。DCD也可用“&”代替。用DCDU分配的字存储单元是字对齐的,而用DCDU分配的字存储单元并不严格字对齐。语法格式:labelDCDUexpr,exprlabel,程序标号,可选。expr,expr可以是数字表达式或程序相关表达式(program-relativeexpression)。(2)使用说明,DC
17、D可能在分配的内存单元前加13字节以保证内存字对齐。当程序对内存对齐方式要求不严格时可以是DCDU伪操作。(3)示例分配一片连续的字存储单元并初始化:DataTestDCD4,5,6用程序标号初始化内存单元:DataTestDCDmem06+4在内存单元不能字对齐的情况下,使用DCDU伪操作。AREAMydata,DATA,READWRITEDCB255;字节定义使内存单元不能字对齐Data3DCDU1,5,204.1ARM汇编器支持的伪操作18 4.1.3数据定义(DataDefinition)伪操作4DCFS(或DCFSU)(1)语法格式,DCFS(或DCFSU)伪指令用于为单精度的浮点数
18、分配一片连续的字存储单元并用伪指令中指定的表达式初始化。每个单精度的浮点数占据一个字单元。用DCFS分配的字存储单元是字对齐的,而用DCFSU分配的字存储单元并不严格字对齐。语法格式:labelDCFSUfpliteral,fpliterallabel,程序标号,可选。fpliteral,单精度浮点数(2)使用说明,DCFS可能在分配的内存单元前加13字节以保证内存字对齐。当程序对内存对齐方式要求不严格时可以是DCFSU伪操作。此伪操作使用的单精度浮点数的范围为:1.17549435e383.40282347e+38。(3)示例分配一片连续的字存储单元并初始化为指定的单精度浮点数。FDataT
19、estDCFS2E5,5E7分配一片连续的字存储单元并初始化为单精度浮点数,但不严格要求字对齐。DCFSU1.0,0.1,3.1e64.1ARM汇编器支持的伪操作19 4.1.3数据定义(DataDefinition)伪操作5DCFD(或DCFDU)(1)语法格式DCFD(或DCFDU)伪指令用于为双精度的浮点数分配一片连续的字存储单元并用伪指令中指定的表达式初始化。每个双精度的浮点数占据两个字单元。用DCFD分配的字存储单元是字对齐的,而用DCFDU分配的字存储单元并不严格字对齐。语法格式:labelDCFDUfpliteral,fpliterallabel,程序标号,可选。fplitera
20、l,双精度浮点数。(2)使用说明DCFS可能在分配的内存单元前加13字节以保证内存字对齐。当程序对内存对齐方式要求不严格时可以是DCFSU伪操作。当程序中的浮点数要由ARM处理器进行操作时,用户选择的浮点处理器结构会自动完成字节顺序的转换。当编译时使用了编译选项fpunone,伪操作DCFS(DCFSU)不可使用。此伪操作使用的单精度浮点数的范围为:2.22507385850720138e3081.79769313486231571e+308。(3)示例分配一片连续的字存储单元并初始化为指定的双精度浮点数。FDataTestDCFD2E115,-5E7分配一片连续的字存储单元并初始化为双精度浮
21、点数,但不严格要求字对齐。DCFDU1.0,-0.1,3.1e64.1ARM汇编器支持的伪操作20 4.1.3数据定义(DataDefinition)伪操作6DCQ(或DCQU)(1)语法格式DCQ(或DCQU)伪指令用于分配一片以8个字节为单位的连续存储区域并用伪指令中指定的表达式初始化。用DCQ分配的存储单元是字对齐的,而用DCQU分配的存储单元并不严格字对齐。语法格式:labelDCQU-literal,-literallabel,程序标号,可选。literal,用于初始化内存的数字必须是可数的数字表达式,其取值范围为02641。可以在数字表达式前加负号来表示用负数初始化内存单元,但此时
22、数字表达式的取值范围为2631。(2)使用说明DCQ可能在分配的内存单元前加13字节以保证内存字对齐。当程序对内存对齐方式要求不严格时可以是DCQU伪操作。(3)示例分配一片连续的存储单元并初始化为指定的值。DataTestDCQ100使用标号定义内存单元:ECQUnumber+44.1ARM汇编器支持的伪操作21 4.1.3数据定义(DataDefinition)伪操作7SPACE(1)语法格式SPACE伪指令用于分配一片连续的存储区域并初始化为0。其中,表达式为要分配的字节数。SPACE也可用“%”代替。语法格式:labelSPACEexprlabel,程序标号,可选。expr,分配的字节
23、数。(2)使用说明SPACE伪操作常和ALIGN一起使用,详见ALIGN伪操作。(3)示例分配连续100字节的存储单元并初始化为0。DataSpaceSPACE100在Mydata段的开始可以是255个初始化为0的字节单元。AREAMydata,DATA,READWRITEdata1SPACE2554.1ARM汇编器支持的伪操作22 4.1.3数据定义(DataDefinition)伪操作8MAP(1)语法格式MAP伪操作用于定义一个结构化的内存表的首地址。MAP也可用“”代替。表达式可以为程序中的标号或数学表达式,基址寄存器为可选项,当基址寄存器选项不存在时,表达式的值即为内存表的首地址,当
24、该选项存在时,内存表的首地址为表达式的值与基址寄存器的和。MAP伪操作通常与FIELD伪操作配合使用来定义结构化的内存表。语法格式:MAPexpr,base-registerexpr,如果基地址寄存器(base-register)没有指定,expr表达式存储到结构化内存表首地址。如果表达式expr是“程序相关的(program-relative)”,则程序标号在使用前必须定义。base-register,指定一个寄存器。当指令中包含这一项时,结构化内存表的首地址为expr和base-register寄存器值的和。(2)使用说明MAP伪指令通常与FIELD伪指令配合使用来定义结构化的内存表。当基
25、地址寄存器(base-register)一旦被指定,下面所有的FIELD伪操作全部以基地址为基础增加偏移量。(3)示例定义结构化内存表首地址的值为0 x100+R0:MAP0 x100,R0不存在基地址寄存器,结构化内存表的首地址直接由表达式定义:MAP04.1ARM汇编器支持的伪操作23 4.1.3数据定义(DataDefinition)伪操作9FILED(1)语法格式FIELD伪操作用于定义一个结构化内存表中的数据域。FILED也可用“#”代替。表达式的值为当前数据域在内存表中所占的字节数。FIELD伪操作常与MAP伪操作配合使用来定义结构化的内存表。MAP伪操作定义内存表的首地址,FIE
26、LD伪操作定义内存表中的各个数据域,并可以为每个数据域指定一个标号供其他的操作引用。语法格式:labelFIELDexprlabel,程序标号,可选。当指令中存在这一项时,label的值为当前内存表的位置计数器VAR的值。汇编器处理完这条FIELD指令后,内存表计数器的值将加上expr的值。expr,FIELD指定的域所占内存单元字节数。4.1ARM汇编器支持的伪操作24 4.1.3数据定义(DataDefinition)伪操作(2)使用说明MAP伪操作中的基地址寄存器(base-register)一旦指定,将被其后的所有FIELD伪操作定义的数据域默认使用,指定遇到下一个包含基地址寄存器(b
27、ase-register)的MAP指令。另外在操作中定义的标号可以被LOAD/STORE指令直接引用。(3)示例下面的例子定义了一个内存表,其首地址为固定地址0 x100。该结构化内存表包含3个域:A的长度为16个字节,位置为0 x100;B的长度为32个字节,位置为0 x110;S的长度为256个字节,位置为0 x130。MAP0 x100;定义结构化内存表首地址的值为0 x100。AFIELD16;定义A的长度为16字节,位置为0 x100BFIELD32;定义B的长度为32字节,位置为0 x110SFIELD256;定义S的长度为256字节,位置为0 x130下面的例子显示了一个寄存器相
28、关的首地址定义结构化内存表。MAP0,R9;将结构化内存表的首地址设为R9的值FIELD4LABFIELD4LDRr0,LAB最后的LDR指令,相当于:LDRR0,R9,#44.1ARM汇编器支持的伪操作25 4.1.4汇编控制伪操作汇编控制伪操作用于控制汇编程序的执行流程,常用的汇编控制伪操作包括以下几条。(1)IF、ELSE、ENDIF。(2)WHILE、WEND。(3)MACRO、MEND。(4)MEXIT。4.1ARM汇编器支持的伪操作26 4.1.4汇编控制伪操作汇编控制伪操作用于控制汇编程序的执行流程,常用的汇编控制伪操作包括以下几条。(1)IF、ELSE、ENDIF。(2)WHI
29、LE、WEND。(3)MACRO、MEND。(4)MEXIT。4.1ARM汇编器支持的伪操作27 4.1.4汇编控制伪操作1IF、ELSE、ENDIF(1)语法格式IF、ELSE、ENDIF伪操作能根据条件的成立与否决定是否执行某个指令序列。当IF后面的逻辑表达式为真,则执行IF后的指令序列,否则执行ELSE后的指令序列。其中,ELSE及其后指令序列可以没有,此时,当IF后面的逻辑表达式为真,则执行指令序列,否则继续执行后面的指令。IF、ELSE、ENDIF伪指令可以嵌套使用。语法格式如下:IFlogical-expressingELSEENDIFlogical-expression:用于决定
30、指令执行流程的逻辑表达式。4.1ARM汇编器支持的伪操作28 4.1.4汇编控制伪操作(2)使用说明当程序中有一段指令需要在满足一定条件时执行,使用该指令。该操作还有另一种形式。IFlogical-expressionInstructionELIFlogical-expression2InstructionsELIFlogical-expression3InstructionsENDIFELIF形式避免了IF-ELSE形式的嵌套,使程序结构更加清晰、易读。(3)示例IFCONFIG=16BNE_rt_udiv_1;LDRR0,=_rt_div0;BXR0;ELSEBEQ_rt_div();EN
31、DIF4.1ARM汇编器支持的伪操作29 4.1.4汇编控制伪操作2WHILE、WEND(1)语法格式WHILElogical-expressioncodeWENDlogical-expression:用于决定指令执行流程的逻辑表达式。(2)使用说明WHILE、WEND指令形式在进入循环之前判断执行条件,如果在第一次进入循环时,逻辑表达式即为“假”,循环体可以不执行。(3)示例下面的例子用count来控制循环体执行次数。CountSETA1;WHILEcount1”,对汇编器来说取值为“假(FLASE)”。逻辑常量只有两种取值情况,真或假。字符串常量为一个固定的字符串,一般用于程序运行时的信息
32、提示。4.3ARM汇编语言的语句格式60 4.3.1ARM汇编语言中的符号3程序中的变量代换汇编语言中的变量可以作为作为一整行出现在汇编程序中,也可以作为行的一部分使用。如果在数字变量前面有一个代换操作符“$”,编译器会将该数字变量的值转换为十六进制的字符串,并将该十六进制的字符串代换“$”后的数字变量。如果在逻辑变量前面有一个代换操作符“$”,编译器会将该逻辑变量代换为它的取值(真或假)。如果在字符串变量前面有一个代换操作符“$”,编译器会将该字符串变量的值代换“$”后的字符串变量。如果程序中需要字符“$”,则可以用“$”来表示。汇编器将不进行变量替换,而是将“$”作为“$”。4.3ARM汇
33、编语言的语句格式61 下面的两个例子说明了变量替换的过程。;直接的变量替换GBLSadd4ff;add4ffSETSADDr4,r4,#0 xFF;给变量add4ff赋值$add4ff.00;引用变量;codesADDr4,r4,#0 xFF00;有特殊符号的变量替换GBLSs1GBLSs2GBLSfixupGBLAcount;countSETA14s1SETSa$b$count;s1=a$b0000000Es2SETSabcfixupSETS|xy$s2.z|;fixup=|xyabcz|C$code|MOVr4,#16;label=C$code4.3ARM汇编语言的语句格式62 4.3.1
34、ARM汇编语言中的符号4程序标号(label)在ARM汇编中,标号代表一个地址,段内标号的地址在汇编时确定,而段外标号地址值在链接时确定。根据标号的生成方式,程序标号分为以下三种。程序相关标号(Program-relativelabels)。寄存器相关标号(Register-relativelabels)。绝对地址(Absoluteaddress)。(1)程序相关标号程序相关标号指位于目标指令前的标号或程序中的数据定义伪操作前的标号。这种标号在汇编时将被处理成PC值加上或减去一个数字常量。它常用于表示跳转指令的目标地址或代码段中所嵌入的少量数据。(2)寄存器相关地址这种标号在汇编时将被处理成寄
35、存器的值加上或减去一个数字常量。它常被用于访问数据段中的数据。这种基于寄存器的标号通常用MAP和FIELD伪操作定义,也可以用EQU伪操作定义。(3)绝对地址绝对地址是一个32位的数字量,使用它可以直接寻址整个内存空间。4.3ARM汇编语言的语句格式63 4.3.1ARM汇编语言中的符号5局部标号局部标号是一个099之间的十进制数字,可重复定义。局部标号后面可以紧接一个通常表示该局部变量作用范围的符号。局部变量的作用范围为当前段,也可以用伪操作ROUT来定义局部标号的作用范围。局部标号在子程序或程序循环中常被用到,也可以配合宏定义伪操作(MACRO和MEND)来使程序结构更加合理。在同一个段中
36、,可以使用相同的数字命名不同的局部变量。默认情况下,汇编器会寻址最近的变量。也可以通过汇编器命令选项来改变搜索顺序。局部变量命名语法:nroutname局部变量引用的语法格式:%F|BA|Tnroutname其中,routname为变量作用范围名称;%表示引用操作;F指示汇编器只向前搜索;B指示汇编器只向后搜索;A指示汇编器搜索所有宏的嵌套。T指示汇编器只搜索宏的当前层。如果在引用过程中,没有指定F和B,则汇编器先向后搜索,再向前搜索。如果A和T没有指定,汇编器搜索所有从当前层次到宏最高层次,比当前层次低的层次不再搜索。如果指定了routname,汇编器向前搜索最近的ROUT操作,若routn
37、ame与该ROUT伪操作定义的名称不匹配,汇编器报告错误并结束汇编。4.3ARM汇编语言的语句格式64 4.3.2ARM汇编语言中的表达式和运算符在汇编语言程序设计中经常使用各种表达式,表达式一般由变量、常量、运算符和括号构成。常用的表达式有数字表达式、逻辑表达式和字符串表达式。1字符串表达式字符串表达式一般由字符串常量、字符串变量、运算符和括号构成。字符串由包含在双引号内的一系列字符组成。编译器所支持的字符串最大长度为512字节。当在字符串中包含“$”或引号时,可以用“$”表示“$”,用两个双引号表示一个双引号。例如:abcSETSonedoublequotedefSETSone$dolla
38、rsymbol上面的例子分别将字符串abc和def赋值为“onedoublequote”和“one$dollarsymbol”。4.3ARM汇编语言的语句格式65 4.3.2ARM汇编语言中的表达式和运算符字符串可以通过SETA、SETL、SETS伪操作对其赋值。常用的与字符串表达式相关的运算符如下。LEN:计算字符串长度运算符。CHR:ASCII码转换运算符。STR:字符串转换运算符。LEFT:字符串取左运算符。RIGHT:字符串取右运算符。CC:字符串连接运算符。详见后面操作符一节。下面的例子说明了如何使用字符串操作符给字符串变量赋值。improbSETSliteral:CC:(abc:L
39、EFT:4)这个例子将字符串赋值为“literaluote”。4.3ARM汇编语言的语句格式66 4.3.2ARM汇编语言中的表达式和运算符、2整数表达式整数表达式一般由数字常量、数字变量、数字运算符和括号构成整数表示式可以包含寄存器相关(register-relative)或程序相关(program-relative)表达式,这些表达式在编译时被汇编器翻译为地址无关数字常量。整数表达式一般被计算为32位的整数,当此整数被定义为无符号数时,其取值范围为0232-1,当被定义为有符号数时,其取值范围为-231231-1。汇编器认为-n和232-n是相等的。对于关系操作,如比较两个数的大小,汇编器
40、将其操作数看作无符号的数,也就是说“0-1”对汇编器来说取值为“假(FLASE)”。下面的例子说明了在程序中,如何对整数表达式进行操作。aSETA256*256;将数字变量赋值为256*256MOVr1,#(a*22);将数字表达式(a*22)的值放入r14.3ARM汇编语言的语句格式67 4.3.2ARM汇编语言中的表达式和运算符汇编语言中,整数数字量有以下几种形式。十进制数(decimal-digis)“0 x”+十六进制数(0 xhexadecimal-digits)“&”+十六进制数(&hexadecimal-digits)n进制数(n_base-n-digits)字符(charact
41、er)其中,十进制数(decimal-digis)可以是“0”到“9”数字的任意组合;十六进制数(hexadecimal-digits)可以是“0”到“9”数字和字母“A”到“F”的任意组合;“n_”可以取2到9,“base-n-digits”是在n进制下合法的任意数值;字符(character)可以是除单引号以外的所有字符。下面的例子说明了整数表达式的基本用法。aSETA34906addrDCD0 xA10ELDRr4,=&1000000FDCD2_11001010c3SETA8_74007DCQ0 x0123456789abcdefLDRr1,=A;ARM伪指令将整数65(A的ASCII码
42、)存入寄存器ADDr3,r2,#;将整数39(字符“/”的ASCII码)加到r2,结果存入r34.3ARM汇编语言的语句格式68 4.3.2ARM汇编语言中的表达式和运算符3浮点数字量表达式浮点数字量有以下几种形式。-digitsE-digits。-digits.digitsE-digits。0 xhexdigits。&hexdigits。其中,digits为十进制数,要在其后加上字母E(大写或小写)来表示其指数;hexdigits为十六进制数。单精度浮点数的表示范围为1.17549435e383.40282347e+38;双精度浮点数的表示范围为2.22507385850720138e-30
43、81.79769313486231571e+308。下面的例子说明了浮点数据量的基本用法。DCFD1E308,-4E-100DCFS1.0DCFD3.725e15LDFS0 x7FC00000;LDFD&FFF0000000000000;4.3ARM汇编语言的语句格式69 4.3.2ARM汇编语言中的表达式和运算符4逻辑表达式逻辑表达式一般由逻辑量、逻辑运算符和括号构成,其表达式的运算结果为真或假。与逻辑表达式相关的运算符有“=”、“”、“=”、“=”、“/=”、“”运算符和“LAND”、“LOR”、“LNOT”及“LEOR”运算符。4.3ARM汇编语言的语句格式70 4.3.2ARM汇编语言
44、中的表达式和运算符5程序或寄存器相关表达式寄存器相关表达式的值等于指定寄存器的值加上或减去一个数字表达式。程序相关表达式的值等于程序计数器PC的值加上或减去一个数字表达式的值。此种表达式通常由程序中的标号与一个数字表达式组成。下面的例子说明了程序或寄存器相关表达式的基本使用方法。LDRr4,=data+4*n;n是汇编时取值变量;codeMOVpc,lrdataDCDvalue0;n-1个DCD伪操作DCDvaluen;data+4*n指向此;更多DCD伪操作4.3ARM汇编语言的语句格式71 4.3.2ARM汇编语言中的表达式和运算符6汇编中的操作符(1)操作符的优先级在汇编语言程序设计中,
45、表达式包含一个扩展的操作符集,这些操作符和高级语言中的运算符十分接近。其运算次序遵循如下的优先级。优先级相同的双目运算符的运算顺序为从左到右。相邻的单目运算符的运算顺序为从右到左,单目运算符的优先级高于其他运算符。括号运算符的优先级最高。汇编语法的操作符优先级和C语言中的不完全相同。例如在汇编中,下面的汇编语言(1+2SHR3)相当于(1+(2SHR3),而在C语言中,运算则变为(1+2)3)=0。类似于这样的操作,在使用时要特别注意。为了保证表达式运算结果的正确,建议使用为了保证表达式运算结果的正确,建议使用“()()”来避免异义。来避免异义。4.3ARM汇编语言的语句格式72 4.3.2A
46、RM汇编语言中的表达式和运算符汇编操作符的优先级以及对应的C语言运算符上表是按操作符的优先级从上到下排列的。4.3ARM汇编语言的语句格式73 4.3.2ARM汇编语言中的表达式和运算符(2)单目运算,最高优先级的单目运算在表达式中最先被计算。单目操作符写在操作数的前面。运算顺序为从右到左。4.3ARM汇编语言的语句格式74 4.3.2ARM汇编语言中的表达式和运算符(3)双目运算,ARM汇编中将双目运算符放在两个操作数中间。一般情况下,双目运算的优先级低于单目运算。下面将以操作符的优先级为序分别介绍各操作符。乘法相关操作符包括乘、除、取模运算,在双目运算中具有最高优先级字符串相关操作符移位操
47、作符。移位操作中两个操作数均为数字表达式4.3ARM汇编语言的语句格式75 4.3.2ARM汇编语言中的表达式和运算符加减运算操作符关系操作符逻辑操作符4.3ARM汇编语言的语句格式76 4.3.3ARM汇编语言内置的变量ARM汇编器中定义了一些内置变量,这些内置变量不能使用伪指令设置(如,SETA、SETL、SETS等),一般用于程序的条件汇编控制。下面的例子显示了如何使用内置变量控制程序的执行流程。IfCONFIG=16;若为Thumb代码则执行If后的语句;codeselse;codesendifb;程序结束4.3ARM汇编语言的语句格式77 下面介绍由ARM汇编器预定义的内置变量。AR
48、CHITECTURE:选定的ARM体系结构的值,如3,3M,4,4TAREANAME:当前段名。ARMASM_VERSION:ARM编译器ARMASM的变量号。|ads$version|:ARM编译器ARMASM的变量号,同ARMASM_VERSION。CODESIZE:如果当前指令为ARM指令,该内置变量取值为32,如果当前指令为Thumb指令,该内置变量取值为16,同CONFIG。COMMANDLINE:当前命令行内容。CONFIG:如果当前指令为ARM指令,该内置变量取值为32,如果当前指令为Thumb指令,该内置变量取值为16,同CODESIZE。CPU:所使用的CPU名称。默认为AR
49、M7TDMI。如果在编译命令行中使用“-CPU”选项确定CPU类型,则该值为“GenericARM”。ENDIAN:如果编译器在大端模式下,其值为“big”;如果在小端模式下,其值为“little”。FPIC:默认为FALSE,如果设置了“/fpic”选项,其值为TRUE4.3ARM汇编语言的语句格式78 FPU:所选fpu协处理器的名字。默认为“softVFP”。INPUTFILE:当前源文件名。INTER:默认为FALSE,如果设置了“/inter”选项,其值为TRUE。LINENUM:目前源文件行号。NOSWST:默认为FALSE,如果设置了“/noswst”选项,其值为TRUE。OPT
50、:保存当前设置的列表选项。伪操作OPT用来保存当前列表选项,改变选项值,或恢复原始值。PC或“.”:当前程序地址值。PCSTOREOFFSET:指令STRpc,.和STMRb,.,pc与存储的PC值之间的偏移量。ROPI:默认为FALSE,如果设置了“/ropi”选项,其值为TRUERWPI:默认为FALSE,如果设置了“/rwpi”选项,其值为TRUE。SWST:默认为FALSE,如果设置了“/swst”选项,其值为TRUE。VAR或:存储区位置寄存器的当前值。4.3ARM汇编语言的语句格式79 4.4.1汇编语言的程序格式在ARM(Thumb)汇编语言程序中以程序段为单位组织代码。段是相对