版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
第三章ARM微处理器指令系统和程序设计北京航空航天大学电工电子中心2025年2月提纲ARM指令系统概述ARM汇编语言的语句格式ARM伪指令汇编语言程序结构ARM汇编与C混合编程ARM微处理器初始化分析ARM指令集1.ARM处理器是基于RISC(精简指令运算集)设计的2.ARM支持32位的ARM指令集和16位的Thumb指令集3.ARM处理器支持两种运行状态:ARM状态和Thumb状态,ARM指令必须在ARM状态下执行;同样,Thumb指令也必须处于Thumb状态下执行。ARM处理器可以在两种状态下进行切换。ARMvsThumbARM指令集分类ARM指令集属于Load/Store型指令。ARM指令集分为6类:1.跳转指令2.数据处理指令3.程序状态寄存器处理指令4.加载/存储指令5.协处理器指令6.异常产生指令ARM体系结构的主要特征-三地址指令ARM是三地址指令格式,指令的基本格式如下:<opcode>{<cond>}{S}<Rd>,<Rn>{,<operand2>}
其中<>号内的项是必须的,{}号内的项是可选的。各项的说明如下:opcode:指令助记符;
cond:执行条件;S:是否影响CPSR寄存器的值;Rd:目标寄存器;
Rn:第1个操作数的寄存器;operand2:第2个操作数;指令语法目标寄存器(Rd)源寄存器1(Rn)源寄存器2(Rm)ADDr3,r1,r2r3r1r2例:ARM体系结构的主要特征-条件执行ARM指令的基本格式如下:ARM指令集——条件码<opcode>{<cond>}{S}<Rd>,<Rn>{,<operand2>}
使用条件码“cond”可以实现高效的逻辑操作(节省跳转和条件语句),提高代码效率。
所有的ARM指令都可以条件执行,而Thumb指令只有B(跳转)指令具有条件执行
功能。如果指令不标明条件代码,将默认为无条件(AL)执行。ARM体系结构的主要特征-条件执行ARM指令集——条件码C代码:If(a>b)a++;Elseb++;对应的汇编代码:CMP R0,R1 ;R0(a)与R1(b)比较ADDHI R0,R0,#1;若R0>R1,则R0=R0+1ADDLS R1,R1,#1;若R0≤R1,则R1=R1+1示例:ARM体系结构的主要特征-单指令移位操作Rm,shift——寄存器移位方式
将寄存器的移位结果作为操作数(移位操作不消耗额外的时间),但Rm值保持不变,移位方法如下:ALU桶形移位器Rd结果N预处理未预处理RmRnARM指令集对第2个操作数,提供单指令的移位操作功能寄存器移位方式举例:ADD R1,R1,R1,LSL#3 ;R1=R1+R1<<3SUB R1,R1,R2,LSRR3 ;R1=R1-R2>>R3ARM指令的寻址方式立即数寻址:ADDR1,R1,#0x1寄存器寻址:ADDR1,R1,R2寄存器偏移寻址:ADDR1,R1,R2,ROR#0x2寄存器间接寻址:STRR1,[R2]基址变址寻址:opRd,[Rn,R1]多寄存器寻址:STMIAR0,{R2-R5,R7}堆栈寻址:STMFDSP!,{R1-R7,LR}相对寻址:BLLabel;Label:….助记符说明操作条件码位置LDM{mode}Rn{!},reglist多寄存器加载reglist←[Rn...],Rn回写等LDM{cond}{mode}STM{mode}Rn{!},reglist多寄存器存储[Rn...]←reglist,Rn回写等STM{cond}{mode}ARM存储器访问指令——多寄存器存取
多寄存器加载/存储指令可以实现在一组寄存器和一块连续的内存单元之间传输数据。LDM为加载多个寄存器;STM为存储多个寄存器。允许一条指令传送16个寄存器的任何子集或所有寄存器。它们主要用于现场保护、数据复制、常数传递等。助记符说明操作条件码位置SWPRd,Rm,Rn寄存器和存储器字数据交换Rd←[Rn],[Rn]←Rm(Rn≠Rd或Rm)SWP{cond}SWPBRd,Rm,Rn寄存器和存储器字节数据交换Rd←[Rn],[Rn]←Rm(Rn≠Rd或Rm)SWP{cond}BARM存储器访问指令—寄存器和存储器交换指令SWP指令用于将一个内存单元(该单元地址放在寄存器Rn中)的内容读取到一个寄存器Rd中,同时将另一个寄存器Rm的内容写入到该内存单元中。使用SWP可实现信号量操作。
指令格式如下:SWP{cond}{B}Rd,Rm,[Rn]
其中,B为可选后缀,若有B,则交换字节,否则交换32位字;Rd用于保存从存储器中读入的数据;Rm的数据用于存储到存储器中,若Rm与Rd相同,则为寄存器与存储器内容进行互换;Rn为要进行数据交换的存储器地址,Rn不能与Rd和Rm相同。
ARM子程序调用助记符说明操作条件码位置Blabel分支指令PC←labelB{cond}BLlabel带链接的分支指令LR←PC-4,PC←labelBL{cond}BXRm带状态切换的分支指令PC←Rm,切换处理器状态BX{cond}BLXlabel带链接和状态的分支ARM指令集——分支指令
带状态切换的分支指令——BX指令,该指令可以根据跳转地址(Rm)的最低位来切换处理器状态。其跳转范围限制在当前指令的±32M字节地址内(ARM指令为字对齐,最低2位地址固定为0)。指令格式如下:BX{cond}Rm跳转地址Rm[0]跳转后CPSR标志T位处理器状态00ARM11ThumbARM子程序嵌套调用ARM调用规范使用栈的规范:数据栈为FD(满递减)类型在函数调用之间传递/返回参数4个以下参数,由R0~R3传递,其中arg1-R0大于4个参数时,通过堆栈传递返回结果存在R0中寄存器R4~R10用于局部变量、中间变量存储提纲ARM指令系统概述ARM汇编语言的语句格式ARM伪指令汇编语言程序结构ARM汇编与C混合编程ARM微处理器初始化分析{标号}{指令或伪指令}{;注释}注意,每一条指令的助记符可以全部用大写,或者全部用小写,但不可以在一条指令中大、小写混用。另外,若一条语句太长,可将其分为若干行来书写,在行末用续行符“\”表示下一行与本行为同一条语句。ARM与Thumb汇编语言的语句格式在ARM(Thumb)汇编语言程序设计中,全局变量由GBLA、GBLL、GBLS伪指令声明,局部变量由LCLA、LCLL、LCLS伪指令声明,并使用SETA、SETL和SETS伪指令对其进行初始化。汇编语言程序中的符号
汇编语言程序设计中,经常使用各种符号代替地址、变量和常量等,以增加程序的可读性。符号的命名必须遵循以下的约定:1.符号在其作用范围内必须唯一。2.符号名不能与系统的保留字相同。
3.符号名不应与指令或伪指令同名。4.符号区分大小写,同名的大、小写符号会被认为是两个不同的符号。1.程序中的常量是指其值在程序的运行过程中不能被改变的量。ARM(Thumb)汇编程序所支持的常量有数字常量、逻辑常量和字符串常量。2.数字常量一般为32位的整数,当作为无符号数时,其取值范围为0~232-1,当作为有符号数时,其取值范围为-231~231-1。3.逻辑常量只有两种取值情况:真或假。4.字符串常量为一个固定的字符串。符号常量符号变量
程序中的变量是指其值在程序的运行过程中可以改变的量。ARM(Thumb)汇编程序所支持下列三种变量:1.数字变量用于在程序的运行中保存数字值,但注意数字值的大小不应超出数字变量所表示的范围。2.逻辑变量用于在程序的运行中保存逻辑值,逻辑值只有两种取值情况:真或假。3.字符串变量用于在程序的运行中保存一个字符串,但注意字符串的长度不应超出字符串变量所能表示的范围。
1.程序中的变量通过代换操作取得一个常量,代换操作符为“$”。2.代换操作符放在数字变量前,编译器会将该数字变量的值转换为十六进制的字符串,并将该十六进制的字符串代换“$”后的数字变量。3.代换操作符放在逻辑变量前,编译器会将该逻辑变量代换为它的取值(真或假)。4.代换操作符放在字符串变量前面,编译器会将该字符串变量的值代换“$”后的字符串变量。变量的代换1.在汇编语言程序设计中,表达式一般由变量、常量、运算符和括号构成。2.常用的表达式有算术运算表达式、移位运算表达式、位逻辑1.运算表达式、关系运算表达式、逻辑运算表达式和字符串表达式等。汇编语言程序中的表达式和运算符
表达式运算次序遵循如下的优先级:优先级相同的双目运算符的运算顺序为从左到右。相邻单目运算符的运算顺序为从右到左,且单目运算符优先级高于其他运算符。3.括号运算符的优先级最高。汇编语言程序中的表达式和运算符算术表达式一般由数字常量、数字变量、数字运算符和括号构成。相关的运算符如下:—“+”、“-”、“×”、“/”及“MOD”算术运算符,分别代表加、减、乘、除和取余数运算。【例】以X和Y表示两个数字表达式,则: 1.X+Y表示X与Y的和。 2.X-Y表示X与Y的差。 3.X×Y表示X与Y的乘积。 4.X/Y表示X除以Y的商。 5.XMODY表示X除以Y的余数。算术运算符及表达式移位运算符包括“ROL”、“ROR”、“SHL”及“SHR”四种,分别代表循环左移、循环右移、左移、右移运算。【例】以X和Y表示两个数字表达式,则: 1.XROL Y 表示将X循环左移Y位。 2.XROR Y 表示将X循环右移Y位。 3.XSHL Y 表示将X左移Y位。 4.XSHR Y 表示将X右移Y位。移位运算符及表达式位逻辑运算符包括“AND”、“OR”、“NOT”及“EOR”四种,分别代表按位作逻辑与、或、非及异或运算。【例】以X和Y表示两个数字表达式,则:1.XANDY表示将X和Y按位作逻辑与的操作。2.XORY表示将X和Y按位作逻辑或的操作。NOTY表示将Y按位作逻辑非的操作。XEORY表示将X和Y按位作逻辑异或的操作。位逻辑运算符及表达式关系运算符包括“==”、“>”、“<”、“>=”、“<=”、“/=”、“<>”七种,其表达式的运算结果为真或假。【例】以X和Y表示两个逻辑表达式,则:X==Y表示X等于Y。X>Y表示X大于Y。X<Y表示X小于Y。X>=Y表示X大于等于Y。X<=Y表示X小于等于Y。X/=Y表示X不等于Y。X<>Y表示X不等于Y。关系运算符及表达式逻辑运算符包括“LAND”、“LOR”、“LNOT”及“LEOR”四种,分别代表逻辑与、或、非及异或运算。【例】以X和Y表示两个逻辑表达式,则:XLANDY表示将X和Y作逻辑与的操作。XLORY表示将X和Y作逻辑或的操作。LNOTY表示将Y作逻辑非的操作。XLEORY表示将X和Y作逻辑异或的操作。逻辑运算符及表达式字符串表达式一般由字符串常量、字符串变量、运算符和括号构成。编译器所支持的字符串最大长度为512字节。常用的如下:(1)LEN运算符:返回字符串的长度(字符数),以X表示字符串表达式。格式:LENX(2)CHR运算符:将0~255之间的整数转换为一个字符,以M表示某一个整数。格式:CHRM字符串运算符及表达式(一)(3)STR运算符:将一个数字表达式或逻辑表达式转换为一个字符串。对于数字表达式,STR运算符将其转换为一个以十六进制组成的字符串;对于逻辑表达式,STR运算符将其转换为字符串T或F。格式:STRX注意:X为一个数字表达式或逻辑表达式。(4)LEFT运算符:返回某个字符串左端的一个子串。格式:XLEFTY注意:X为源字符串,Y为一个整数,表示要返回的字符个数。字符串运算符及表达式(二)(5)RIGHT运算符:与LEFT运算符相对应,RIGHT运算符返回某个字符串右端的一个子串。格式:XRIGHTY注意:X为源字符串,Y为一个整数,表示要返回的字符个数。(6)CC运算符:用于将两个字符串连接成一个字符串。格式XCCY注意:X为源字符串1,Y为源字符串2,CC运算符将Y连接到X的后面。字符串运算符及表达式(三)(1)BASE运算符:返回基于寄存器的表达式中寄存器的编号。格式:BASEX注意:X为与寄存器相关的表达式。(2)INDEX运算符:返回基于寄存器的表达式中相对于其基址寄存器的偏移量。格式:INDEXX注意:X为与寄存器相关的表达式。(3)?运算符:返回某代码行所生成的可执行代码的长度。格式:?X注意:返回定义符号X的代码行所生成的可执行代码的字节数。(4)DEF运算符:判断是否定义某个符号。格式:DEFX注意:如果符号X已经定义,结果为真,否则为假。其他常用运算符提纲ARM指令系统概述ARM汇编语言的语句格式ARM伪指令汇编语言程序结构ARM汇编与C混合编程ARM微处理器初始化分析在汇编语言程序中,有一些称为伪指令的特殊指令助记符,形式与一般的指令相似,但两者有本质的区别:一般指令是在程序运行时由CPU执行,而伪指令是在源程序汇编时由汇编程序来处理;一般指令有相应的操作代码,而伪指令没有。伪指令在源程序中的作用是为完成汇编程序作各种准备工作的,这些伪指令仅在汇编过程中起作用,一旦汇编结束,伪指令的使命就完成。ARM汇编器支持的伪指令数据定义伪指令用来为数据分配存储单元,建立变量和存储单元之间的联系,并可实现已分配存储单元的初始化。1、字节单元定义伪指令DCB格式:标号DCB表达式功能:DCB伪指令用于分配一片连续的字节存储单元并用伪指令中指定表达式初始化。注意:表式可以为0~255的数字或字符串。DCB也可用“=”代替。【例】StrDCB“Thisisatest
!”;分配连续的字节存储单元并初始化。ARM汇编器支持的伪指令--数据定义(DataDefinition)伪指令2、半字单元定义伪指令DCW(或DCWU)格式:标号DCW(或DCWU)表达式功能:DCW(或DCWU)伪指令用于分配一片连续的半字存储单元并用伪指令中指定的表达式初始化。注意:表达式可以为程序标号或数字表达式。用DCW分配的字存储单元是半字对齐的,而用DCWU分配的字存储单元并不严格半字对齐。【例】DataTestDCW0,1,2;分配连续的半字存储单元并初始化。数据定义伪指令3、字单元定义伪指令DCD(或DCDU)格式:标号DCD(或DCDU)表达式功能:DCD(或DCDU)伪指令用于分配一片连续的字存储单元并用伪指令中指定的表达式初始化。注意:表达式可以为程序标号或数字表达式。DCD也可用“&”代替。用DCD分配的字存储单元是字对齐的,而用DCDU分配的字存储单元并不严格字对齐。
【例】DataTestDCD3,4,5;分配连续的字存储单元并初始化。数据定义伪指令4、双精度数定义伪指令DCFD(或DCFDU)
格式:标号DCFD(或DCFDU)表达式
功能:DCFD(或DCFDU)伪指令用于为双精度的浮点数分配一片连续的字存储单元并用伪指令中定的表达式初始化。每个双精度的浮点数占据两个字单元。
注意:用DCFD分配的字存储单元是字对齐的,而用DCFDU分配的字存储单元并不严格字对齐。
【例】FDataTestDCFD3E15,-4E2;分配连续的字存储单元并初始化为指定双精度数。数据定义伪指令5、单精度数定义伪指令DCFS(或DCFSU)格式:标号DCFS(或DCFSU)表达式功能:DCFS(或DCFSU)伪指令用于为单精度的浮点数分配一片连续的字存储单元并用伪指令中定的表达式初始化。注意:每个单精度的浮点数占据一个字单元。用DCFS分配的字存储单元是字对齐的,而用DCFSU分配的字存储单元并不严格字对齐。【例】FDataTestDCFS5E13,-2E-4;分配连续的字存储单元并初始化为指定的单精度数。数据定义伪指令6、双字单元定义伪指令DCQ(或DCQU)格式:标号DCQ(或DCQU)表达式功能:DCQ(或DCQU)伪指令用于分配一片以8个字节为单位的连续存储区域并用伪指令中指定的表达式初始化。注意:用DCQ分配的存储单元是字对齐的,而用DCQU分配的存储单元并不严格字对齐。
【例】DataTestDCQ256;分配连续的存储单元并初始化为指定的值。数据定义伪指令7、存储区域定义伪指令SPACE格式:标号SPACE表达式功能:SPACE伪指令用于分配一片连续的存储区域并初始化为0。注意:表达式为要分配的字节数。SPACE也可用“%”代替。【例】DataSpaceSPACE256;分配连续100字节的存储单元并初始化为0。数据定义伪指令8、首地址定义伪指令MAP格式:MAP表达式{,基址寄存器}功能:MAP伪指令用于定义一个结构化的内存表的首地址。MAP也可用“^”代替。注意:表达式可以为程序中的标号或数学表达式,基址寄存器为可选项,当基址寄存器选项不存在时表达式的值即为内存表的首地址,当该选项存在时,内存表的首地址为表达式的值与基址寄存器的和。MAP伪指令通常与FIELD伪指令配合使用来定义结构化的内存表。【例】MAP0x100,R0;定义结构化内存表首地址的值为0x100+R0。数据定义伪指令9、数据域定义伪指令FIELD格式:标号FIELD表达式功能:用于定义结构化内存表中的数据域。也可用“#”代替,值为当前数据域在内存表中所占的字节数。注意:该常与MAP伪指令配合定义结构化的内存表。MAP伪指令定义内存表的首地址,FIELD伪指令定义内存表中的各个数据域,并可以为每个数据域指定一个标号供其他的指令引用。此外两个伪指令仅用于定义数据结构,并不实际分配存储单元。【例】MAP0x100;定义结构化内存表首地址为0x100AFIELD8;定义A长度8字节,位置为0x100BFIELD16;定义B长度16字节,位置为0x108CFIELD32;定义C长度32字节,位置为0x118数据定义伪指令符号定义伪指令用于定义ARM汇编程序中的变量、对变量赋值以及定义寄存器的别名等操作常见的符号定义伪指令有如下几种:ARM汇编器支持的伪指令--符号定义伪指令1、全局变量定义伪指令GBLA、GBLL和GBLS格式:GBLA(GBLL或GBLS)全局变量名功能:GBLA、GBLL和GBLS伪指令用于定义一个ARM程序中的全局变量,并将其初始化。其中:GBLA伪指令用于定义一个全局的数字变量,初始化为0;GBLL伪指令用于定义一个全局的逻辑变量,初始化为F(假);GBLS伪指令用于定义一个全局的字符串变量,初始化为空;注意:由于这三条伪指令用于定义全局变量,因此在整个程序范围内变量名必须唯一。【例】GBLATest1;定义一个全局数字变量,名为Test1GBLLTest2;定义一个全局逻辑变量,名为Test2GBLSTest3;定义一个全局字符串变量名为Test3ARM汇编器支持的伪指令--符号定义伪指令2、局部变量定义伪指令LCLA、LCLL和LCLS格式:LCLA(LCLL或LCLS)局部变量名功能:LCLA、LCLL和LCLS伪指令用于定义一个ARM程序中的局部变量,并将其初始化。其中:LCLA伪指令用于定义一个局部的数字变量,初始化为0;LCLL伪指令用于定义一个局部的逻辑变量,初始化为F(假);LCLS伪指令用于定义一个局部的字符串变量,初始化为空;注意:这三条伪指令用于声明局部变量,在其作用范围内变量名必须唯一。【例】LCLATest4;定义一个局部数字变量,名为Test4LCLLTest5;定义一个局部逻辑变量,名为Test5LCLSTest6;定义一个局部字符串变量名为Test6ARM汇编器支持的伪指令--符号定义伪指令3、变量赋值伪指令SETA、SETL和SETS格式:变量名SETA(SETL或SETS)表达式功能:伪指令SETA、SETL、SETS用于给一个已经定义的全局变量或局部变量赋值。其中:SETA伪指令用于给一个数学变量赋值;SETL伪指令用于给一个逻辑变量赋值;SETS伪指令用于给一个字符串变量赋值;注意:变量名为已经定义过的全局变量或局部变量,表达式为将要赋给变量的值。【例】LCLATest7;声明一个局部的数字变量,变量名为Test3Test7SETA0x1234;将该变量赋值为0x1234LCLLTest8;声明一个局部逻辑变量,名为Test4Test8SETL{TRUE};将该变量赋值为真ARM汇编器支持的伪指令--符号定义伪指令4、寄存器列表定义伪指令RLIST格式:名称RLIST{寄存器列表}功能:RLIST伪指令可用于对一个通用寄存器列表定义名称,使用该伪指令定义的名称可在ARM指令LDM/STM中使用。注意:在LDM/STM指令中,列表中的寄存器访问次序为根据寄存器的编号由低到高,而与列表中的寄存器排列次序无关。【例】RegListRLIST{R0-R5,R8,R10};将寄存器列表名称定义为RegList,可在ARM指令LDM/STM中通过该名称访问寄存器列表。ARM汇编器支持的伪指令--符号定义伪指令ARM汇编器支持的伪指令—汇编结构伪指令汇编结构伪指令用于建立汇编程序的结构框架,常用的伪指令包括以下几条:1、段定义伪指令AREA格式:AREA段名属性1,属性2,……功能:AREA伪指令用于定义一个代码段或数据段。其中,段名若以数字开头,则该段名需用“|”括起来,如|1_test|。注意:一个汇编语言程序至少要包含一个段,当程序太长时,也可以将程序分为多个代码段和数据段。属性字段表示该代码段(或数据段)的相关属性,多个属性用逗号分隔。常用属性如下:CODE属性:用于定义代码段,默认为READONLY。DATA属性:用于定义数据段,默认为READWRITE。READONLY属性:指定本段为只读,代码段默认为READONLY。READWRITE属性:指定本段为可读可写,数据段的默认属性为READWRITE。ALIGN属性:使用方式为ALIGN表达式。在默认时,ELF(可执行连接文件)的代码段和数据段是按字对齐的,表达式的取值范围为0~31,相应的对齐方式为2表达式次方。COMMON属性:该属性定义一个通用的段,不包含任何的用户代码和数据。各源文件中同名的COMMON段共享同一段存储单元。ARM汇编器支持的伪指令—汇编结构伪指令其中,ALIGN实际也是一个伪指令:格式:ALIGN{表达式{,偏移量}}功能:ALIGN伪指令可通过添加填充字节的方式,使当前位置满足一定的对其方式。其中,表达式的值用于指定对齐方式,可能的取值为2的幂,如1、2、4、8、16等。若未指定表达式,则将当前位置对齐到下一个字的位置。偏移量也为一个数字表达式,若使用该字段,则当前位置的对齐方式为:2的表达式次幂+偏移量。
【例】AREAInit,CODE,READONLY,ALIGN=3;指定后面的指令为8字节对齐。指令序列ENDARM汇编器支持的伪指令—汇编结构伪指令2、状态切换伪指令CODE16、CODE32格式:CODE16(或CODE32)功能:CODE16伪指令通知编译器,其后的指令序列为16位的Thumb指令。CODE32伪指令通知编译器,其后的指令序列为32位的ARM指令。注意:若在汇编源程序中同时包含ARM指令和Thumb指令时,可用CODE16伪指令通知编译器其后的指令序列为16位的Thumb指令,CODE32伪指令通知编译器其后的指令序列为32位的ARM指令。因此,在使用ARM指令和Thumb指令混合编程的代码里,可用这两条伪指令进行切换,但注意他们只通知编译器其后指令的类型,并不能对处理器进行状态的切换。ARM汇编器支持的伪指令—汇编结构伪指令【例】AREAInit,CODE,READONLY……CODE32;通知编译器其后指令为32位的ARM指令……BXNEXT;程序跳到NEXT处执行,并将处理器切换到Thumb工作状态……CODE16;通知编译器其后的指令为16位的Thumb指令NEXT……END;程序结束3、程序入口伪指令ENTRY格式:ENTRY功能:ENTRY伪指令用于指定汇编程序的入口点。注意:在一个完整的汇编程序中至少要有一个ENTRY,当有多个ENTRY时,程序的真正入口点由链接器指定,但在一个源文件里最多只能有一个ENTRY,也可以没有。【例】AREAInit,CODE,READONLYENTRY;指定应用程序的入口点……ARM汇编器支持的伪指令—汇编结构伪指令4、程序结束伪指令END格式:END功能:END伪指令用于通知编译器已经到了源程序的结尾。【例】AREAInit,CODE,READONLY……END;指定应用程序的结尾ARM汇编器支持的伪指令—汇编结构伪指令5、标号输出伪指令EXPORT(或GLOBAL)格式:EXPORT标号{[WEAK]}功能:EXPORT伪指令用于在程序中声明一个全局的标号,该标号可在其他的文件中引用。注意:EXPORT可用GLOBAL代替。标号在程序中区分大小写,[WEAK]选项声明其他的同名标号优先于该标号被引用。【例】AREAInit,CODE,READONLYEXPORTMain0;声明一个可全局引用的标号Main0……ENDARM汇编器支持的伪指令—汇编结构伪指令6、标号输入伪指令IMPORT格式:IMPORT标号{[WEAK]}功能:IMPORT伪指令用于通知编译器要使用的标号在其他的源文件中定义,但要在当前源文件中引用,且无论当前源文件是否引用该标号,该标号均会被加入到当前源文件的符号表中。注意:标号在程序中区分大小写,[WEAK]选项表示当所有的源文件都没有定义这样一个标号时,编译器也不给出错误信息。在多数情况下将该标号置为0,若该标号为B或BL指令引用,则将B或BL指令置为NOP操作。【例】AREAInit,CODE,READONLYIMPORTMain1;通知编译器当前文件要引用标号Main1,但Main1在其他源文件中定义……ARM汇编器支持的伪指令—汇编结构伪指令ARM汇编器支持的伪指令—汇编结构伪指令7、标号引入伪指令EXTERN格式:EXTERN标号{[WEAK]}功能:EXTERN伪指令用于通知编译器要使用的标号在其他的源文件中定义,但要在当前源文件中引用。与IMPORT不同的是,如果当前源文件实际并未引用该标号,该标号就不会被加入到当前源文件的符号表中。注意:标号在程序中区分大小写,[WEAK]选项表示当所有的源文件都没有定义这样一个标号时,编译器也不给出错误信息,在多数情况下将该标号置为0,若该标号为B或BL指令引用,则将B或BL指令置为NOP操作。【例】EXTERNMain2;通知编译器当前文件要引用标号Main2,但Main2在其他源文件中定义……ARM汇编器支持的伪指令—汇编结构伪指令8、源文件包含伪指令GET(或INCLUDE)格式:GET文件名功能:GET伪指令用于将一个源文件包含到当前的源文件中,并将被包含的源文件在当前位置进行汇编处理。可以使用INCLUDE代替GET。注意:汇编程序中常用的方法是在某源文件中定义一些宏指令,用EQU定义常量的符号名称,用MAP和FIELD定义结构化的数据类型,然后用GET伪指令将这个源文件包含到其他的源文件中,使用方法与C语言中的“include”相似。【例】GETfile1.s;通知编译器当前源文件包含源文件a1.sGETD:\file2.s;通知编译器当前源文件包含源文件C:\a2.s……ARM汇编器支持的伪指令—汇编结构伪指令9、目标文件包含伪指令INCBIN格式:INCBIN文件名功能:INCBIN伪指令用于将一个目标文件或数据文件包含到当前的源文件中,被包含的文件不作任何变动的存放在当前文件中,编译器从其后开始继续处理。【例】INCBINfile3.dat;通知编译器当前源文件包含文件a1.datINCBINE:\mm\file4.txt;通知编译器当前源文件包含文件C:\a2.txt……ARM汇编器支持的伪指令—汇编控制伪指令1、条件控制伪指令IF、ELSE、ENDIF格式:IF逻辑表达式指令序列1ELSE指令序列2ENDIF功能:该组伪指令能根据条件的成立与否决定是否执行某个指令序列。当IF后面的逻辑表达式为真,则执行指令序列1,否则执行指令序列2。ARM汇编器支持的伪指令—汇编控制伪指令其中,ELSE及指令序列2可以没有,此时当IF后面的逻辑表达式为真,则执行指令序列1,否则继续执行后面的指令。注意:IF、ELSE、ENDIF伪指令可以嵌套使用。【例】GBLLTest;声明一个全局的逻辑变量,变量名为Test……IFTest=TRUE指令序列1ELSE指令序列2ENDIFARM汇编器支持的伪指令—汇编控制伪指令2、循环控制伪指令WHILE、WEND格式:WHILE逻辑表达式指令序列WEND功能:该组伪指令能根据条件的成立与否决定是否循环执行某个指令序列。当WHILE后面的逻辑表达式为真,则执行指令序列,该指令序列执行完毕后,再判断逻辑表达式的值,若为真则继续执行,一直到逻辑表达式的值为假。ARM汇编器支持的伪指令—汇编控制伪指令注意:WHILE、WEND伪指令可以嵌套使用。【例】GBLACounter;声明一个全局的数学变量,变量名为CounterCounterSETA3;由变量Counter控制循环次数……WHILECounter<10指令序列WENDARM汇编器支持的伪指令—汇编控制伪指令3、宏定义伪指令MACRO、MEND格式:MACRO$标号宏名$参数1,$参数2,……指令序列
MEND功能:MACRO、MEND伪指令可以将一段代码定义为一个整体,称为宏指令,然后就可以在程序中通过宏指令多次调用该段代码。注意:$标号在宏指令被展开时,标号会被替换为用户定义的符号。宏指令可以使用一个或多个参数,当宏指令被展开时,这些参数被相应的值替换。ARM汇编器支持的伪指令—汇编控制伪指令说明:宏指令的使用方式和功能与子程序有些相似,子程序可以提供模块化的程序设计、节省存储空间并提高运行速度。但在使用子程序结构时需要保护现场,从而增加了系统的开销。因此,在代码较短且需要传递的参数较多时,可以使用宏指令代替子程序。包含在MACRO和MEND之间的指令序列称为宏定义体。在宏定义体的第一行应声明宏的原型(包含宏名、所需的参数),然后就可以在汇编程序中通过宏名来调用该指令序列。ARM汇编器支持的伪指令—汇编控制伪指令在源程序被编译时,汇编器将宏调用展开,用宏定义中的指令序列代替程序中的宏调用,并将实际参数的值传递给宏定义中的形式参数。MACRO、MEND伪指令可以嵌套使用。4、宏退出伪指令MEXIT格式:MEXIT功能:MEXIT用于从宏定义中跳转出去。ARM汇编器支持的伪指令—其他常用的伪指令1、等效定义伪指令EQU格式:名称EQU表达式{,类型}功能:EQU伪指令用于为程序中的常量、标号等定义一个等效的字符名称,类似于C语言中的#define。其中EQU可用“*”代替。注意:名称为EQU伪指令定义的字符名称,当表达式为32位的常量时,可指定表达式的数据类型,有以下三种类型:CODE16、CODE32和DATA。【例】TestEQU10;定义标号Test的值为50AddrEQU0xff,CODE32;定义Addr的值为0xff,且该处为32位的ARM指令。ARM汇编器支持的伪指令—其他常用的伪指令2、别名定义伪指令RN格式:名称RN表达式功能:RN伪指令用于给一个寄存器定义一个别名。注意:采用这种方式可以方便程序员记忆该寄存器的功能。其中,名称为给寄存器定义的别名,表达式为寄存器的编码。【例】TempRNR0;将R0定义一个别名Temp3、ROUT格式:{名称}ROUT功能:用于给一个局部变量定义作用范围。注意:在程序中未使用该伪指令时,局部变量的作用范围为所在的AREA,而使用ROUT后,局部变量的作为范围为当前ROUT和下一个ROUT之间。提纲ARM指令系统概述ARM汇编语言的语句格式ARM伪指令汇编语言程序结构ARM汇编与C混合编程ARM微处理器初始化分析汇编语言程序结构可执行映象文件通常由以下几部分构成:一个或多个代码段,代码段的属性为只读。零个或多个包含初始化数据的数据段,数据段的属性为可读写。零个或多个不包含初始化数据的数据段,数据段的属性为可读写。在汇编语言程序中,用AREA伪指令定义段,并说明所定义段的相关属性。ENTRY伪指令标识程序的入口点,接下来为指令序列,程序的末尾为END伪指令,该伪指令告诉编译器源文件的结束。每一个汇编程序段都必须有一条END伪指令,指示代码段的结束。汇编语言程序结构-子程序调用在ARM汇编语言程序中,子程序的调用一般是通过BL指令来实现的。使用格式:BL子程序名运行时,将子程序的返回地址存放在连接寄存器LR中,同时将程序计数器PC指向子程序入口点,当子程序执行完毕需要返回调用处时,只需要将存放在LR中的返回地址重新拷贝给程序计数器PC即可。在调用子程序的同时,也可以完成参数的传递和从子程序返回运算的结果,通常可以使用寄存器R0~R3完成。
以下是使用BL指令调用子程序的汇编语言源程序的基本结构:汇编语言的程序结构-实例AREAInit,CODE,READONLYENTRYStartLDRR0,=0x3FF5000LDRR1,0xFFSTRR1,[R0]LDRR0,=0x3FF5008LDRR1,0x01STRR1,[R0]BLNext……Next……MOVPC,LR……END提纲ARM指令系统概述ARM汇编语言的语句格式ARM伪指令汇编语言程序结构ARM汇编与C混合编程ARM微处理器初始化分析
在应用系统的程序设计中,若所有的编程任务均用汇编语言来完成,其工作量是可想而知的,这样做也不利于系统升级或应用软件移植。由于C语言便于理解,有大量的支持库,所以它是当前ARM程序设计所使用的主要编程语言。对硬件系统的初始化、CPU状态设定、中断使能、主频设定以及RAM控制参数初始化等C程序力所不能及的底层操作,还是要由汇编语言程序来完成。一个完整的ARM应用程序通常是C/C++语言和汇编程序的混合。ARM汇编与C混合编程ARM汇编与C混合编程一个ARM工程应由多个文件组成,包括汇编语言源文件、C/C++语言源文件和C/C++头文件等。ARM工程各种源文件先由编译器和汇编器将它们分别编译或汇编成汇编语言文件及目标文件。链接器负责将所有目标文件连接成一个文件并确定各指令的确定地址,从而形成最终可执行文件。链接器有三个功能:(1)生成与地址相关的代码,把所有文件连接成一个可执行文件;(2)根据程序员所指定的选项,为程序分配地址空间;(3)给出链接信息,以说明链接过程和结果。初始化阶段:汇编与C的衔接在ARM程序的初始化阶段,通常由汇编语言部分完成系统硬件的初始化,然后再使用跳转指令B或BL进入C语言部分。ARM公司的开发环境ARMDeveloperSuite(简称ADS)定义的初始化阶段程序框架为:C与汇编之间的函数调用为了解决C和汇编的相互调用问题,此人们制定了ARM-Thumb过程调用标准ATPCS(ARM-ThumbProcedureCallStandard)。ATPCS标准既是ARM的C编译器使用的函数调用规则,也是设计可被C程序调用的汇编函数的编写规则。函数是通过寄存器和堆栈来传递参数和返回函数值的。ATPCS规定,ARM的数据堆栈为FD型堆栈,即满递减堆栈。所以,堆栈的操作使用STMFD(push)和LDMFD(pop)。
C与汇编之间的函数调用•ATPCS标准规定,对于参数个数不多于4的函数,编译器必须按参数在列表中的顺序,自左向右为它们分配寄存器R0~R3。其中函数返回时,R0还被用来存放函数的返回值。•如果函数的参数多于4个,那么多余的参数则按自右向左的顺序压入数据堆栈,即参数入栈顺序与参数顺序相反。
C与汇编之间的函数调用例1:编写一个C程序,调用如下汇编语言函数strcopy,实现字符串拷贝。ARM汇编与C混合编程例2:编写一个汇编程序,调用如下C语言函数g,实现函数f的功能ARM汇编与C混合编程C与汇编之间的全局变量共享汇编程序如果要访问C语言中定义的全局变量,仍然需要使用IMPORT或EXTERN来声明。例3:编写一个汇编代码的函数,引用一个在C文件中定义的整型全局变量globvar,将其加2后写回globvar。C与汇编之间的全局变量共享C与汇编之间的全局变量共享C程序如果要访问汇编程序中定义且声明为可外部引用的数据,需要使用extern关键字来声明数据类型。例4:编写一个C函数,引用一个如下汇编程序文件中定义的数据符号Var1,将赋值为0x20。C与汇编的混合程序设计除函数调用方法之外,ARM编译器armcc中含有的内嵌汇编器还允许在C程序中内联或嵌入汇编代码,以提高程序的效率。两种方式:内联汇编,嵌入式汇编。内联汇编程序是在C程序的语句中直接嵌入汇编程序段而形成一个语句块。嵌入式汇编程序是一个仅具有C语言函数声明的单独汇编程序,不能和C语言的语句混合编写。灵活地使用内联汇编和嵌入式汇编,有助于提高程序效率。内联汇编所谓内联汇编程序,就是在C程序中直接编写汇编程序段而形成一个语句块,这个语句块可以使用除了BX和BLX之外的全部ARM指令来编写,从而可以使程序实现一些不能从C
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 4s店喷漆外包合同
- 一对一辅导外包合同
- 不同意劳务外包合同
- 中药代煎外包合同
- 二次外包合同
- 人保公司外包合同
- 兔喜生活外包合同
- 仓库管理外包合同
- 会议设备外包合同
- 公司增值税外包合同
- 【医卫类】2021年湖南省普通高等学校对口招生考试医卫类专业综合知识试题
- 电压电流串并流规律课件
- 2025年物业维修服务与客户满意度提升手册
- 2026年聊城幼儿师范学校第二批公开招聘工作人员9人备考题库及1套完整答案详解
- 2026保安员(初级)考试题模拟考试题库及答案(必刷)
- 语音厅保密协议书
- 燃气管道旁开挖施工方案
- 2025安徽黄山市徽城投资集团有限公司招聘10人笔试历年难易错考点试卷带答案解析2套试卷
- 《三峡》课件 部编语文八年级上册
- 2025年易制毒化学品安全培训试卷(含答案)
- 农业行政执法课件
评论
0/150
提交评论