560 likes | 817 Views
事项. 更好理解 MMU ,下载 http://10.1.4.123 中的 mmu.pdf. 更好说明寻址过程. 为什么我们要学指令?. C 语言: y=a*(b+c) ARM 指令实现: ADR R4,b LDR R0,[R4] ADR r4,c LDR r1,[r4] ADD r2,r0,r1
E N D
事项 • 更好理解MMU,下载http://10.1.4.123中的mmu.pdf
为什么我们要学指令? • C 语言:y=a*(b+c) ARM指令实现:ADR R4,b LDR R0,[R4] ADR r4,c LDR r1,[r4] ADD r2,r0,r1 ADR r4,a LDR r0,[r4] MUL r2,r2,r0 ADR r4,y STR r2,[r4]
本课内容 • ARM指令的条件执行 • Load/Store类指令 • ARM数据处理类指令 • ARM转移类指令 • ARM协处理器类指令 • ARM杂项指令 • XScale指令
5.2.2 ARM指令的条件执行 • 几乎所有的ARM指令均可包含一个可选的条件码,句法说明中以{cond}表示。只有在CPSR中的条件码标志满足指定的条件时,带条件码的指令才能执行。 • 几乎所有的ARM数据处理指令均可以根据执行结果来选择是否更新条件码标志。 • 条件码中的N,Z,C和V位的值将决定指令如何执行,条件码如表所示
5.2.3 Load/Store类指令 • 单字和无符号字节Load/Store类指令 • 半字和有符号字节Load/Store类指令 • 双字Load/Store类指令 • 多寄存器Load/Store类指令 • 预读取PLD指令 • 内存和寄存器交换类指令
单字和无符号字节Load/Store类指令 功能:提供ARM寄存器和内存之间单字节(8位)或单字(32位)数据的传送 格式: 1)零偏移(zero offset) LDR | STR {<条件码>}{B}{T} Rd ,[Rn ] ;((Rn))→Rd 零偏移指的是将Rn的内容作为传送数据的地址。 2)前变址(pre-indexed offset) LDR | STR{<条件码>} {B} Rd , [Rn , < offset >] {!} ;((Rn)+ offset)→Rd 前变址指的是在数据传送之前,将偏移量加到Rn中,其结果作为传送数据的存储地址。若使用后缀“!”,则结果写回到Rn中,Rn不允许是R15 3)程序相对偏移(program–relative) LDR | STR{<条件码>} Rd , LABEL ;(LABEL)→Rd 程序相对偏移指的是由PC计算偏移量,并将PC作为Rn生成前变址指令。不能使用后缀“!”。 4)后变址(post-indexed offset) LDR | STR{<条件码>} {B} {T} Rd , [Rn ], < offset > 后变址指的是将Rn的值用作传送数据的存储器地址,数据传送后,偏移量加到Rn中,结果写回到Rn。Rn不允许是R15。LDR Rd , [Rn ] , offset 等价为:((Rn))→Rd,(Rn)+offset→Rn
例 1) :将R0中的内容存放进外设中。 LDR R1 , UARTADD ; 将UART地址放进R1中 STRB R0 , [R1] ;将数据放进外设中 … UARTADD & &1000000 ;UART的地址值 例 2) :LDR R8,[R10] ;(( R10))→R8 LDRNE R2,[R5,#960]! ;Z≠1时,((R5)+960)→R2,(R5)+960→R5 STR R2,[R9,#consta-struc] ; consta-struc是常量的表达式,该常量值的范围为1~4095 STRB R0,[R3,-R8,ASR #2] ;R0→(R3-R8/4),存储R0的最低有效字节,R3和R8不变 STR R5,[R7],#-8 ;R5→(R7), R7-8→R7 LDR R0,localdata ; 读取一个字,该字位于标号lacaldata所在地址
半字和有符号字节Load/Store类指令 • 功能:提供ARM寄存器和内存之间半字(16位)和有符号字节(8位)数据的传送。 • 格式:1)零偏移(zero offset) LDR | STR{<条件码>} H | SH | SB Rd,[Rn] 2)前变址(pre-indexed offset) LDR | STR{<条件码>} H | SH | SB Rd , [Rn , <offset>] {!} 3)程序相对偏移(pregram–relatve) LDR | STR{<条件码>} H | SH | SB Rd , LABEL 4)后变址(post-indexed offset) LDR | STR{<条件码>}H | SH | SB Rd , [Rn ], <offset> 其中: H | SH | SB 表示数据类型选择 SH 对有符号半字(仅LDR) H 对无符号半字; SB 对有符号字节(仅LDR)。
例:LDREQSH R11,[R6] ;(有条件地)R11←[R6],读取16位半字,有符号扩展到32位 LDRH R1,[R0,#22] ;R1←[R0+22],读取16位半字,零扩展到32位 STRH R4,[R0+R1] ;存储最低的有效半字到R0+R1地址开始的两个字节,地址写回到R0 LDRSB R6,constf ;读取位于标号constf地址中的字节,有符号扩展
双字Load/Store类指令 • 功能:提供ARM寄存器和内存之间双字(64位)数据的传送 • 格式:1)零偏移(zero offset) LDR | STR{<条件码>} D Rd,[Rn] 2)前变址格式(pre-indexed offset) LDR | STR{<条件码>} D Rd , [Rn , <offset>] {!} 3)程序相对偏移(pregram–relatve) LDR | STR{<条件码>} D Rd , LABEL 4)后变址格式(post-indexed offset) LDR | STR{<条件码>} D Rd , [Rn ], <offset>
多寄存器Load/Store类指令 • 功能: 装入和存储多个寄存器,可以传送R0~R15的任何组合 • 格式: 1)标准格式 LDM | STM{<条件码>}<mode> Rn{!} , <寄存器组> 2)非用户模式下,用下面格式可以同时把当前的SPSR写入CPSR中,转向用户模式,寄存器组包含PC。 LDM {<条件码>}< mode > Rn{!} , <寄存器组+PC>^ 3)非用户模式下,用下面格式可以实现访问用户模式的寄存器,但寄存器组不包含PC。 LDM | STM{<条件码>}< mode > Rn , <寄存器组-PC>^
例 1) 若保存三个工作寄存器状态和返回地址, STMFD R13! , {R0-R2 , R14} 若恢复三个工作寄存器状态和返回地址 LDMFD R13! , {R0-R2 , PC} 例 2) LDMIA R8,{R0,R2,R9} ; ((R8))→R0 ; ((R8)+4)→R2 ; ((R8)+8)→R9 STMDB R1!,{R3—R6,R11,R12} ; (R3)→R1- 4 ; (R4)→R1- 8 ; (R5)→R1- 12 ; (R6)→R1- 16 ; (R11)→R1- 20 ; (R12)→R1- 24 ; (R1)- 24→R1 STMFD R13!,{R0,R4-R7,LR} ;寄存器进栈 LDMFD R13!,{R0,R4-R7,PC} ; 同样的寄存器出栈,从子程序返回 例 3) 子程序调用 SUB1 STMFD SP! , {R0-R2 , R14} ;保护R0~R2和返回地址 …… ; 其它指令 BL label ; 允许子程序嵌套 …… ; 其它指令 LDMFD SP! , {R0-R2 , R15} ;恢复R0~R2,返回子程序调用程序后执行
预读取PLD指令 • 功能:Cache 预读取(PLD,PreLoaD),使用PLD指示存储系统从后面几条新指令所指定的存储器地址读取。存储系统可使用这种方法加速以后的存储器访问。 • 格式:PLD [Rn,{offset}] • 其中:Rn 存储器的基址寄存器。 Offset 加在Rn上的偏移量 PLD [R9,#-2481]
内存和寄存器交换类指令 • 功能:用一条指令实现在寄存器和存储器之间交换数据 • 格式:SWP{<条件码>} {B} Rd , Rm , [Rn] ;((Rn))→Rd , (Rm)→Rn; n≠m ,d , ;如d=m, 为交换,Rm←((Rn))
5.2.4 ARM数据处理类指令 • 第二操作数 • 数据运算类指令 • 前导零计数指令 • 乘法类指令 • QADD、QSUB、QDADD和QDSUB指令
第二操作数 大多数ARM通用数据处理指令有一个灵活的第二操作数(flexible second operand)。在每一个指令的格式中以“Operand2”表示 。
两种可能的格式: (1)# immed-8r 常量的表达式。常量必须对应于8位位图(pattern)。该位图在32位字中,被循环移位偶数位(0、2、4、8、…、26、28、30)。合法常量:0xFF、0xFF000、0xF000000F。非法常量:0x101、0xFF04、0xFF003、0xFFFFFFFF。 (2)±Rm {, shift} Rm 存储第二操作数的ARM寄存器。可用各种方法对寄存器中的位图进行移位或循环移位。在指令中移位操作的结果用作第二操作数,但Rm本身不变。 Shift Rm的移位方法
数据运算类指令 • 功能:完成数据在寄存器中的运算,这些运算包括32位数据的算术、位操作,其中某一个操作数可以经过移位或循环运算。 • 格式: <操作码>{<条件码> } {S} Rd , Rn , Operand2 操作码 包括ADD、SUB、RSB、ADC、SBC、RSC、AND、ORR、EOR、BIC MOV、MVN、CMP、CMN、TST和TEQ指令
例 1: ADD R2,R1,R3 ;(R1)+(R3)→R2 例 2: SUBS R2, R2, #1 ; (R2)-1→R2 BEQ LABEL ; 如等于0,转向LABEL 例 3: R0中的内容乘5 ADD R0, R0, R0, LSL #2 ; (R0)*5→R0 例 4: R0中的内容乘10 ADD R0, R0, R0, LSL #2 ; (R0)*10→R0 MOV R0, R0, LSL #1
前导零计数指令 • 功能:CLZ(Count Leading Zeros)指令对Rm中值的低位零(leading zeros)的个数进行计数,结果放到Rd中。若源寄存器全为0,则结果为32。若位[31]为1,则结果为0 • 格式:CLZ {<条件码>} Rd , Rm • 其中: Rd ARM结果寄存器,Rd不允许是R15。 Rm 操作数寄存器。
QADD、QSUB、QDADD和QDSUB指令 • 功能:这四条指令属于DSP增强指令,完成饱和加、饱和减、饱和乘2加、饱和乘2减四种饱和运算功能 • 格式:<操作码>{条件码} Rd, Rm, Rn <操作码>包括:QADD、QSUB、QDADD和QDSUB指令。 其中: Rd 结果寄存器 Rm,Rn 操作数寄存器
说明:饱和运算是DSP指令所特有的功能,对加/减法指令的结果做了如下修改:说明:饱和运算是DSP指令所特有的功能,对加/减法指令的结果做了如下修改: • 如果加/减法指令的结果在-231~231-1之间,饱和运算的结果取加/减法指令的结果。 • 如果加/减法指令的结果大于231-1,饱和运算的结果取最终结果为231-1。 • 如果加/减法指令的结果小于-231,饱和运算的结果取最终结果为-231。 QDADD和QDSUB指令计算SAT(Rm+SAT(Rn*2))。饱和可发生在加倍操作、加法上,或两种情况下同时发生。若饱和仅发生在加倍操作上,则标志Q置位,但最后结果是不饱和的。SAT意为饱和运算。
例子: QADD R0,R1,R9 ;SAT(R1+R9)→R0 QDSUBLT R9,R0,R1 ;SAT(R0-SAT((R9)*2))→R9
5.2.5 ARM转移类指令 • ARM转移类指令完成循环、调用子程序和从ARM状态转向Thumb状态等功能,包括B、BL、BX和BLX指令 。 • 转移/转移带链接类指令 • 转移交换、转移带链接和交换指令BX,BLX
转移/转移带链接类指令 • 功能:B、BL指令完成当前执行指令地址的转移,偏移地址量可以达到32M,BL指令还可以把转移指令后第一条指令的地址放进链接寄存器R14中完成连接作用,通常用来完成子程序的调用 • 格式:B{L} {<条件码>} <Label> 其中:Label 程序相对偏移表达式。
说明:BL(Branch and Link)指令将下一条指令的地址拷贝到R14(LR,链接寄存器),并引起处理器转移到Label。BL指令(L=1) , 等价于先把(PC)→R14,再(PC)+offset →PC。 机器级的B和BL指令限制在当前指令的±225(±32M)字节范围内。但是,即使Label超出了该范围,汇编可以使用这些指令。
例:1) 条件转移 CMP R0 , #5 ; 如果R0小于5; BLT SUB1 ; 则转 SUB1 ; BGE SUB2 ; 否则转 SUB2。 例:2) 程序调用 BL SUB ;调用子程序SUB; …… ; 返回点; SUB ….… ; 子程序入口; MOV PC , R14 ; 执行完返回。 例:3) 执行十次循环 MOV R0 , #10 ; 设置循环次数; LOOP …… SUBS R0 , #1 ; 循环次数减1; BNE LOOP ; 如果循环次数不0 , 继续循环; …. ; 否则结束循环。
转移交换、转移带链接和交换指令BX,BLX • 功能: BX、BLX指令用来支持Thumb指令集,可以使处理器由ARM指令转向执行Thumb指令或者由Thumb指令返回执行ARM指令 • 格式: 1) B{L}X {<条件码>} 寄存器Rm 2) BLX <Label> 其中:Rm 含有转移地址的寄存器。Rm的位[0]不用来作为地址的一部分。若Rm的位[0]为1,则指令将CPSR中的标志T置位,且将目标地址的代码解释为Thumb代码。若Rm的位[0]为0,则位[1]就不能为1
例: 1) 无条件转移 BX R0 ; 按R0内容转移 ; 如果R0[0]为1 ,转Thumb状态 例: 2) Thumb子程序调用 CODE32 ; ARM 代码 …… BLX TSUB ; 调用Thumb 指令TSUB子程序 …… CODE16 ; Thumb 代码执行 TSUB …… ;Thumb 指令TSUB子程序 BX R14 ; 返回ARM 代码
5.2.6 ARM协处理器类指令 ARM协处理器指令完成与协处理器有关的操作,如协处理器内部寄存器之间的数据传送、协处理器与存储器之间的数据传送、协处理器与CPU寄存器之间的数据传送。这些指令依赖于使用的特定的协处理器,协处理器设计者可以自由地按需要设计协处理器的功能,而且这些指令通常借助于汇编器
ARM体系支持16个协处理器 • 针对每个协处理器的指令占用 ARM指令集中的固定部分 • 如果相应的协处理器不存在, 将发生一个未定义指令异常。 • 这有三种协处理器指令 • 协处理器数据处理指令 • CDP:初始化协处理器数据处理操作 • 协处理器寄存器传送指令 • MRC: 从 ARM 寄存器移到协处理器寄存器 • MCR:从协处理器寄存器移到ARM 寄存器 • 协处理器存储器传送指令 • LDC:从存储器装载到协处理器寄存器 • STC:从协处理器寄存器存储到存储器
CDP和CDP2指令(CDP,Coprocessor Data operation) • 功能:完成协处理器寄存器数据操作。 • 格式: CDP {条件码} CP#, opcodel, CRd, CRn, CRm{,opcode2} CDP2 CP#, opcodel, CRd, CRn, CRm{,opcode2} 其中: CP# 指令操作的协处理器名。标准名为pn,n为0~15范围内的整数。 Opcodel 协处理器的特定操作码。 CRn,CRm,CRn 协处理器寄存器。 opcode2 可选的协处理器特定操作码。
例: CDP p1,10,c1,c2,c3 ;协处理器1中的处理器C2和C3完成操作10 然后将结果放在C1中。 CDPEQ p2,5,c1,c2,c3,2 ;如果Z位置1,那么协处理器2中的C2和C3完成操作5(子操作2),然后将结果放在C1中。
LDC和STC指令 • 功能: 在存储器和协处理器之间传送数据 • 格式:1)零偏移格式 LDC | STC{<条件码>} {L} <CP#> , CRd , [Rn ] 2)前变址格式 LDC | STC{<条件码>} {L} <CP#> , CRd , [Rn , #offset ]{!} LDC2 | STC2 <CP#> , CRd , [Rn , #offset ]{!} 3)后变址格式 LDC | STC{<条件码>} {L} <CP#> , CRd , [Rn] , #offset LDC2 |STC2 <CP#> , CRd , [Rn] , #offset
例 1): LDC p6 , CR1 , [R4] ; 将存储器中的内容取至协处理器6寄存器CR1中 R4为所取内容的地址 例 2): LDC p6 , CR4 , [R2 , 4] ; 将存储器中的内容取至协处理器6寄存器CR4中R2+4为所取内容的地址 例 3): STC p8 , CR8 , [R2 , #4] ! ; 将协处理器8寄存器CR8中的内容存至存储器中R2+4为所存内容的地址 然后,R2=R2+4 例 4): STC p6 , CR9 , [R2] , #-16 ; 将协处理器6寄存器CR9中的内容存至存储器中 R2为所存内容的地址 然后,R2=R2-16
MRC、MRC2 、MCR和MCR2指令 • 功能:在协处理器与ARM寄存器之间传送数据 • 格式:1)从协处理器传送至ARM寄存器 MRC{<条件码>} <CP#> , <Opcode1> , Rd , CRn , CRm { , <Opcode2>} MRC2 < CP#> , <Opcode1> , Rd , CRn , CRm { , <Opcode2>} 2)从ARM寄存器传送至协处理器 MCR{<条件码>} < CP#> , <Opcode1> , Rd , CRn , CRm { , <Opcode2>} MCR2 < CP#> , <Opcode1> , Rd , CRn , CRm { , <Opcode2>} • 本组指令格式中所有操作数的含义同(CDP和CDP2)
例1): MRC p15 , 5, R4 , C0 , C2, 3 ; 协处理器15中的寄存器C0和C2完成操作5(子操作3),然后将结果传到CPU寄存器4中。 例2): MCR p14 , 1, R7 , C7 , C12, 6 ; 协处理器14在CPU寄存器7中完成 操作1(子操作6),然后将结果传到协处理器14的寄存器C12中。
MCRR和MRRC指令 • 功能:在2个ARM寄存器和协处理器之间进行数据传送 • 格式: MRRC{<条件码>} < CP#>, <Opcode1>, Rd, CRn, CRm MCRR{<条件码>} < CP#>, <Opcode1>, Rd, CRn, CRm
5.2.7 ARM杂项指令 • 状态寄存器传送至通用寄存器类指令 • 通用寄存器传送至状态寄存器传送指令 • 软件中断指令SWI • 断点指令(v5T)
状态寄存器传送至通用寄存器类指令 • 功能:将状态寄存器的内容传送至通用寄存器 • 格式:MRS{<条件码>} Rd , CPSR | SPSR 其中: Rd 目标寄存器,Rd不允许为R15。 R=0,将CPSR中的内容传送至目的寄存器; R=1,将SPSR中的内容传送至目的寄存器 注释: MRS与MSR配合使用,作为更新PSR的读—修改—写序列的一部分。例如:改变处理器或清除标志Q。 注意:当处理器在用户模式或系统模式下,一定不能试图访问SPSR。
例: MRS R0 , CPSR ;将CPSR中的内容传送至R0 MRS R3, SPSR ;将SPSR中的内容传送至R3
通用寄存器传送至状态寄存器传送指令 • 功能:将通用寄存器的内容传送至状态寄存器 • 格式: MSR{<条件码>} CPSR_f | SPSR_f , < #immed_8r > MSR{<条件码>} CPSR_<field> | SPSR_<field> , Rm • 其中:<field>字段可以是以下之一或多种: C: 控制域屏蔽字段(PSR中的第0位到第7位); X: 扩展域屏蔽字段(PSR中的第8位到第15位); S:状态域屏蔽字段(PSR中的第16位到第23位); F: 标志域屏蔽字段(PSR中的第24位到第31位)。 immed_8r 值为数字常量的表达式。常量必须对应8位位图。该位图在32位字中循环移位偶数位。 Rm 源寄存器。
例1): 设置N、Z、C、V标志 MSR CPSR_f , #&f0000000 ;仅高8位有效,其它必须为0 例2): 仅置位C标志,保留N、Z、V标志 MRS R0 , CPSR ;将CPSR中的内容传送至R0 ORR R0 , R0 , #&20000000 ; 置位R0的第29位 MSR CPSR_f , R0 ;再将R0中的内容传送至CPSR 例3): 从管理模式转到IRQ模式 MRS R0 , CPSR ; 将CPSR中的内容传送至R0 BIC R0 , R0 , #&1f ;清R0的第5位 ORR R0 , R0 , #&12 ;设置IRQ模式的标志位 MSR CPSR_c , R0 ;再将R0中的内容传送至CPSR
软件中断指令SWI • 格式: SWI{<条件码>} immed_24 其中: immed_24 表达式,其值范围为0-224-1的整数(24位整数) 注释: SWI指令用来执行系统调用,处理器进入管理模式,并从地址0x08开始执行指令。<24位立即数>并不影响指令的执行,由系统所解释。CPSR保存到管理模式的SPSR中,执行转移到SWI向量。
断点指令(v5T) • 格式:BKPT immed_16 其中:immed_16 表达式,其值为范围在0~65536内的整数(16位整数)。 注释: 支持软件调试,执行时中断正常指令,进入相应的调试子程序。BKPT指令适用于ARM v5指令系统及以上版本。
5.2.8 XScale指令 • MIA乘法指令 • MIAPH乘法指令 • MIAxy乘法指令 • MAR和MRA内部累加器访问指令
MIA乘法指令 • 功能:MIA乘法指令同MLA乘法指令类似,仅仅是MIA指令将最终结果保存至acc0中 • 格式:MIA {<cond>} acc0 , Rm , Rs 其中:Rs 乘数寄存器 Rm 被乘数寄存器 acc0 累加器0