1、第第4章章 ARM嵌入式系统程序设计及调试基础嵌入式系统程序设计及调试基础14.1 ARM嵌入式汇编语言程序设计基础嵌入式汇编语言程序设计基础 4.2 ARM嵌入式嵌入式C语言程序设计基础语言程序设计基础 4.3 ARM汇编语言与汇编语言与C/C+的混合编程的混合编程4.4 ARM ADS集成开发环境的使用集成开发环境的使用 4.5 Embest IDE集成开发环境的使用集成开发环境的使用 第第4章章 ARM嵌入式系统程序设计及调试基础嵌入式系统程序设计及调试基础2 在在ARM汇编语言程序里,有一些特殊指令助记符,这汇编语言程序里,有一些特殊指令助记符,这些助记符与指令系统的助记符不同,没有相
2、应的操作码,些助记符与指令系统的助记符不同,没有相应的操作码,通常称这些特殊指令助记符为伪指令,他们所完成的操作通常称这些特殊指令助记符为伪指令,他们所完成的操作称为伪操作。伪指令在源程序中的作用是为完成汇编语言称为伪操作。伪指令在源程序中的作用是为完成汇编语言程序作各种准备工作的,这些伪指令仅在汇编过程起作用,程序作各种准备工作的,这些伪指令仅在汇编过程起作用,一旦汇编结束,伪指令的使命就完成。一旦汇编结束,伪指令的使命就完成。 在在ARM得汇编程序中,有符号定义(得汇编程序中,有符号定义(Symbol Defintion)伪指令,数据定义(伪指令,数据定义(Data Definition)
3、伪指令,地址读取伪)伪指令,地址读取伪指令,汇编控制(指令,汇编控制(Assembly Control)伪指令,宏指令以及)伪指令,宏指令以及其它伪指令。其它伪指令。41 ARM嵌入式汇编语言程序设计基础嵌入式汇编语言程序设计基础411 ARM汇编器支持的伪指令汇编器支持的伪指令第第4章章 ARM嵌入式系统程序设计及调试基础嵌入式系统程序设计及调试基础3 1符号定义伪指令符号定义伪指令 1)GBLA、GBLL和和GBLS 格式:格式:GBLA(GBLL或或GBLS) 全局变量名全局变量名 用途:定义一个用途:定义一个ARM程序中的全局变量,并将其初始化。其程序中的全局变量,并将其初始化。其中中
4、GBLA伪指令用于定义一个全局的数字变量,并初始化为伪指令用于定义一个全局的数字变量,并初始化为0;GBLL伪指令用于定义一个全局的逻辑变量,并初始化为伪指令用于定义一个全局的逻辑变量,并初始化为F(假);(假);GBLS伪指令用于定义一个全局的字符串变量,并初始化为空。伪指令用于定义一个全局的字符串变量,并初始化为空。 由于以上由于以上3条伪指令用于定义全局变量,因此在整个程序范围条伪指令用于定义全局变量,因此在整个程序范围内变量名必须唯一。例如:内变量名必须唯一。例如: GBLA Test1 ;定义一个全局的数字变量,变量名为;定义一个全局的数字变量,变量名为Test1Test1 SETA
5、 0 xAA ;将该变量赋值为;将该变量赋值为0 xAAGBLL Test2 ;定义一个全局的逻辑变量,变量名为;定义一个全局的逻辑变量,变量名为Test2Test2 SETL TRUE ;将该变量赋值为真;将该变量赋值为真GBLS Test3 ;定义一个全局的字符串变量,变量名为;定义一个全局的字符串变量,变量名为 Test3Test3 SETS “Testing” ;将该变量赋值为;将该变量赋值为“Testing”第第4章章 ARM嵌入式系统程序设计及调试基础嵌入式系统程序设计及调试基础4 2)LCLA、LCLL、LCLS 格式:格式:LCLA(LCLL或或LCLS)局部变量名)局部变量名
6、 用途:定义一个用途:定义一个ARM程序中的局部变量,并将其初始化。其中程序中的局部变量,并将其初始化。其中LCLA伪指令用于定义一个局部的数字变量,并初始化为伪指令用于定义一个局部的数字变量,并初始化为0;LCLL伪指令用于定义一个局部的逻辑变量,并初始化为伪指令用于定义一个局部的逻辑变量,并初始化为F(假);(假);LCLS伪指令用于一个局部的字符串变量,并初始化为空。伪指令用于一个局部的字符串变量,并初始化为空。 由于以上由于以上3条伪指令用于声明局部变量,因此在其作用范围内变条伪指令用于声明局部变量,因此在其作用范围内变量名必须唯一。例如:量名必须唯一。例如:LCLA Test4 ;声
7、明一个局部得数字变量,变量名为;声明一个局部得数字变量,变量名为Test4Test4 SETA 0 xAA ;将该变量赋值为;将该变量赋值为0 xAALCLL Test5 ;声明一个局部的逻辑变量,变量名为;声明一个局部的逻辑变量,变量名为Test5Test5 SETL TURE ;将该变量赋值为真;将该变量赋值为真LCLS Test6 ;定义一个局部的字符串变量,变量名为;定义一个局部的字符串变量,变量名为Test6Test6 SETS “Testing” ;将该变量赋值为;将该变量赋值为“Testing”第第4章章 ARM嵌入式系统程序设计及调试基础嵌入式系统程序设计及调试基础5 3)SE
8、TA、SETL、SETS 格式:变量名格式:变量名 SETA(SETL或或SETS) 表达式表达式 用途:给一个已经定义的全局变量或局部变量赋值。用途:给一个已经定义的全局变量或局部变量赋值。 其中变量名为已经定义过的全局变量或局部变量,表达式为将其中变量名为已经定义过的全局变量或局部变量,表达式为将要赋值给变量的值。要赋值给变量的值。SETA伪指令用于给一个数学变量赋值;伪指令用于给一个数学变量赋值;SETL伪指令用于给一个逻辑变量赋值;伪指令用于给一个逻辑变量赋值;SETS伪指令用于给一个伪指令用于给一个字符串变量赋值。例如:字符串变量赋值。例如:LCLA Test3 ;声明一个局部的数字
9、变量,变量名为;声明一个局部的数字变量,变量名为Test3Test3 SETA 0 xAA ;将该变量赋值为;将该变量赋值为0 xAA LCLL Test4 ;声明一个局部的逻辑变量,变量名为;声明一个局部的逻辑变量,变量名为Test5Test4 SETL TRUE ;将该变量赋值为真;将该变量赋值为真第第4章章 ARM嵌入式系统程序设计及调试基础嵌入式系统程序设计及调试基础6 4)RLIST 格式:名称格式:名称 RLIST寄存器列表寄存器列表 用途:对一个通用寄存器列表定义名称,使用该伪指令定用途:对一个通用寄存器列表定义名称,使用该伪指令定义的名称可在义的名称可在ARM指令指令LDM/S
10、TM中使用。在中使用。在LDM/STM指令指令中,列表中的寄存器访问次序为根据寄存器的标号由低到高,中,列表中的寄存器访问次序为根据寄存器的标号由低到高,而与列表中得寄存器排列次序无关。例如:而与列表中得寄存器排列次序无关。例如: RegList RLIST R0R5,R8,R10 ;将寄存器列表;将寄存器列表名称定义为名称定义为RegList,可在,可在ARM指令指令LDM/STM中通过该名称中通过该名称访问寄存器列表。访问寄存器列表。第第4章章 ARM嵌入式系统程序设计及调试基础嵌入式系统程序设计及调试基础7 2数据定义伪指令数据定义伪指令 1)DCB 格式:标号格式:标号 DCB 表达式
11、表达式 用途:分配一片连续的字节存储单元并用伪指令中的表达式初用途:分配一片连续的字节存储单元并用伪指令中的表达式初始化。其中,表达式可以为始化。其中,表达式可以为0255的数字或字符串。的数字或字符串。DCB伪指令也可伪指令也可用用“=”代替。例如:代替。例如: Str DCB “This is a test!” ;分配一片连续的字节存储单元并初;分配一片连续的字节存储单元并初始化始化 2)DCW(或(或DCWU) 格式:标号格式:标号 DCW(或(或DCWU)伪指令)伪指令 用途:分配一片连续的半字节存储单元,并用伪指令中指定的用途:分配一片连续的半字节存储单元,并用伪指令中指定的表达式初
12、始化。其中,表达式可以为程序标号或数字表达式。表达式初始化。其中,表达式可以为程序标号或数字表达式。DCW伪指令和伪指令和DCWU伪指令的区别仅在于用伪指令的区别仅在于用DCW伪指令分配的字存储单伪指令分配的字存储单元是半字对齐,而用元是半字对齐,而用DCWU伪指令分配的字存储单元并不严格半字伪指令分配的字存储单元并不严格半字对齐。例如:对齐。例如: DataTest DCW 1,2,3 ;分配一片连续的半字存储单元并初;分配一片连续的半字存储单元并初始化始化第第4章章 ARM嵌入式系统程序设计及调试基础嵌入式系统程序设计及调试基础8 3)DCD(或(或DCDU) 格式:标号格式:标号 DCD
13、(或(或DCDU) 表达式表达式 用途:分配一片连续的字存储单元并用伪指令指定的表达式初用途:分配一片连续的字存储单元并用伪指令指定的表达式初始化。其中,表达式可以为程序标号或数字表达式。始化。其中,表达式可以为程序标号或数字表达式。DCD伪指令伪指令也可用也可用“&”代替。代替。DCD伪指令和伪指令和DCDU伪指令的区别仅在于用伪指令的区别仅在于用DCD伪指令分配的字存储单元是字对齐的,而用伪指令分配的字存储单元是字对齐的,而用DCDU伪指令分配伪指令分配的字存储单元并不严格字对齐。例如:的字存储单元并不严格字对齐。例如: FdataTest DCD 4,5,6 ;分配一片连续的字存储单元并
14、初;分配一片连续的字存储单元并初始化始化 4)DCFD(或(或DCFDU) 格式:标号格式:标号 DCFD(或(或DCFDU) 表达式表达式 用途:为双精度的浮点数分配一片连续的字存储单元并用伪指用途:为双精度的浮点数分配一片连续的字存储单元并用伪指令中指定得表达式初始化。每个双精度的浮点数占据令中指定得表达式初始化。每个双精度的浮点数占据2个字单元。个字单元。DCFD伪指令和伪指令和DCFDU伪指令的区别仅在于用伪指令的区别仅在于用DCFD伪指令分配的伪指令分配的字存储单元是字对齐的,而用字存储单元是字对齐的,而用DCFDU伪指令分配的字存储单元并伪指令分配的字存储单元并不严格对齐。例如:不
15、严格对齐。例如: FdataTest DCFD 2E115,-5E7 ;分配一片连续的字存储单元;分配一片连续的字存储单元并初始化为指定的双精度数并初始化为指定的双精度数第第4章章 ARM嵌入式系统程序设计及调试基础嵌入式系统程序设计及调试基础9 5)DCFS(或(或DCFSU) 格式:标号格式:标号 DCFS(或(或DCFDU) 表达式表达式 用途:为单精度得浮点数分配一片连续的字存储单元并用伪指用途:为单精度得浮点数分配一片连续的字存储单元并用伪指令中指定的表达式初始化。每个单精度的浮点数占据令中指定的表达式初始化。每个单精度的浮点数占据1个字单元。个字单元。DCFS伪指令和伪指令和DCF
16、SU伪指令的区别仅在于用伪指令的区别仅在于用DCFS伪指令分配的字伪指令分配的字存储单元是字对齐的,而用存储单元是字对齐的,而用DCFSU伪指令分配的字存储单元并不严伪指令分配的字存储单元并不严格字对齐。例如:格字对齐。例如: FDataTEST DCFS 2E5,-5E-7 ;分配一片连续的字存储单;分配一片连续的字存储单元并初始化为指定的单精度数元并初始化为指定的单精度数 6)DCQ(或(或DCQU) 格式:标号格式:标号 DCQ(或(或DCQU) 表达式表达式 用途:分配一片以用途:分配一片以8个字节为单位的连续存储区域并用伪指令中个字节为单位的连续存储区域并用伪指令中指定的表达式初始化
17、。指定的表达式初始化。DCQ伪指令和伪指令和DCQU伪指令的区别仅在于用伪指令的区别仅在于用DCQ伪指令分配的存储单元是字对齐的,而用伪指令分配的存储单元是字对齐的,而用DCQU伪指令分配的伪指令分配的存储单元并不严格字对齐。例如:存储单元并不严格字对齐。例如: DataTest DCQ 100 ;分配一片连续的字存储单元并初始化;分配一片连续的字存储单元并初始化为指定的值为指定的值第第4章章 ARM嵌入式系统程序设计及调试基础嵌入式系统程序设计及调试基础10 7)SPACE 格式:标号格式:标号 SPACE 表达式表达式 用途:用途:SPACE伪指令用于分配伪指令用于分配1片连续的存储区域并
18、初始化为片连续的存储区域并初始化为0。其中,表达式为要分配的字节数。其中,表达式为要分配的字节数。SPACE也可用也可用“%”代替。例如:代替。例如:DataSpace SPACE 100 ;分配连续;分配连续100字节的存储单元并初始化字节的存储单元并初始化为为0 8)MAP 格式:格式:MAP 表达式表达式,基址寄存器,基址寄存器 用途:定义结构化的内存表的首地址。用途:定义结构化的内存表的首地址。MAP伪指令也可用伪指令也可用“”代替。表达式可以为程序中的标号或数学表达式,基址寄存器为可代替。表达式可以为程序中的标号或数学表达式,基址寄存器为可选项,当基址寄存器选项不存在时,表达式的值即
19、是内存表的首地选项,当基址寄存器选项不存在时,表达式的值即是内存表的首地址,当该选项存在时,内存表的首地址为表达式的值与基址寄存器址,当该选项存在时,内存表的首地址为表达式的值与基址寄存器的和。的和。 MAP伪指令仅用于定义数据结构,并不实际分配存储单元,通伪指令仅用于定义数据结构,并不实际分配存储单元,通常可与常可与FIELD伪指令配合使用来定义结构化的内存表。例如:伪指令配合使用来定义结构化的内存表。例如:MAP 0 x100,R0 ;定义结构化的内存表的首地址的值位;定义结构化的内存表的首地址的值位0 x100+R0第第4章章 ARM嵌入式系统程序设计及调试基础嵌入式系统程序设计及调试基
20、础11 9)FILED 格式:标号格式:标号 FIELD 表达式表达式 用途:定义一个结构化内存表中的数据域,其中,表达式的用途:定义一个结构化内存表中的数据域,其中,表达式的值为当前数据域在内存表中所占的字节数。值为当前数据域在内存表中所占的字节数。FIELD伪指令也可用伪指令也可用“#”代替。代替。 与与MAP伪指令相同,伪指令相同,FIELD伪指令仅用于定义数据结构,并伪指令仅用于定义数据结构,并不实际分配存储单元。不实际分配存储单元。FIELD伪指令常与伪指令常与MAP伪指令配合使用来伪指令配合使用来定义结构化的内存表。定义结构化的内存表。MAP伪指令定义内存表的首地址,伪指令定义内存
21、表的首地址,FIELD伪指令定义内存表中的各个数据域,并可以为每个数据指定一个伪指令定义内存表中的各个数据域,并可以为每个数据指定一个标号供其他的指令引用。标号供其他的指令引用。 例如:例如: MAP 0 x100 ;定义结构化内存表首地址的值为;定义结构化内存表首地址的值为0 x100 A FIELD 16 ;定义;定义A的长度为的长度为16字节,位置为字节,位置为0 x100 B FIELD 32 ;定义;定义B的长度为的长度为32字节,位置为字节,位置为0 x110 S FIELD 256 ;定义;定义S的长度为的长度为256字节,位置为字节,位置为0 x130第第4章章 ARM嵌入式系
22、统程序设计及调试基础嵌入式系统程序设计及调试基础123地址读取伪指令地址读取伪指令第第4章章 ARM嵌入式系统程序设计及调试基础嵌入式系统程序设计及调试基础13 1)ADR伪指令伪指令小范围的地址读取小范围的地址读取 在汇编编译器编译源程序时,在汇编编译器编译源程序时,ADR伪指令被编译器替换成伪指令被编译器替换成一条合适的指令。通常,编译器用一条一条合适的指令。通常,编译器用一条ADD指令或指令或SUB指令来指令来实现实现ADR伪指令的功能,若不能用一条指令实现,则产生错误,伪指令的功能,若不能用一条指令实现,则产生错误,编译失败。编译失败。ADR伪指令中的地址是基于伪指令中的地址是基于PC
23、或寄存器的,当或寄存器的,当ADR伪指令中的地址是基于伪指令中的地址是基于PC时,该地址与时,该地址与ADR伪指令必须在同一伪指令必须在同一个代码段中。个代码段中。 地址表达式地址表达式expression的取值范围如下:的取值范围如下: 当地址值是字节对齐时,其取值范围为当地址值是字节对齐时,其取值范围为-255B255B;当地;当地址值是字对齐时,其取值范围为址值是字对齐时,其取值范围为-1020B1020B。 例如:例如:LOOP MOV R0,#10 ;LOOP 为行标,指示某一行代码为行标,指示某一行代码ADR R4,LOOP ;将;将LOOP地址放入地址放入r4(相对地址)(相对地
24、址),因为因为PC值为当前指令地址值加值为当前指令地址值加8字节,替换成字节,替换成ADR伪伪指令将被编译伪伪指令将被编译器译为器译为;SUB R4,PC,0 xC;NOP (MOV R0,R0)第第4章章 ARM嵌入式系统程序设计及调试基础嵌入式系统程序设计及调试基础14 2)ADRL伪指令伪指令中等范围的地址读取中等范围的地址读取 ADRL比比ADR伪指令可以读取更大范围的地址。在汇编编译器伪指令可以读取更大范围的地址。在汇编编译器编译源程序时,编译源程序时,ADRL伪指令被编译器替换成两条合适的指令。若伪指令被编译器替换成两条合适的指令。若不能用两条指令实现,则产生错误,编译失败。不能用
25、两条指令实现,则产生错误,编译失败。 地址表达式地址表达式expression的取值范围如下:的取值范围如下: 当地址值是字节对齐时,其取值范围为当地址值是字节对齐时,其取值范围为-64KB64KB;当地址;当地址值是字对齐时,其取值范围为值是字对齐时,其取值范围为-256KB256KB。 例如:例如:LOOP MOV R0,#10 ;LOOP 为行标,指示某一行代码为行标,指示某一行代码ADRL R4,LOOP ;将;将LOOP地址放入地址放入R4(相对地址)(相对地址),因为因为PC值为当前指令地址值加值为当前指令地址值加8字节,替换成本字节,替换成本ADRL伪伪指令将被编伪伪指令将被编译
26、器译为译器译为;SUB R4,PC,#0 xC;NOP (MOV R0,R0)第第4章章 ARM嵌入式系统程序设计及调试基础嵌入式系统程序设计及调试基础15 3)LDR伪指令伪指令大范围的地址读取大范围的地址读取 在汇编编译源程序时,在汇编编译源程序时,LDR伪指令被编译器替换成一条合适的伪指令被编译器替换成一条合适的指令。若加载的常数未超出指令。若加载的常数未超出MOV或或MVN的范围,则使用的范围,则使用MOV或或MVN指令代替该指令代替该LDR伪指令,否则汇编器将常量放入文字池,并使伪指令,否则汇编器将常量放入文字池,并使用一条程序相对偏移的用一条程序相对偏移的LDR指令从文字池读出常量
27、。指令从文字池读出常量。 例如:例如: LDR R1,=0 xFF ;将;将0 xFF读取到读取到R1中,编译后得到中,编译后得到 MOV R1,0 xFF 例如:例如: LDR R1,=ADDR ;将外部地址;将外部地址ADDR读取到读取到R1中,汇编后中,汇编后将得到:将得到: ;LDR R1,PC,OFFSET_TO_LPOOL ; ;LPOOL DCD ADDR第第4章章 ARM嵌入式系统程序设计及调试基础嵌入式系统程序设计及调试基础16 4汇编控制伪指令汇编控制伪指令 汇编控制伪指令用于控制汇编程序的执行流程。汇编控制伪指令用于控制汇编程序的执行流程。 1)IF、ELSE、ENDIF
28、 格式:格式:IF 逻辑表达式逻辑表达式 指令序列指令序列1 ELSE 指令序列指令序列2 ENDIF IF、ELSE、ENDIF伪指令能根据条件的成立与否决定是否执伪指令能根据条件的成立与否决定是否执行某个指令序列。当行某个指令序列。当IF后面的逻辑表达式为真,则执行指令序列后面的逻辑表达式为真,则执行指令序列1,否则执行指令序列否则执行指令序列2。其中,。其中,ELSE及指令序列及指令序列2可以没有,此时,可以没有,此时,当当IF后面的逻辑表达式为真,则执行指令序列后面的逻辑表达式为真,则执行指令序列1,否则继续执行后,否则继续执行后面的指令。面的指令。IF、ELSE、ENDIF伪指令可以
29、嵌套使用。伪指令可以嵌套使用。 例如:例如: GBLL Test ;声明一个全局的逻辑变量,变量名为;声明一个全局的逻辑变量,变量名为Test IF Test=TRUE 指令序列指令序列1 ELSE 指令序列指令序列2 ENDIF第第4章章 ARM嵌入式系统程序设计及调试基础嵌入式系统程序设计及调试基础17 2)WHILE、WEND 格式:格式:WHILE 逻辑表达式逻辑表达式 指令序列指令序列 WEND WHILE、WEND伪指令能根据条件的成立与否决定是否循环执伪指令能根据条件的成立与否决定是否循环执行某个指令序列。当行某个指令序列。当WHILE后面的逻辑表达式为真,则执行指令序后面的逻辑
30、表达式为真,则执行指令序列,该指令序列执行完毕后,再判断逻辑表达式的值,若为真则继列,该指令序列执行完毕后,再判断逻辑表达式的值,若为真则继续执行,一直到逻辑表达式的值为假。续执行,一直到逻辑表达式的值为假。 WHILE、WEND伪指令可以嵌套使用。例如:伪指令可以嵌套使用。例如:GBLA Counter ;声明一个全局的数学变量,变量名为;声明一个全局的数学变量,变量名为Counter Couter SETA 3 ;由变量;由变量Counter控制循环次数控制循环次数 WHILE Counter”、“=”、“=”、“/=”、“”运算运算符。以符。以X和和Y表示两个逻辑表达式,以上的运算符代表
31、的运算如下:表示两个逻辑表达式,以上的运算符代表的运算如下:X=Y表示表示X等于等于Y;XY表示表示X大于大于Y;X=Y表示表示X大于等于大于等于Y;X=Y表示表示X小于等于小于等于Y;X/=Y表示表示X不等于不等于Y;XY表示表示X不等于不等于Y。第第4章章 ARM嵌入式系统程序设计及调试基础嵌入式系统程序设计及调试基础37 (2) “LAND”、“LOR“、“LNOT”及及“LEOR”运算符。运算符。以以X和和Y表示两个逻辑表达式,以上的逻辑运算符代表的运算如下:表示两个逻辑表达式,以上的逻辑运算符代表的运算如下:X:LAND:Y表示将表示将X和和Y作逻辑与的操作;作逻辑与的操作;X:LO
32、R:Y表示将表示将X和和Y作逻辑或的操作;:作逻辑或的操作;:LNOT:Y表示将表示将Y作逻辑非的操作;作逻辑非的操作;X:LEOR:Y表示将表示将X和和Y作逻辑异或的操作。作逻辑异或的操作。 3)字符串表达式及运算符)字符串表达式及运算符 字符串表达式一般由字符串常量、字符串变量、运算符和括字符串表达式一般由字符串常量、字符串变量、运算符和括号组成。编译器所支持的字符串的最大长度为号组成。编译器所支持的字符串的最大长度为512字节。常用的与字节。常用的与字符串表达式相关的运算符如下。字符串表达式相关的运算符如下。 (1)LEN运算符。运算符。LEN运算符返回字符串的长度(字符数),运算符返回
33、字符串的长度(字符数),以以X表示字符串表达式,其语法格式如下:表示字符串表达式,其语法格式如下:LEN:X (2)CHR运算符。运算符。CHR运算符将运算符将0255之间的整数转换为一之间的整数转换为一个字符,以个字符,以M表示某一个整数,其语法格式如下:表示某一个整数,其语法格式如下: :CHR:M第第4章章 ARM嵌入式系统程序设计及调试基础嵌入式系统程序设计及调试基础38 (3)STR运算符。运算符。STR运算符将一个数字表达式或逻辑表达式运算符将一个数字表达式或逻辑表达式转换为一个字符串。对于数字表达式,转换为一个字符串。对于数字表达式,STR运算符将其转换为一运算符将其转换为一个以
34、十六进制组成的字符串;对于逻辑表达式,个以十六进制组成的字符串;对于逻辑表达式,STR运算符将其运算符将其转换为字符串转换为字符串T或或F,其语法格式如下:,其语法格式如下:STR:X其中其中X为一个数字表达式或逻辑表达式。为一个数字表达式或逻辑表达式。 (4)LEFT运算符。运算符。LEFT运算符返回某个字符串左端的一个运算符返回某个字符串左端的一个字串,其语法格式如下:字串,其语法格式如下:X:LEFT:Y其中其中X为源字符串,为源字符串,Y为一个整数,表示要返回的字符个数。为一个整数,表示要返回的字符个数。 (5)RIGHT运算符。与运算符。与LEFT运算符相对应,运算符相对应,RIGH
35、T运算符运算符返回某个字符串右端的一个字串,其语法格式如下:返回某个字符串右端的一个字串,其语法格式如下:X:RIGHT:Y其中其中X为源字符串,为源字符串,Y为一个整数,表示要返回的字符个数。为一个整数,表示要返回的字符个数。第第4章章 ARM嵌入式系统程序设计及调试基础嵌入式系统程序设计及调试基础39 (6)CC运算。运算。CC运算符用于将两个字符串连接成一个字符串,运算符用于将两个字符串连接成一个字符串,其语法格式如下:其语法格式如下:X:CC:Y其中其中X为源字符串为源字符串1,Y为源字符串为源字符串2,CC运算符将运算符将Y 连接到连接到X后面。后面。 4)与寄存器和程序计数器()与
36、寄存器和程序计数器(PC)相关的表达式及运算符)相关的表达式及运算符 常用的与寄存器和程序计数器相关的表达式及运算符如下:常用的与寄存器和程序计数器相关的表达式及运算符如下: (1)BASE运算符。运算符。BASE运算符返回基于寄存器的表达式中寄运算符返回基于寄存器的表达式中寄存器的编号,其语法格式如下:存器的编号,其语法格式如下:BASE:X其中其中X为与寄存器相关的表达式为与寄存器相关的表达式 (2)INDEX运算符。运算符。INDEX运算符返回基于寄存器的表达式中运算符返回基于寄存器的表达式中相对于其基址寄存器的偏移量,其语法格式如下:相对于其基址寄存器的偏移量,其语法格式如下:INDE
37、X:X 其中,其中,X为与寄存器相关的表达式为与寄存器相关的表达式 5)其他常用运算符)其他常用运算符 (1)?运算符。?运算符返回某代码行所生成的可执行代码的长)?运算符。?运算符返回某代码行所生成的可执行代码的长度,如度,如“?X”表示返回定义符号表示返回定义符号X的代码行所生成的可执行代码的的代码行所生成的可执行代码的字节数。字节数。(2)DEF运算符。运算符。DEF运算符判断是否定义某个符号,如:运算符判断是否定义某个符号,如:DEF:X:表示当符号:表示当符号X已经定义,结果为真;否则为假。已经定义,结果为真;否则为假。 第第4章章 ARM嵌入式系统程序设计及调试基础嵌入式系统程序设
38、计及调试基础40 1汇编语言的程序结构汇编语言的程序结构 在在ARM(Thumb)汇编语言程序中,以程序段位单位组织代码。)汇编语言程序中,以程序段位单位组织代码。段是相对独立的指令或数据序列,具有特定的名称。段可以分为代段是相对独立的指令或数据序列,具有特定的名称。段可以分为代码段和数据段,代码段的内容为执行代码,数据段存放运行时需要码段和数据段,代码段的内容为执行代码,数据段存放运行时需要用到的数据。一个汇编程序至少要有一个代码段,当程序较长时,用到的数据。一个汇编程序至少要有一个代码段,当程序较长时,可以分割为多个代码段和数据段,多个段在程序编译链接时最终形可以分割为多个代码段和数据段,
39、多个段在程序编译链接时最终形成一个可执行的映象文件。成一个可执行的映象文件。 可执行映象文件通常由以下几部分构成。可执行映象文件通常由以下几部分构成。(1)一个或多个代码段,代码段的属性为只读。)一个或多个代码段,代码段的属性为只读。(2)零个或多个包含初始化数据的数据段,其属性为可读写。)零个或多个包含初始化数据的数据段,其属性为可读写。(3)零个或多个不包含初始化数据的数据段,其属性为可读写。)零个或多个不包含初始化数据的数据段,其属性为可读写。 链接器根据系统默认或用户设定的规则,将各个段安排在存储器链接器根据系统默认或用户设定的规则,将各个段安排在存储器中的相应位置。因此源程序中段之间
40、的相对位置与可执行的映象文中的相应位置。因此源程序中段之间的相对位置与可执行的映象文件中段的相对位置一般不会相同。件中段的相对位置一般不会相同。413 ARM汇编语言的程序结构汇编语言的程序结构第第4章章 ARM嵌入式系统程序设计及调试基础嵌入式系统程序设计及调试基础41 以下是一个汇编语言的程序基本结构:以下是一个汇编语言的程序基本结构: AREA Init, CODE, READONLY ENTRY START LDR R0, =0 x3FF5000 LDR R1, #0 xFF STR R1, R0 LDR R0,=0 x3FF5008 LDR R1,0 x01 STR R1,R0 EN
41、D。 在汇编语言程序中,用在汇编语言程序中,用AREA伪指令定义一个段,并说明所定伪指令定义一个段,并说明所定义段的相关属性,以上程序段中定义了一个名为义段的相关属性,以上程序段中定义了一个名为Init的代码段,属的代码段,属性为只读。性为只读。ENTRY伪指令标识程序的入口点,接下来为指令序列,伪指令标识程序的入口点,接下来为指令序列,程序的末尾为程序的末尾为END伪指令。伪指令。第第4章章 ARM嵌入式系统程序设计及调试基础嵌入式系统程序设计及调试基础42 2汇编语言的子程序调用汇编语言的子程序调用 在在ARM汇编语言程序中,子程序的调用一般是通过汇编语言程序中,子程序的调用一般是通过BL
42、指令来指令来实现的,其格式如下:实现的,其格式如下: BL 子程序名子程序名 该指令在执行时完成如下操作:将子程序的返回地址存放在该指令在执行时完成如下操作:将子程序的返回地址存放在连接寄存器(连接寄存器(LR)中,同时将程序计数器()中,同时将程序计数器(PC)指向子程序的入)指向子程序的入口点,当子程序执行完毕需要返回调用处时,只需要将存放在口点,当子程序执行完毕需要返回调用处时,只需要将存放在(LR)中的返回地址重新拷贝给)中的返回地址重新拷贝给PC即可。在调用子程序的同时,即可。在调用子程序的同时,也可以完成参数的传递和从子程序返回运算的结果,通常可以使也可以完成参数的传递和从子程序返
43、回运算的结果,通常可以使用寄存器用寄存器R0至至R3完成。完成。第第4章章 ARM嵌入式系统程序设计及调试基础嵌入式系统程序设计及调试基础43 C语言是一种结构化的程序设计语言,它的优点是运行速度语言是一种结构化的程序设计语言,它的优点是运行速度快、编译效率高、移植性好和可读性强。快、编译效率高、移植性好和可读性强。C语言具有简单的语法语言具有简单的语法结构和强大的处理功能,并可方便的实现对硬件的直接操作。结构和强大的处理功能,并可方便的实现对硬件的直接操作。C语言支持模块化程序设计结构,支持自顶向下的结构化程序设计语言支持模块化程序设计结构,支持自顶向下的结构化程序设计方法。因此方法。因此C
44、语言编写的应用软件,可大大提高软件的可读性,语言编写的应用软件,可大大提高软件的可读性,缩短开发周期,便于系统的改进和扩充,这为开发大规模、高性缩短开发周期,便于系统的改进和扩充,这为开发大规模、高性能和高可靠性的应用系统提供了基本保证。能和高可靠性的应用系统提供了基本保证。 嵌入式嵌入式C语言程序设计是利用基本的语言程序设计是利用基本的C语言知识,面向嵌入式语言知识,面向嵌入式工程实际应用进行程序设计。嵌入式工程实际应用进行程序设计。嵌入式C语言程序设计首先是语言程序设计首先是C语言语言程序设计,必须符合程序设计,必须符合C语言基本语法。嵌入式语言基本语法。嵌入式C语言程序设计又是语言程序设
45、计又是面向嵌入式的应用,因此就要利用面向嵌入式的应用,因此就要利用C语言基本知识开发出面向嵌语言基本知识开发出面向嵌入式的应用程序。如何能够在嵌入式系统开发中熟练、正确的运入式的应用程序。如何能够在嵌入式系统开发中熟练、正确的运用用C语言开发出高质量的应用程序,是学习嵌入式程序设计的基语言开发出高质量的应用程序,是学习嵌入式程序设计的基础。础。42 ARM嵌入式嵌入式C语言程序设计基础语言程序设计基础第第4章章 ARM嵌入式系统程序设计及调试基础嵌入式系统程序设计及调试基础44 1C语言的语言的“预处理伪指令预处理伪指令”在嵌入式程序设计中的应用在嵌入式程序设计中的应用 在在C语言源程序中常常
46、加入一些语言源程序中常常加入一些“预处理命令预处理命令”,可以改,可以改进程序设计环境,提高编程效率,它虽然写在源程序中,但不产进程序设计环境,提高编程效率,它虽然写在源程序中,但不产生程序代码,因此称为预处理伪指令。生程序代码,因此称为预处理伪指令。 C语言所有预处理伪指令都是以语言所有预处理伪指令都是以#号开头,以区别于源文件号开头,以区别于源文件中的语句行与说明行。预处理伪指令有以下三种:文件包含、宏中的语句行与说明行。预处理伪指令有以下三种:文件包含、宏定义和条件编译。定义和条件编译。 预处理伪指令有以下特点:把文件的正文替换进来,如标预处理伪指令有以下特点:把文件的正文替换进来,如标
47、准头文件和自定义头文件;对宏定义进行宏扩展,减少了编程量,准头文件和自定义头文件;对宏定义进行宏扩展,减少了编程量,改进源程序的可读性;条件编译改善了编程的灵活性,也改善了改进源程序的可读性;条件编译改善了编程的灵活性,也改善了可移植性。可移植性。 421 嵌入式嵌入式C语言程序设计基础语言程序设计基础第第4章章 ARM嵌入式系统程序设计及调试基础嵌入式系统程序设计及调试基础45 1)文件包含伪指令)文件包含伪指令 文件包含伪指令可将头文件包含到程序中,头文件中定义的文件包含伪指令可将头文件包含到程序中,头文件中定义的内容包括符号常量、复合变量原型、用户定义的变量类型原型和内容包括符号常量、复
48、合变量原型、用户定义的变量类型原型和函数的原型说明等。函数的原型说明等。 指令格式如下:指令格式如下: #include ;标准头文件;标准头文件 #include“头文件名头文件名” ;用户自定义头文件;用户自定义头文件 #include 宏标识符宏标识符 文件包含伪指令举例如下:文件包含伪指令举例如下: #include ;标准头文件;标准头文件 #include ;标准头文件;标准头文件 本例中本例中string和和stdio是标准头文件,按环境变量是标准头文件,按环境变量include 指定的目录顺序搜索指定的目录顺序搜索string和和stdio。第第4章章 ARM嵌入式系统程序设计
49、及调试基础嵌入式系统程序设计及调试基础46 2) 宏定义伪指令宏定义伪指令 (1)简单宏。定义格式为:)简单宏。定义格式为:# define 宏标识符宏标识符 宏体。在定义宏体。在定义宏时应尽量避免使用宏时应尽量避免使用C语言的关键字和预处理器的预定义宏。语言的关键字和预处理器的预定义宏。 (2)参数宏。定义格式为:)参数宏。定义格式为:# define 宏标识符(形式参数表)宏标识符(形式参数表) 宏体。使用参数宏时,形式参数表应换为同样个十的实参数表,宏体。使用参数宏时,形式参数表应换为同样个十的实参数表,这一点类似函数的调用。这一点类似函数的调用。 (3)条件宏定义。先测试是否定义过某个
50、宏标识符,然后决)条件宏定义。先测试是否定义过某个宏标识符,然后决定如何处理。其定义格式如表定如何处理。其定义格式如表42所示。所示。 (4)宏释放。用于释放原先定义的宏标识符。经释放后的宏)宏释放。用于释放原先定义的宏标识符。经释放后的宏标示符可再次用于定义其它宏体。其定义格式为:标示符可再次用于定义其它宏体。其定义格式为:# undef 宏标宏标识符。识符。第第4章章 ARM嵌入式系统程序设计及调试基础嵌入式系统程序设计及调试基础47第第4章章 ARM嵌入式系统程序设计及调试基础嵌入式系统程序设计及调试基础48 3)条件编译伪指令)条件编译伪指令 条件编译伪指令是写给编译器的,指示编译器在
侵权处理QQ:3464097650--上传资料QQ:3464097650
【声明】本站为“文档C2C交易模式”,即用户上传的文档直接卖给(下载)用户,本站只是网络空间服务平台,本站所有原创文档下载所得归上传人所有,如您发现上传作品侵犯了您的版权,请立刻联系我们并提供证据,我们将在3个工作日内予以改正。