1三、ARM指令系统寻址方式ARM指令集(重点)ARM伪指令Thumb指令集(ARM指令集的功能子集)2寻址方式立即寻址MOVR0,#20;20→R0寄存器寻址MOVR0,R1;(R1)→R0寄存器移位寻址寄存器间接寻址LDRR0,[R3];((R3))→R0基址加偏址寻址LDRR0,[R1,#4]!((R1)+4))→R0;(R1)+4→R1前变址偏移寻址LDRR0,[R1],#4;((R1))→R0,(R1)+4→R1后变址偏移寻址堆栈寻址LDM/STMFD、ED、FA、EA多寄存器寻址LDM/STMIA、IB、DA、DB相对寻址Brel;(pc)+rel→pc3LDMIAR1,{R0,R2,R5};R0←[R1];R2←[R1+4];R5←[R1+8]LDMIBR1,{R0,R2,R5};R0←[R1+4];R2←[R1+8];R5←[R1+12]LDMDAR1,{R0,R2,R5};R5←[R1];R2←[R1-4];R0←[R1-8]LDMDBR1,{R0,R2,R5};R5←[R1-4];R2←[R1-8];R0←[R1-12]4•ARM存储器访问指令——多寄存器存取数据块传送指令操作过程如右图所示,其中R1为指令执行前的基址寄存器,R1’则为指令执行后的基址寄存器。R5R6R7R1R1’指令STMIAR1!,{R5-R7}4008H4004H4000H4014H4010H400CHR5R6R7R1R1’指令STMDAR1!,{R5-R7}4008H4004H4000H4014H4010H400CHR5R6R7R1R1’指令STMIBR1!,{R5-R7}4008H4004H4000H4014H4010H400CHR5R6R7R1’R1指令STMDBR1!,{R5-R7}4008H4004H4000H4014H4010H400CHEAFAEDFD5栈顶SP栈顶SP栈底空堆栈栈底满堆栈0x123456780x12345678栈顶SP0x12345678栈顶SP压栈压栈堆栈寻址LDM/STMFD、ED、FA、EA6栈底栈顶栈区SP堆栈存储区栈顶栈底栈区SP向下增长向上增长0x123456780x12345678堆栈压栈堆栈压栈LDM:出栈/STM:压栈FD、ED、FA、EA7多寄存器多寄存器loadload和和storestore指令的堆栈和块拷贝对照指令的堆栈和块拷贝对照递增递减满空满空增值先增STMIBSTMFALDMIBLDMED后增STMIASTMEALDMIALDMFD减值先减LDMDBLDMEASTMDBSTMFD后减LDMDALDMFASTMDASTMED8栈底栈顶栈区SP堆栈存储区栈顶栈底栈区SP向下增长向上增长0x123456780x12345678堆栈压栈堆栈压栈STMFA:满递增(入栈)STMIB:STMFD:满递减(入栈)STMDB0x123456780x12345678RnRn栈顶SP栈顶SP9栈底栈顶栈区SP堆栈存储区栈顶栈底栈区SP向下增长向上增长0x123456780x12345678堆栈压栈堆栈压栈STMEA:空递增(入栈)STMIASTMED:空递减(入栈)STMDA0x123456780x12345678RnRn栈顶SP栈顶SP10栈底栈顶栈区SP堆栈存储区栈顶栈底栈区SP向下增长向上增长0x123456780x12345678堆栈出栈堆栈出栈LDMFA:满递增(出栈)LDMDALDMFD:满递减(出栈)LDMIA0x123456780x12345678RnRn栈顶SP栈顶SP11栈底栈顶栈区SP堆栈存储区栈顶栈底栈区SP向下增长向上增长0x123456780x12345678堆栈出栈堆栈出栈LDMED:空递减(出栈)LDMIBLDMEA:空递增(出栈)LDMDB0x123456780x12345678RnRn栈顶SP栈顶SP12数据块传送存储堆栈操作压栈说明数据块传送加载堆栈操作出栈说明STMDASTMED空递减LDMDALDMFA满递减STMIASTMEA空递增LDMIALDMFD满递增STMDBSTMFD满递减LDMDBLDMEA空递减STMIBSTMFA满递增LDMIBLDMED空递增;使用数据块传送指令进行堆栈操作STMDAR0!,{R5-R6}压栈...LDMIBR0!,{R5-R6}出栈;使用堆栈指令进行堆栈操作STMEDR0!,{R5-R6}...LDMEDR0!,{R5-R6}两段代码的执行结果是一样的,但是使用堆栈指令的压栈和出栈操作编程很简单(只要前后一致即可),而使用数据块指令进行压栈和出栈操作则需要考虑空与满、加与减对应的问题。堆栈操作和数据块传送向下生长空堆栈13应用示例:S3C44B0部分启动代码•VectorsbResetHandler;/*fordebugbHandlerUndef;/*handlerUndefbHandlerSWI;/*SWIinterrupthandler*/bHandlerPabort;/*handlerPAbort*/bHandlerDabort;/*handlerDAbort*/b.;/*handlerReserved*/ldrpc,=HandlerIRQbHandlerFIQ•HandlerFIQ;HANDLERHandleFIQsubsp,sp,#4;reservedforPCstmfdsp!,{r8-r9};STMDBldrr8,=HandleFIQ;_ISR_STARTADDRESSldrr9,[r8]strr9,[sp,#8]ldmfdsp!,{r8-r9,pc};LDMIA14•简单的ARM程序;文件名:TEST1.S;功能:实现两个寄存器相加;说明:使用ARMulate软件仿真调试AREAExample1,CODE,READONLY;声明代码段Example1ENTRY;标识程序入口CODE32;声明32位ARM指令STARTMOVR0,#0;设置参数MOVR1,#10LOOPBLADD_SUB;调用子程序ADD_SUBBLOOP;跳转到LOOPADD_SUBADDSR0,R0,R1;R0=R0+R1MOVPC,LR;子程序返回END;文件结束使用“;”进行注释标号顶格写实际代码段声明文件结束15§3.3ARM指令系统介绍(一)存储器访问(Load/Store)指令(二)ARM数据处理指令(三)程序状态寄存器访问指令(四)ARM分支转移类指令(五)ARM协处理器类指令(六)软件中断16存储器寻址•芯片复位后用户看见的地址空间128KBFlash(LPC2114/2212)256KBFlash(LPC2124/2214)16KBSRAM8KBBootBlock2MBVPB外设2MBAHB外设0x000000000xFFFFFFFF保留给片内存储器使用保留给片内存储器使用保留给外部储器使用0x400000000xE00000000x800000000xF00000000x00020000地址空间ARM7处理器是典型的RISC处理器,对存储器的访问只能使用加载和存储指令实现。ARM7处理器是冯•诺依曼存储结构,程序空间、RAM空间及I/O映射空间统一编址,除对RAM操作以外,对外围IO、程序数据的访问均要通过加载/存储指令进行。17(一)存储器访问指令(Load/Store)1、单字和无符号字节Load/Store指令2、半字和有符号字节Load/Store指令3、双字Load/Store指令4、多寄存器Load/Store指令5、内存与寄存器交换指令18(一)存储器访问(Load/Store)指令1.单字和无符号字节Load/Store指令功能:提供ARM寄存器和内存之间单字节(8位)或单字(32位)数据的传送。LDR/STR的功能§3.3ARM指令系统介绍19•LDR和STR——字和无符号字节加载/存储指令编码指令执行的条件码I为0时,偏移量为12位立即数,为1时,偏移量为寄存器移位P表示前/后变址U表示加/减B为1表示字节访问,为0表示字访问W表示回写为指令的寻址方式Rd为源/目标寄存器Rn为基址寄存器L用于区别加载(L为1)或存储(L为0)20字节码结构(一)存储器访问(Load/Store)指令STRBR0,[R3,-R8,ASR#2];R0→(R3-R8/4),21指令格式:(1)零偏移LDR/STR{〈条件码〉}{B}{T}Rd,[Rn];((Rn))→Rd功能:将Rn的内容作为传送数据的地址。B:可选后缀,若有B,则传送Rd的最低有效字节。若操作码是LDR,则将Rd的其它字节清零。(加载无符字节数据,零扩展到32位)1.单字和无符号字节Load/Store指令(一)存储器访问(Load/Store)指令22(1)零偏移Rd:ARM寄存器Rn:存储器的基址寄存器,若指令是带写回的前变址(加后缀“!”)或后变址。(一)存储器访问(Load/Store)指令1.单字和无符号字节Load/Store指令23(2)前变址LDR/STR{条件码}{B}Rd,[Rn,offset]{!};((Rn)+offset)→Rd;;有“!”,则(Rn)+offset→Rn;无“!”,Rn不变1.单字和无符号字节Load/Store指令(一)存储器访问(Load/Store)指令24(2)前变址在数据传送之前,将偏移量加到Rn中,其结果作为传送数据的存储器地址。若使用后缀“!”,则结果写回到Rn中。Rn不允许是R15。其中offset—Rn上的偏移量。!:可选后缀,若有“!”,则将结果地址写回到Rn,若Rn是R15,则不能够用后缀“!”。LDRRd,[Rn,#offset]!((Rn)+offset))→Rd;(Rn)+offset→Rd1.单字和无符号字节Load/Store指令(一)存储器访问(Load/Store)指令25(3)程序相对偏移LDR/STR{〈条件码〉}Rd,Label;(Label)→RdLabel:程序相对偏移表达式,必须在当前指令的±4kB范围内。LDRRd,Label等价为:LDRRd,[R15,Label-{pc}]((R15)+Label-{pc}))→Rd1.单字和无符号字节Load/Store指令(一)存储器访问(Load/Store)指令汇编器由pc计算偏移量,并将pc作为Rn生成前变址指令。不能使用后缀“!”。26(4)后变址LDR/STR{条件码}{B}{T}Rd,[Rn],offset将Rn的值用作传送数据的存储器地址,数据传送后,偏移量加到Rn中,结果写回到Rn。Rn不允许是R15。LDRRd,[Rn],offset;((Rn))→Rd,(Rn)+offset→Rn1.单字和无符号字节Load/Store指令(一)存储器访问(Load/Store)指令27例1:将R0中的内容存放到外设中LDRR1,UARTADD;将UART地址放进R1中STRBR0,[R1];将数据放进外设中……UARTADD&&10000;UART的地址值(一)存储器访问(Load/Store)指令1.单字和无符号字节Load/Store指令28例2:LDRR8,[R10];((R10))→R8LDRNER2,[R5,#960]!;Z1时,((R5)+960)→R2,(R5)+960→R5STRR2,[R9,#consta-struc];consta-struc是常量表达式,该常量值的范围为1~40951.单字和无符号字节Load/Store指令(一)存储器访问(Load/Store)指令29STRBR0,[R3,-R8,ASR#2];R0→(R3-R8/4),存储R0的最低有效字节,;R3和R8不变。STRR5,[R7],#-8;R5→(R7),(R7)–8→R7LDRR0,localdata;读取一个字,该字位于标号localdata所在地址。1.单字和无符号字节Load/Stor