




版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
嵌入式ARM系统原理与实例开发北京大学出版社出版7/24/20231北京大学出版社出版12ARM处理器工作模式及寄存器功能ARM寻址方式与程序框架3ARM指令及应用程序设计第3章ARM程序设计基础4ARM伪指令及应用程序设计举例5ARM汇编程序设计实例7/24/20232北京大学出版社出版ARM处理器模式除用户模式之外的其余6种称为非用户模式(特权模式)在特权模式中,除系统模式之外的其余5种又称为异常模式不同的工作模式间可以相互切换。
工作模式功能CPSR[4:0]用户模式(usr)正常的程序执行状态10000快速中断模式(fiq)用于高速数据传输或通道处理10001外部中断模式(irq)用于通用的中断处理10010管理模式(svc)操作系统的保护模式10011中止模式(abt)用于虚拟存储及存储保护10111未定义指令模式und用于支持硬件协处理器的软件仿真11011系统模式(sys)运行特权级的操作系统任务111117/24/20233北京大学出版社出版ARM处理器的寄存器User/SystemSupervisorAbortUndefinedInterruptFastInterruptR0R0R0R0R0R0R1R1R1R1R1R1R2R2R2R2R2R2R3R3R3R3R3R3R4R4R4R4R4R4R5R5R5R5R5R5R6R6R6R6R6R6R7R7R7R7R7R7R8R8R8R8R8R8_FIQR9R9R9R9R9R9_FIQR10R10R10R10R10R10_FIQR11R11R11R11R11R11_FIQR12R12R12R12R12R12_FIQR13R13_SVCR13_ABORTR13_UNDEFR13_IRQR13_FIQR14R14_SVCR14_ABORTR14_UNDEFR14_IRQR14_FIQPCPCPCPCPCPC
CPSRCPSRCPSRCPSRCPSRCPSR
SPSR_SVCSPSR_ABORTSPSR_UNDEFSPSR_IRQSPSR_FIQ为什么需要R13,R14,SPSR?7/24/20234北京大学出版社出版寄存器设计原则对于一个正在运行的程序,主要包括以下内容:当前程序的位置:PC寄存器存储。当前CPU的状态:CPSR寄存器存储。当前临时数据:R0~R12通用寄存器存储(特殊情况下,部分也有特殊用途)。在运行时,涉及到中断切换,因此需要进行现场保护:当前程序的位置:R14寄存器存储。当前CPU的状态:SPSR寄存器存储。当前临时数据:存储在内存栈中,由R13寄存存储栈首地址。7/24/20235北京大学出版社出版ARM的寄存器组织1.通用寄存器:包括R0~R15,以及程序计数器PC.R0~R7称为不分组寄存器;R8~R12有两组物理寄存器。一组属于快速模式(R8_fiq~R12_fiq)另一组属于其它模式(R8_usr~R12_usr);R13和R14有6组物理寄存器。其中用户模式和系统模式共用一组
寄存器R13通常作为堆栈指针SP(stackpointer)寄存器R14常用作连接寄存器LR(linkregister);寄存器R15,又称为PC(programcounter)7/24/20236北京大学出版社出版ARM的寄存器组织2.状态寄存器:当前程序状态寄存器CPSR(currentprogramstatusRegister),可以在任何工作模式下被访问;程序状态备份寄存器SPSR(SavedProgramStatusRegister),只有在异常模式下,才能被访问;
7/24/20237北京大学出版社出版CPSR/SPSR条件标志(ConditionCodeFlags)N=ALU计算结果为负数(NegativeresultfromALU(ArithmeticLogicalUnit)flag)。Z=ALU计算结果为0(ZeroresultfromALUflag)。C=ALU计算结果进位(ALUoperationCarriedout)。Foranaddition,includingCMN,C=1ifproducedacarry.Forasubtraction,includingCMP,C=0ifproducedaborrow.V=ALU计算结果溢出(ALUoperationOverflowed)。Q=EDSP(preserveandrestoretheCPSRQflagifanexceptionoccursaboutenhancedDSPinstructions.)中断禁止位(InterruptDisablebits)I=1,关IRQ。F=1,关FIQ。TBit(Architecturev4Tonly)T=0,处理器当前处于ARM状态(ProcessorinARMstate)T=1,处理器当前处于Thumb状态(ProcessorinThumbstate)7/24/20238北京大学出版社出版ARM指令编码方式其中,<>内的项是必须的,{}内的项是可选的,如<opcode>是指令助记符,是必须的,而{<cond>}为指令执行条件,是可选的,如果不写则使用默认条件AL(无条件执行)。其中:Opcode:指令助记符,如LDR,STR等。Cond:执行条件,如EQ,NE等。S:是否影响CPSR寄存器的值,书写时影响CPSR,否则不影响。Rd:目标寄存器。Rn:第一个操作数的寄存器。operand2:第二个操作数。7/24/20239北京大学出版社出版ARM指令综述7/24/202310北京大学出版社出版第二个操作数组成每个立即数由一个8位的常数循环右移偶数位得到,其中循环右移的位数由一个4位的二进制的两倍表示,即<immediate>=immed_8循环右移(2*rotate_imm)。7/24/202311北京大学出版社出版ARM指令的条件码0000EQZ置位相等/等于00001NEZ清0不等0010CS/HSC置位进位/无符号高于或等于0011CC/LOC清0无进位/无符号低于0100MIN置位负数0101PLN清0非负数0110VSV置位溢出0111VCV清0无溢出7/24/202312北京大学出版社出版ARM指令的条件码(续)1000HIC置位且Z清0无符号高于1001LSC清0或Z置位无符号低于或等于1010GEN等于V有符号大于或等于1011LTN不等于V有符号小于1100GTZ清0且N等于V有符号大于1101LEZ置位或N不等于V有符号小于或等于1110AL任何状态总是(always)1111NV无从不(never)注:AL是默认的,NV不建议使用。7/24/202313北京大学出版社出版12ARM处理器工作模式及寄存器功能ARM寻址方式3ARM指令及应用程序设计第3章ARM程序设计基础4ARM伪指令及应用程序设计5ARM汇编程序设计实例7/24/202314北京大学出版社出版立即寻址MOV R0,#0xff00 ;0xff00->R07/24/202315北京大学出版社出版寄存器寻址MOV R1,R2 ;R2->R1SUB R0,R1,R2 ;R1-R2->R07/24/202316北京大学出版社出版基地址变址寻址LDR R2,[R3,#0x0F] ;R2←[R3+0x0F]STR R1,[R0,#-2] ;R1←[R0-2]LDR R0,[R1,#4]! ;R0←[R1+4]、R1←R1+47/24/202317北京大学出版社出版寄存器偏移寻址MOV R0,R2,LSL#3 ;R2的值左移3位,结果放入R0,即R0=R2*8ANDS R1,R1,R2,LSLR3 ;R2的值左移R3位,然后和R1相与操作,结果放入R17/24/202318北京大学出版社出版寄存器间接寻址LDR R1,[R2] ;R1←[R2]ADD R1,R1,[R2] ;R1←R1+[R2]7/24/202319北京大学出版社出版多寄存器寻址LDMIA R1,{R2,R12} ;R2←[R1],R12←[R2+4]7/24/202320北京大学出版社出版ARM汇编程序框架7/24/202321北京大学出版社出版段7/24/202322北京大学出版社出版程序入口与程序结束在C语言程序中,程序入口由main()函数指定,而在汇编程序中,程序入口由ENTRY伪指令指定,在一个源文件中只能有一个入口,而在一个完整的项目中,可以有一个或者多个入口,当有多个入口,由链接器通过entry参数指定真正入口位置。而在程序结束时,用END指令表示汇编程序结束,每个汇编程序文件中,都必须有一个END。7/24/202323北京大学出版社出版标号标号就是一个地址的代号,一般用于跳转指令使用,如果是较大范围跳转,则需要使用与ARM指令不相冲突关键字,例如框架代码中的START和STOP,标号在编程时顶格写(代码和伪指令前都要使用TAB键)。如果是小范围内的局部跳转,则可以使用数字。7/24/202324北京大学出版社出版12ARM处理器工作模式及寄存器功能ARM寻址方式3ARM指令及应用程序设计第3章ARM程序设计基础4ARM伪指令及应用程序设计5ARM汇编程序设计实例7/24/202325北京大学出版社出版mov指令及例程MOV{<cond>}{S}<Rd>,<op1> 数据传送指令MVN{<cond>}{S}<Rd>,<op1>数据取反传送指令7/24/202326北京大学出版社出版加減法指令及例程ADD{<cond>}{S}<Rd>,<Rn>,<op2>加法指令 Rd=op1ADC{<cond>}{S}<Rd>,<Rn>,<op2>带进位的加法指令 Rd=!op1SUB{<cond>}{S}<Rd>,<Rn>,<op2>
减法指令 Rd=Rn+op2RSB{<cond>}{S}<Rd>,<Rn>,<op2>反向减法指令 Rd=Rn+op2+carrySBC{<cond>}{S}<Rd>,<Rn>,<op2>
带借位减法指令 Rd=Rn-op2RSC{<cond>}{S}<Rd>,<Rn>,<op2>
带借位的反向减法指令 Rd=op2-Rn7/24/202327北京大学出版社出版加減法指令及例程AREA EXAMPLE3,CODE,READONLY ;/*声明一段名为EXAMPLE3的CODE*/ ENTRY ;/*指定函数的入口*/START MOV R0,#0xFF ;/*把#0xFF传送到R0*/ MOV R1,#0xEF000000 ;/*把#0XEF000000传送到R1*/ MOV R2,#0x2F000000 ;/*把#0x2F000000传送到R2*/ MVN R3,#0Xff ;/*把#0xFF取反后传送到R3*/ ADD R4,R2,R1 ;/*把R2加R1的值传送到R4*/ ADDS R5,R2,R1 ;/*把R2加R1的值传送到R5,s表示会影响cpsr*/ ADCS R6,R2,R1 ;/*把R2加R1的值,再加上carry的值后传送到R6. ;s表示值会影响cpsr*/7/24/202328北京大学出版社出版加減法指令及例程SUB R4,R2,R1 ;/R2减R1的值传送到R4*/ SUBS R4,R2,R1 ;/*R2减R1的值传送到R4, ;s表示值会影响cpsr*/ RSB R5,R2,R1 ;/*R1减R2的值传送到R5*/ RSBS R5,R2,R1 ;/*R1减R2的值后传送到R5, ;s表示会影响cpsr*/ SBC R6,R1,R2 ;/*R1减R2的值再减去!CARRY ;后传送到R6*/ RSC R7,R1,R2 ;/*R2减R1的值再减去!CARRY ;后传送到R7*/stop BL stop END ;/*endoftheprogram*/7/24/202329北京大学出版社出版逻辑指令及例程AND{<cond>}{S}<Rd>,<Rn>,<op2> 逻辑与指令 Rd=RnANDop2ORR{<cond>}{S}<Rd>,<Rn>,<op2> 逻辑或指令 Rd=RnORop2EOR{<cond>}{S}<Rd>,<Rn>,<op2> 逻辑异或指令 Rd=RnEORop2 BIC{<cond>}{S}<Rd>,<Rn>,<op2> 位清除指令 Rd=RnAND(!op2) 7/24/202330北京大学出版社出版逻辑指令及例程AREA EXAMPLE3,CODE,READONLY ;/*声明一段名为EXAMPLE3的代码*/ ENTRYSTART MOV R0,#0xF8 ;/*对R0赋值#0XF8*/ MOV R1,#0X0F ;/*对R1赋值#0X0F*/ AND R2,R1,R0 ;/*R2=R1&R0*/ EOR R3,R1,R0 ;/*R3=R1|R0*/
ORR R4,R1,R0 ;/*R4=R1⊕R0*/ BIC R5,R1,R0 ;/*R5=R1&R0的取反*/stopBstop ;/*死循环*/end7/24/202331北京大学出版社出版乘法指令及例程MUL{<cond>}{S}<Rd>,<Rn>,<op2>32位乘法指令Rd=Rn×op2MLA{<cond>}{S}<Rd>,<Rn>,<op2>,<op3>32位乘加指令Rd=Rn×op2+op3SMULL{<cond>}{S}<Rd1>,<Rdh>,<Rn>,<op2>64位有符号数乘法指令RdhRd1=Rn×op2SMLAL{<cond>}{S}<Rd1>,<Rdh>,<Rn>,<op2>64位有符号数乘加指令RdhRd1=Rn×op2+RdhRd1UMULL{<cond>}{S}<Rd1>,<Rdh>,<Rn>,<op2>64位无符号数乘法指令同SMULL指令,但指令中的Rn,op2的值为32位的无符号数UMLAL{<cond>}{S}<Rd1>,<Rdh>,<Rn>,<op2>64位无符号数乘加指令同SMLAL指令,但指令中的Rn,op2的值为32位的无符号数7/24/202332北京大学出版社出版乘法指令及例程AREA EXAMPLE3,CODE,READONLY ;/*声明一段名为EXAMPLE3的代码*/ ENTRYSTARTMOV R0,#0XFF000000 ;/*对R0赋值#0XFF000000*/ MOV R1,#-0X10 ;/*对R1赋值#-0X10*/ MOV R2,#0X1000000 ;/*对R2赋值#0X1000000*/ MOV R3,#0 ;/*对R3赋值#0*/
MULS R4,R0,R1 ;/*R4=R0*R1,结果影响寄存器CPSR的值*/
SMULLS R6,R5,R1,R0 ;/*R6=R1*R0的低32位,R5=R1*R0的高32位, ;结果影响寄存器CPAR的值*/
UMULLS R8,R7,R1,R0 ;/*R8=R1*R0的低32位,R7=R1*R0的高32位, ;结果影响寄存器CPSR的值*/7/24/202333北京大学出版社出版乘法指令及例程 MLAR3,R0,R1,R2 ;/*R3=R0*R1+R2*/ SMLALR6,R0,R1,R2 ;/*R6=R1*R2的低32位+R6,
;R0=R1*R2的高32位+R0*/ UMLALR8,R0,R1,R2 ;/*R8=R1*R2的低32位+R8,
;R0=R1*R2的高32位+R0, ;其中R1,R2的值为 ;32位无符号数,R8,R0的值 ;为64位无符号数*/STOP BLSTOP ;/*死循环*/END7/24/202334北京大学出版社出版跳转指令及例程B{<cond>}<addr>跳转指令,一旦遇到B指令,ARM指令将立即跳转到给定的addr标号位置,然后从那里继续执行。BL{<cond>}<addr>带返回的跳转指令,同B指令,但BL指令执行跳转指令的同时,还将PC的值保存到LR寄存器中。BLX<addr>或BLX<Rn>带返回和状态切换的跳转指令,处理器跳转到目标地址处,从那里继续执行,并将PC的值保存到LR寄存器中。BX<Rn>带状态切换的跳转指令,处理器跳转到目标地址处,从那里继续执行,目标地址为寄存器Rn的值和0xFFFFFFFE作与操作的结果。7/24/202335北京大学出版社出版跳转指令及例程AREA EXAMPLE3,CODE,READONLY ENTRY
START Ba ;跳转至a MOVR1,#10 ;这条语句将不会被执行a MOVR2,#11 ;r2=11 BLb ;跳转至b BLXt16 ;跳转至t16 Bends ;跳转到endsends7/24/202336北京大学出版社出版 MOVPC,LR ;PC=LR,PC指向(Bends),死循环, ;程序到这里结束b MOVR3,#2 ;r3=2 MOVPC,LR ;PC=LR,PC指向(BLb)的下一行, ;返回t16 MOVPC,LR ;PC=LR,PC指向(BLXt16)的 ;下一行,返回 END7/24/202337北京大学出版社出版单内存数据加载指令程序举例AREA EXAMPLE3,CODE,READONLY ;/*GIVEACODE,WHICHCALLEDEXAMPLE3*/ ENTRYSTART MOV R0,#0X02 ;/*SET#0X02TOR0*/ ADR R2,src ;/*将标号src的address装入R2*/ ADR R1,drc ;/*将标号drc的address装入R1*/
LDR R3,[R2] ;/*把内存中地址为R2的字数据装入R3*/ STR R3,[R1] ;/*把R3的字数据保存到以R1为地址的内存中*/
LDR R4,[R2,#0X08] ;/*把内存中地址为R2+#0X08的字数据装入R4*/ STR R4,[R1,#0X08] ;/*把R4的字数据保存到以R1+#0x08为地址的内存中, ;然后R1=R1+#0X08*/ LDR R5,[R2,R0] ;/*把内存中地址为R2+R0的字数据装入R5*/ STR R5,[R1,R0] ;/*把R5的字数据保存到以R1+R0为地址的内存中*/ LDR R3,[R2,#0X01]! ;/*把内存地址为R2+#0X01的字数据装入R3,然后 ;R2=R2+#0X01/ STR R3,[R1,#0X01]!; /*把R3的字数据保存到以R1+#0x01为地址的内存中, ;然后R1=R1+#0X01*/ 7/24/202338北京大学出版社出版内存数据加载指令及例程LDR{<cond>}<Rd>,<addressing_mode>字数据读取指令,将<addressing_mode>中的字读取到Rd中。STR{<cond>}<Rd>,<addressing_mode>;字数据写入指令,将一个32位的字(<Rd>中的字)数据写入到指定的内存单元。LDM{<cond>}<addressing_mode><Rn>{!},<Registers>批量内存字数据读取指令。STM{<cond>}<addressing_mode><Rn>{!},<Registers>批量内存字数据写入。7/24/202339北京大学出版社出版单内存数据加载指令程序举例 LDR R4,[R2,R0]! ;/*把内存地址为R2+R0的字数据装入R4, ;然后R2=R2+R0*/ STR R4,[R1,R0]! ;/*把R4的字数据保存到以R1+R0为地址的内存中, ;然后R1=R1+R0*/ LDR R5,[R2],R0 ;/*将内存中地址为R2的字数据装入R5, ;并将新地址R2+R0写入R2*/ STR R5,[R1],R0 ;/*把R5的字数据保存到以R1为地址的内存中, ;然后R1=R1+R0*/ LDR R5,[R2],#0X08 ;/*将内存中地址为R2的字数据装入R5, ;并将新地址R2+#0X08写入R2*/ LDR R5,[R1],#0X08 ;/*将内存中地址为R1的字数据装入R5, ;并将新地址R1+#0X08写入R1*/ends b ends ;PC=LR,PC指向(Bends),死循环,程序到这里结束src DCB 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16drc SPACE16 END7/24/202340北京大学出版社出版批量内存数据加载指令程序举例AREA EXAMPLE3,CODE,READONLY ENTRYSTART ADR R0,src ;加载src地址到R0 ADD R0,R0,#0X8 ;r0=r0+#0x8 ADR R1,drca ;加载drca地址到R1 ADR R13,drcb ;加载drcb地址到R13 LDMIA R0,{R3,R4} ;将起始地址为[r0]的内存内容顺次加载到r3,r4 LDMIB R0,{R5,R6} ;将起始地址为[r0+4]的内存内容顺次加载到r5,r6 LDMDA R0,{R7,R8} ;将地址为[r0-4]、[r0]的内存内容顺次加载到r7,r8 LDMDB R0,{R3,R4} ;将地址为[r0-4-4]、[r0-4]的内存内容 ;顺次加载到r3,r4 MOV R3,#0X0F ;r3=0x0f
MOV R4,#0XF0 ;r4=0xf0 MOV R5,#0XF000 ;r5=0xf0007/24/202341北京大学出版社出版批量内存数据加载指令程序举例 MOV R6,#0XFF ;r6=0xff MOV R7,#0XF ;r7=0xf MOV R8,#0XFF ;r8=0xff STMEA R0!,{R3,R4} ;将r3,r4顺次传送到内存地址[r0],[r0+4] STMED R0!,{R5,R6} ;将r3,r4顺次传送到内存地址[r0+4],[r0+4+4] STMFA R0!,{R7,R8} ;将r7,r8顺次传送到内存地址[r0+4],[r0+4+4] STMFD R0!,{R3,R4} ;将r3,r4顺次传送到内存地址[r0-4-4],[r0-4] LDMDB R0!,{R3,R4}^ ;将地址为[r0-4-4]、[r0-4]的内存内容顺次加载到
;r3,r4,用于指示指令的寄存器工作在用户模式ends b ends ;PC=LR,PC指向(Bends),死循环,程序到这里结束src DCD 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16drca SPACE64 drcb SPACE64 END7/24/202342北京大学出版社出版CPSR数据传输指令及例程MRS{<cond>}<Rd>,CPSR/SPSR程序状态寄存器到通用寄存器的数据传达指令,用于将程序状态寄存器的内容传送到目标寄存器Rd中。MSR{<cond>}CPSR/SPSR_<field>,<po1>通用寄存器到程序状态寄存器的数据传送指令,用于将寄存器Rd的值传送到程序状态寄存器中。7/24/202343北京大学出版社出版CPSR数据传输指令及例程AREA EXAMPLE3,CODE,READONLY ENTRYSTART MRS R0,CPSR ;/*保存cpsr到R0*/ MRS R1,SPSR ;/*保存spsr到R1*/ MOV R0,#0XF0 ;/*设置R0为#0XF0*/ MOV R1,#0xff000000 ;/*设置R1为#0xff000000*/ MSR CPSR_f,R1 ;/*用R1去改变cpsr的标识位*/ MSR CPSR_s,R0 ;/*用R0去改变cpsr的状态位*/ MSR CPSR_x,R0 ;/*用R0去改变cpsr的扩展位*/ MSR CPSR_c,R0 ;/用R0去改变cpsr的控制位*/stop BL stop ;/*结束程序*/ END 7/24/202344北京大学出版社出版数据交换指令及例程SWP{<cond>}<Rd>,<op1>,[<op2>]字数据交换,Rd=[op2],[op2]=op1.SWPB{<cond>}<Rd>,<op1>,[<op2>]数据取反传送指令。从op2所表示的内存装载一个字节并把这个字节放置到目的寄存器Rd的低8位中,Rd的高24位设置为0;然后将寄存器op1的低8位数据存储到同一内存地址中。7/24/202345北京大学出版社出版数据交换指令及例程 AREA EXAMPLE3,CODE,READONLY ENTRYSTART MOV R1,#0x124 ;R1=0x124
MOV R2,#0x234 ;R2=0x234 MOV R10,#0X10 ;R10=0x10 SWP R1,R2,[R10] ;R1=R10所表示的内存单元的数据。再将R2 ;的数据保存到R10所表示的内存单元
SWPB R3,R2,[R10] ;R3=R10所表示的内存单元的数据的低8位
;再将R2的数据的低8位
;保存到R10所表示的内存单元 Bend ;跳到endend
MOVPC,LR ;死循环,程序结束
END7/24/202346北京大学出版社出版12ARM处理器工作模式及寄存器功能ARM寻址方式3ARM指令及应用程序设计第3章ARM程序设计基础4ARM伪指令及应用程序设计5ARM汇编程序设计实例7/24/202347北京大学出版社出版符号定义伪指令及例程(1)GBLA 定义全局数字变量并初始化为0。格式如下: GBLA变量名(2)GBLS定义全局字符串变量并初始化为空串。格式如下: GBLS变量名(3)GBLL定义全局逻辑变量并初始化为FALSE。格式如下: GBLL变量名(4)SETA给数字变量赋值。格式如下: 变量名SETA数值(5)SETS给字符串变量赋值。格式如下: 变量名SETS字符串;(6)SETL给逻辑变量赋值。格式如下: 变量名SETL逻辑{TRUE/FALSE}7/24/202348北京大学出版社出版符号定义伪指令及例程(7)LCLA定义一个局部数字变量,并初始化为0。格式如下: LCLA变量名(8)LCLS定义一个局部字符串变量,并初始化为空串。格式如下: LCLS变量名(9)LCLL定义一个局部逻辑变量,并初始化为FALSE。格式如下: LCLL变量名(10)MACROMEND。定义宏。格式如下: MACRO [$标号]宏名[参数1,参数2,参数3……..] 指令序列 MEND 其中,MACRO表明一个宏定义的开始,MEND表示宏结束。7/24/202349北京大学出版社出版符号定义伪指令及例程GBLS String1 ;定义一个全局的字符串变量 GBLL Logic ;定义一个全局逻辑变量 GBLA var ;定义一个全局数字变量String1 SETS "test" ;String1付值为"test";;;;;定义变量值要顶格写Logic SETL {TRUE} ;Logic付值为TRUE,var SETA 0Xff ;var付值为0xff;-----------------------------------------------------以上为定义变量及初始化MACRO ;宏定义开始,宏一定要在前面定义,否则不能识别$HandlerLabelHANDLER$p1,$p2 ;$HandlerLabel为标号, ;HANDLER为宏名$p1,$p2为参数CLA var ;定义一个局部数字变量,在宏中定义局部变量, ;不影响全局变量 LCLS String ;定义一个局部字符串变量 LCLL Logic ;定义一个局部逻辑变量var SETA 0x11 ;var付值为0x11Logic SETL {FALSE} ;Logic付值为FALSE,String SETS "nottest" ;String1付值为"nottest"7/24/202350北京大学出版社出版符号定义伪指令及例程$HandlerLabel ;标号$HandlerLabel MOV R1,#var ;R1=var这里的var是宏体内的局部变量 INFO0,"String1" ;第一次扫描的时候提示"String1"
MOV R3,$#p1 ;R3=p1 MOVR4,$#p2 ;R4=p2 MEND ;宏定义结束;--------------------------------------------------------------以上定义宏
AREA EXAMPLE3,CODE,READONLY ENTRYSTARTHandlerFIQ HANDLER3,5 ;向宏HANDLER传送两个参数为3,5 MOV R3,#0 ;R3=0 MOV R4,#1 ;R4=1END1 B END1 ;死循环,程序结束 END 7/24/202351北京大学出版社出版数据定义伪指令及例程(1)DCB分配连续的字节储存单元并使用指定数据初始化。格式如下: 标号DCB表达式(2)DCW/DCWU分配连续的半字(2字节)储存单元并使用指定数据初始化。格式如下: 标号DCW/DCWU表达式(3)DCQ/DCQU 分配一块8个字节为单位连续的储存单元并使用指定数据初始化。格式如下: 标号DCQ/DCQU表达式(4)DCD分配连续的字(4字节)储存单元并使用指定数据初始化。 标号DCD表达式(5)DCFS/DCFSU为单精度浮点数分配连续的字储存单元并使用指定数据初始化。格式如下: 标号DCFS/DCFSU表达式(6)DCFD/DCFDU为双精度浮点数分配连续的字储存单元并使用指定数据初始化。格式如下: 标号DCFD/DCFDU表达式 (7)SPACE分配一块连续的存储单元。格式如下: SPACE表达式(8)FIELD分配一块连续的存储单元。格式如下: FIELD字节数(9)MAP定义一个结构化的内存表的首地址。格式如下: MAP表达式[,基址寄存器]7/24/202352北京大学出版社出版数据定义伪指令及例程7/24/202353北京大学出版社出版控制伪指令及例程(1)IF、ELSE和ENDIF条件编译指令。格式如下: IF 逻辑表达式 指令序列1 ELSE 指令序列2 ENDIFIF、ELSE和ENDIF可以分别用“[”、“|”、“]”代替,IF、ELSE和ENDIF伪指令可以嵌套使用。7/24/202354北京大学出版社出版控制伪指令及例程(2)WHILE、WEND指令格式如下:WHILE 逻辑表达式 指令序列WENDWHILE、WEND伪指令能根据条件的成立与否决定是否循环执行某个指令序列。使用示例如下:7/24/202355北京大学出版社出版控制伪指令及例程(3)MACRO、MEND指令格式如下: $标号 宏名 $参数1,$参数2,…… 指令序列 MENDMACRO、MEND伪指令可以将一段代码定义为一个整体,称为宏指令,然后就可以在程序中通过宏指令多次调用该段代码。7/24/202356北京大学出版社出版控制伪指令及例程7/24/202357北京大学出版社出版地址加载伪指令及例程(1)ADR小范围的地址读取伪指令。格式如下:ADR{cond}register,expr指令功能为:通常,编译器用一条ADD指令或SUB指令来实现该ADR伪指令的功能。(2)ADRL中等范围的地址读取伪指令。格式如下:ADRL{cond}register,expr指令功能为:ADRL伪指令被编译器替换成两条合适的指令,即使一条指令可以完成该伪指令的功能,编译器也将用两条指令来替换该ADRL伪指令。(3)LDR大范围的地址读取伪指令。格式如下:LDR{cond}register,=[expr|label-expr]指令功能为:当需要读取到寄存器中的数据超过了MOV及MVN指令可以操作的范围时,可以使用LDR伪指令将该数据读取到寄存器中。(4)NOP空操作伪指令。格式如下:NOP指令功能为:NOP伪指令不影响CPSR中的条件标志为。7/24/202358北京大学出版社出版地址加载伪指令及例程 AREA EXAMPLE3,CODE,READONLY ENTRYSTART MOV R0,#10 ;PC值为当前指令地址值加8字节 ADR R1,START ;本ADR伪指令被编译器替换成 ;SUBR1,PC,#0xc ADRL R2,START+60000;本ADRL伪指令被编译器替换成 ;ADDR2,PC,#0xe800和 ;ADDR2,PC,#0x254 LDR R3,=0xFF0FF ;将0xFF0FF读取到R3中 END1 B END1 END7/24/202359北京大学出版社出版声明引用伪指令及例程(1)EQU指令格式如下:名称 EQU 表达式{,类型}EQU伪指令用于为程序中的常量、标号等定义一个等效的字符名称,类似于C语言中的#define。其中EQU可用“*”代替。(2)EXPORT(或GLOBAL)指令格式如下:EXPORT 标号{[WEAK]}EXPORT伪指令用于在程序中声明一个全局的标号,该标号可在其他的文件中引用。EXPORT可用GLOBAL代替。(3)IMPORT指令格式如下:IMPORT 标号{[WEAK]}IMPORT伪指令用于通知编译器要使用的标号在其他的源文件中定义,但要在当前源文件中引用,而且无论当前源文件是否引用该标号,该标号均会被加入到当前源文件的符号表中。(4)EXTERN指令格式如下:EXTERN 标号{[WEAK]}EXTERN伪指令用于通知编译器要使用的标号在其他的源文件中定义,但要在当前源文件中引用,如果当前源文件实际并未引用该标号,该标号就不会被加入到当前源文件的符号表中。7/24/202360北京大学出版社出版声明引用伪指令及例程(5)GET(或INCLUDE)指令格式如下:GET 文件名GET伪指令用于将一个源文件包含到当前的源文件中,并将被包含的源文件在当前位置进行汇编处理。可以使用INCLUDE代替GET。(5)GET(或INCLUDE)指令格式如下:GET 文件名GET伪指令用于将一个源文件包含到当前的源文件中,并将被包含的源文件在当前位置进行汇编处理。(6)INCBIN指令格式如下:INCBIN 文件名INCBIN伪指令用于将一个目标文件或数据文件包含到当前的源文件中,被包含的文件不作任何变动的存放在当前文件中,编译器从其后开始继续处理。(7)RN指令格式如下:名称 RN 表达式RN伪指令用于给一个寄存器定义一个别名。(8)ROUT指令格式如下:{名称} ROUTROUT伪指令用于给一个局部变量定义作用范围。7/24/202361北京大学出版社出版段域伪指令及例程(1)FILED和MAP结构化内存表中的数据域指令。指令格式如下:标号 FIELD 表达式FIELD伪指令用于定义一个结构化内存表中的数据域。(2)AREA指令格式如下:AREA 段名 属性1,属性2,…… AREA伪指令用于定义一个代码段或数据段。其中,段名若以数字开头,则该段名需用“|”括起来,如|1_test|。属性字段表示该代码段(或数据段)的相关属性,多个属性用逗号分隔。常用的属性如下:CODE属性:用于定义代码段,默认为READONLY。DATA属性:用于定义数据段,默认为READWRITE。READONLY属性:指定本段为只读,代码段默认为READONLY。READWRITE属性:指定本段为可读可写,数据段的默认属性为READWRITE。ALIGN属性:使用方式为ALIGN表达式。在默认时,ELF(可执行连接文件)的代码段和数据段是按字对齐的,表达式的取值范围为0~31,相应的对齐方式为2表达式次方。COMMON属性:该属性定义一个通用的段,不包含任何的用户代码和数据。各源文件中同名的COMMON段共享同一段存储单元。7/24/202362北京大学出版社出版段域伪指令及例程(3)ALIGN指令格式如下:ALIGN {表达式{,偏移量}}ALIGN伪指令可通过添加填充字节的方式,使当前位置满足一定的对其方式。(4)CODE16和CODE32指令格式如下:CODE16(或CODE32)CODE16伪指令通知编译器,其后的指令序列为16位的Thumb指令。CODE32伪指令通知编译器,其后的指令序列为32位的ARM指令。(5)ENTRY指令格式如下:ENTRYENTRY伪指令用于指定汇编程序的入口点。 (6)END指令格式如下:ENDEND伪指令用于通知编译器已经到了源程序的结尾。7/24/202363北京大学出版社出版12ARM处理器工作模式及寄存器功能ARM寻址方式3ARM指令及应用程序设计第3章ARM程序设计基础4ARM伪指令及应用程序设计5ARM汇编程序设计实例7/24/202364北京大学出版社出版ARM汇编程序结构示例功能说明此程序实现一个主要向读者演示一个ARM汇编程序结构,对于任何一个ARM汇编程序,都需要至少一个程序入口(ENTRY),对于任意一段代码,都需要定义此段代码的属性(AREA)。同时使用BL命令调用子程序,最后,对于任何一段ARM汇编程序,都需要有结束标识END。7/24/202365北京大学出版社出版代码示例AREAsubrout,CODE,READONLY;声明一个只读代码段,其名字为subroutENTRY ;入口startMOVr0,#10 ;r0=10MOVr1,#3 ;r1=3BLdoadd ;跳转到doaddstopMOVr0,#0x18 ;angel_SWIreason_ReportExceptionLDRr1,=0x20196 ;ADP_Stopped_ApplicationExitSWI0x123456 ;ARMsemihostingSWIdoadd
ADDr0,r0,r1 ;r0=r1+r1MOVpc,lr ;从子程序返回
END ;结束7/24/202366北京大学出版社出版数据加载ARM汇编程序示例本程序主要向读者展示LDR命令的基本功能,从而实现地址跳转,同时在此程序中演示了数据域定义指令SPACE。另外,在此程序中使用到了LTORG指令。关于此指令功能说明如下:LTORG是在此指令出现的地方放一个文本池。例如,在ARM汇编中经常会使用: ldrr0,=instruction ;将地址instruction载入r07/24/202367北京大学出版社出版代码示例
AREALDRlabel,CODE,READONLYENTRY ;执行入口startMOV lr,pc ;保存当前PC值到lr寄存器,以便从func1返回
Bfunc1 ;跳转到第一个子程序
MOV lr,pc ;保存当前PC值到lr寄存器,以便从func2返回
BLfunc2 ;跳转到第二个子程序stopMOVr0,#0x18 ;angel_SWIreason_ReportExceptionLDRr1,=0x20196 ;ADP_Stopped_ApplicationExitSWI0x123456 ;ARMsemihostingSWIfunc1LDRr0,=start ;=>LDRR0,[PC,#offsettoLitpool1]LDRr1,=Darea+12 ;=>LDRR1,[PC,#offsettoLitpool1]LDRr2,=Darea+6000 ;=>LDRR2,[PC,#offsettoLitpool1]MOVpc,lr ;返回7/24/202368北京大学出版社出版代码示例LTORG ;在LDR指令前后4KB的范围内用 ;LTORG显式地在代码段中添加一个文字池func2LDRr3,=Darea+6000 ;=>LDRr3,[PC,#offsettoLitpool1] ;(sharingwithpreviousliteral)LDRr4,=Darea+6004 ;Ifuncommentedwillproducean ;errorasLitpool2isoutofrangeMOVpc,lr ;返回DareaSPACE8000
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2025安徽师范大学专职辅导员招聘12人模拟试卷有答案详解
- 2025江西招收劳务派遣制工作人员3人考前自测高频考点模拟试题及答案详解(必刷)
- 2025广东中山市沙溪镇人民政府所属事业单位招聘事业单位人员11人模拟试卷及答案详解(网校专用)
- 2025胡杨河市人民法院招聘书记员(1人)模拟试卷有完整答案详解
- 2025年济宁金乡县事业单位公开招聘工作人员(教育类)(39人)考前自测高频考点模拟试题及答案详解(各地真题)
- 2025年西安亮丽电力集团有限责任公司招聘(10人)模拟试卷及1套参考答案详解
- 浙江国企招聘2025温州市瓯飞新型建材有限公司面向社会公开招聘10名工作人员(合同制)笔试历年参考题库附带答案详解
- 2025黑龙江省建设科创投资有限公司面向社会招聘1人笔试历年参考题库附带答案详解
- 2025陕西恒润利农生物科技有限公司招聘(18人)笔试历年参考题库附带答案详解
- 2025重庆明德商业保理有限公司招聘1人笔试历年参考题库附带答案详解
- 体力活动金字塔
- 铜仁市大学生乡村医生专项计划招聘考试真题
- 土地综合整治投标方案(技术方案)
- JJF(皖) 174-2024 重点用能单位能源资源计量在线审查规范
- JGJ-T+141-2017通风管道技术规程
- 历年全国《宪法》知识竞赛试题库完整版及答案【历年真题】
- 基本乐理(师范教育专业)全套教学课件
- JJG 270-2008血压计和血压表
- 《解剖学基础》课件-上肢骨及其连接
- 轻质燃料油安全技术说明书样本
- 小米全屋智能方案
评论
0/150
提交评论