嵌入式复习

  • 格式:doc
  • 大小:820.50 KB
  • 文档页数:11

到ARM7为止的ARM处理器使用简单的3级流水线,它包括下列流水线级。

(1)取指令(fetch):从寄存器装载一条指令。

(2)译码(decode):识别被执行的指令,并为下一个周期准备数据通路的控制信号。

在这一级,指令占有译码逻辑,不占用数据通路。

(3)执行(excute):处理指令并将结果写回寄存器。

在ARM9TDMI中使用了典型的5级流水线,5级流水线包括下面的流水线级。

(1)取指令:从存储器中取出指令,并将其放入指令流水线。

(2)译码:指令被译码,从寄存器堆中读取寄存器操作数。

(3)执行:将其中1个操作数移位,并在ALU中产生结果。

(4)缓冲/数据(buffer/data):如果需要则访问数据存储器,否则ALU只是简单地缓冲1个时钟周期。

(5)回写(write-back):将指令的结果回写到寄存器堆,包括任何从寄存器读出的数据。

ARM 微处理器可支持多达16 个协处理器,用于各种协处理操作。

字节8位内存空间以字节为单位编址半字节16位2个字节字32位4字节大端存储是指字或者半字的最高位字节存放在内存的最低位字节地址上。

例如我们有一个字为0x12345678,这个字由4个字节组成,按照从高位到低位的次序分别是:0x12,0x34,0x56,0x78。

大端存储是指字或者半字的最高位字节(MSB:Most Significant Bit)存放在内存的最低位字节地址上。

例如我们有一个字为0x12345678(0x表示一个16进制的数),这个字由4个字节组成,按照从高位到低位的次序分别是:0x12,0x34,0x56,0x78。

如果把这个字放到以0x00008000起始的内存中,这个字在内存中的实际存放情况如表所示:如果我们有一个半字为0x1234,这个字由2个字节组成,按照从高位到低位的次序分别是:0x12,0x34。

如果把这个字放到以0x00008000起始的内存中,这个字在内存中的实际存放情况如表所示:小端存储是指字或者半字的最低位字节(LSB:Lowest Significant Bit)存放在内存的最低位字节地址上。

以16进制数0x12345678为例,这个字由4个字节组成,按照从高位到低位的次序分别是:0x12,0x34,0x56,0x78。

如果把这个字放到以0x00008000起始的内存中,这个字在内存中的实际存放情况如表3.4所示:如果我们有一个半字为0x1234,这个字由2个字节组成,按照从高位到低位的次序分别是:0x12,0x34。

如果把这个字放到以0x00008000起始的内存中,这个字在内存中的实际存放情况如表所示:常数表达式合法的判定方法第一,看这个数转换成二进制后1的个数是否不超过8个如果不超过8个,再看这n个1(n)是否能同时放到8个二进制位中如果可以放进去,再看这八个二进制位是否可以循环右移偶数位得到起初被判断的那个数值,如果可以,则此数值即为符合8位位图原理,否则,不符合MOV R1,R2 ;将R2的值存入R1MOV R0,R2,LSL #3 ;R0←R2 * 8,R2 的值左移3位,结果放入R0MOV R0,R2,LSL R1 ;R2 的值左移R1 位,结果放入R0LDR R0,[R1];R0←[R1],以寄存器R2的值作为操作数的地址,把取得操作数传送到R0中。

LDR R0,[R1,#4];R0←[R1+4],将寄存器R1的内容加上4形成操作数的地址,取得的操作数存入寄存器R0中。

LDR R2,[R3,#0x0C] ;读取R3+0x0C地址上的存储单元的内容,放入R2MOV R1,R0;将寄存器R0的值传送到寄存器R1MOVEQ PC,R14;将寄存器R14的值传送到PC,常用于子程序返回MOVS R1,R0,LSL#3;将寄存器R0的值左移3位后传送到R1 ,并影响标志位MOV R0,R0 ;R0=R0 NOP指令MOV R0,R0,LSL #3MOV PC,R14 ;返回调用者,用于普通函数返回MOVS PC,R14 ;退出到调用者并恢复标志位,用于异常函数返回跳转(B)和跳转连接(BL)指令是改变指令执行顺序的标准方式。

跳转指令改变程序的执行流程或者调用子程序。

这种指令使得一个程序可以使用子程序、if-then-else结构及循环。

执行流程的改变迫使程序计数器(PC)指向一个新的地址另一种实现指令跳转的方式是通过直接向PC寄存器中写入目标地址值,实现在4GB地址空间中任意跳转,这种跳转指令又称为长跳转。

如果在长跳转指令之前使用“MOV LR”或“MOV PC”等指令,可以保存将来返回的地址值,也就实现了在4GB的地址空间中的子程序调用。

助记符说明操作B跳转指令pc←labelBL 带返回的连接跳转pc←label(lr←BL后面的第一条指令)BX跳转并切换状态pc←Rm&0xfffffffe,T←Rm&1⑥通过使用跳转使程序体循环10次。

MOV R0,#10LOOPSUBS R0,R0,#1BNE LOOP⑦条件子程序调用示例。

…CMP R0,#5 ;如果R0<5BLLT SUB1 ;则调用BLGE SUB2 ;否则调用SUB2LDR R1,[R0,#0x12];将R0+12地址处的数据读出,保存到R1中(R0的值不变)LDR R1,[R0];将R0地址处的数据读出,保存到R1中(零偏移)LDR R1,[R0,R2];将R0+R2地址的数据读出,保存到R1中(R0的值不变)LDR R1,[R0,R2,LSL #2];将R0+R2×4地址处的数据读出,保存到R1中(R0、R2的值不变)LDR Rd,label;label为程序标号,label必须是当前指令的-4~4KB范围内LDR Rd,[Rn],#0x04;Rn的值用做传输数据的存储地址。

在数据传送后,将偏移量0x04 与Rn相加,结果写回到Rn中。

Rn不允许是R15STR指令用于将一个32位的字数据写入到指令中指定的内存单元。

(1)指令的语法格式STR{<cond>} <Rd>,<addr_mode>(2)指令举例①变量访问NumCount EQU 0x40003000 ;定义变量NumCountLDR R0,=NumCount;使用LDR伪指令装载NumCount的地址到R0LDR R1,[R0] ;取出变量值ADD R1,R1,#1 ;NumCount=NumCount+1STR R1,[R0] ;保存变量②GPIO设置GPIO—BASE EQU 0xe0028000;定义GPIO寄存器的基地址LDR R0,=GPIO—BASELDR R1,=0x00ffff00 ;将设置值放入寄存器STR R1,[R0,#0x0C];IODIR=0x00ffff00,IOSET的地址为0xE0028004LDRB指令根据addr_mode所确定的地址模式将一个8位字节读取到指令中的目标寄存器Rd。

指令的语法格式:LDR{<cond>}B <Rd>,<addr_mode>LDRB R0,[R1] ;将存储器地址为R1的字节数据读入寄存器R0,并将R0的高24位清零。

LDRB R0,[R1,#8] ;将存储器地址为R1+8的字节数据读入寄存器R0,并将R0的高24位清零。

STRB指令从寄存器中取出指定的8位字节放入存储器的低8位,并将存储器的高位补0。

指令的语法格式:STR{<cond>}B <Rd>,<addr_mode>LDRH指令用于从内存中将一个16位的半字读取到目标寄存器。

如果指令的内存地址不是半字节对齐的,指令的执行结果不可预知。

STRH指令从寄存器中取出指定的16位半字放入寄存器的低16位,并将寄存器的高位补0。

指令作用操作LDM 装载多个寄存器{Rd}*N←mem32[start address+4*N]STM 保存多个寄存器{Rd}*N→mem32[start address+4*N]LDM/STM 批量加载/存储指令可以实现在一组寄存器和一块连续的内存单元之间传输数据。

LDM 为加载多个寄存器,STM 为存储多个寄存器。

允许一条指令传送16个寄存器的任何子集或所有寄存器。

多寄存器寻址方式可以一次完成多个寄存器值的传送。

这种寻址方式可以用一条指令完成传送最多16个通用寄存器的值。

例如以下语句:LDMIA R0,{R1,R2,R3,R4};R1←[R0],R2←[R0+4],R3←[R0+8],R4←[R0+12]LDMIA R1!,{R2-R4,R6};将R1指向的单元中的数据读出到R2~R7、R12中(R1自动加1)堆栈是一种数据结构,按先进后出(First In Last Out,FILO)的方式工作,使用一个称作堆栈指针(SP:Stack Pointer)的专用寄存器指示当前的操作位置,堆栈指针总是指向栈顶。

递增堆栈:向堆栈写入数据时,堆栈由低地址向高地址生生长。

递减堆栈:向堆栈写入数据时,堆栈由高地址向低地址生生长。

堆栈指针指向最后压入的堆栈的有效数据项,称为满堆栈;堆栈指针指向下一个待压入数据的空位置,称为空堆栈。

x EQU 45 ; x=45y EQU 64 ; y=64stack_top EQU 0x30200000AREA text,CODE,READONLYldr sp, =stack_topmov R0, #xstr R0, [sp]mov R0, #yldr R1, [sp]add R0, R0, R1str R0, [sp]stopb stopend程序状态寄存器指令MRS 把程序状态寄存器的值送到一个通用寄存器Rd=PSRMSR 把通用寄存器的值送到程序状态寄存器或把一个立即数送到程序状态字PSR[field]=Rm或PSR[field]=immediateMRS指令用于将程序状态寄存器的内容传送到通用寄存器中。

在ARM处理器中,只有MRS指令可以将状态寄存器CPSR或SPSR读出到通用寄存器中。

(1)指令的语法格式MRS{cond} Rd,PSR其中,Rd为目标寄存器,Rd不允许为程序计数器(PC)。

PSR为CPSR或SPSR。

在ARM处理器中,只有MSR指令可以直接设置状态寄存器CPSR或SPSR。

(1)指令的语法格式MSR{cond} PSR_field,#immed_8rMSR{cond} PSR_field,Rm其中,PSR是指CPSR或SPSR。

<fields>设置状态寄存器中需要操作的位。

状态寄存器的32位可以分为4个8位的域(field)。

bits[31:24]为条件标志位域,用f表示;bits[23:16]为状态位域,用s表示;bits[15:8]为扩展位域,用x表示;bits[7:0]为控制位域,用c 表示;immed_8r为要传送到状态寄存器指定域的立即数,8位;Rm为要传送到状态寄存器指定域的数据源寄存器。