400 likes | 750 Views
ARM 及 Thumb 指令集. 课程安排. ARM 指令集 Thumb 指令集 v5TE 体系结构扩展. ARM 指令编码格式. 31 28 27 25 24 21 20 19 16 15 12 11 8 7 0. 说明 Cond 指令执行的条件编码 Opcode 指令操作符编码 S 决定指令的操作是否影响 CPSR 的值 Rd 操作目标寄存器编码 Rn 包含第一操作数的寄存器编码 Shifter_operand 表示第二操作数.
E N D
课程安排 • ARM指令集 Thumb指令集 v5TE体系结构扩展
ARM指令编码格式 31 28 2725 24 21 20 19 16 15 12 11 8 7 0 • 说明 • Cond • 指令执行的条件编码 • Opcode • 指令操作符编码 • S • 决定指令的操作是否影响CPSR的值 • Rd • 操作目标寄存器编码 • Rn • 包含第一操作数的寄存器编码 • Shifter_operand • 表示第二操作数
条件执行及标志位 R1减1,并设置标志位 如果 Z标志清零则跳转 • ARM指令可以通过添加适当的条件码后缀来达到条件执行的目的。 • 这样可以提高代码密度,减少分支跳转指令数目,提高性能。 CMP r3,#0 CMP r3,#0 BEQ skip ADDNE r0,r1,r2 ADD r0,r1,r2skip • 默认情况下,数据处理指令不影响条件码标志位,但可以选择通过添加“S”来影响标志位。 CMP不需要增加 “S”就可改变相应的标志位。 loop … SUBS r1,r1,#1 BNE loop
Condition Codes Suffix 描述 测试的标志位 EQ 等于(Equal) Z=1 NE 不等于(Not equal) Z=0 CS/HS 无符号的大于或等于 C=1 CC/LO 无符号的小于 C=0 MI 负数(Minus) N=1 PL 正数或零 N=0 VS 溢出(Overflow) V=1 VC 没溢出 V=0 HI 无符号的大于 C=1 & Z=0 LS 无符号的小于或大于 C=0 or Z=1 GE 大于等于 N=V LT 小于(Less Than) N!=V GT 大于(Greater Than) Z=0 & N=V LE 小于等于 Z=1 or N=!V AL 总是执行(Always) • 下表为所有可能的条件码: • 注意:AL为默认状态,不需要单独指出
条件执行示例 • 一系列的指令都使用条件指令 if (a==0) func(1); CMP r0,#0MOVEQ r0,#1BLEQ func • 置标志位,再使用不同的条件码 if (a==0) x=0;if (a>0) x=1; CMP r0,#0MOVEQ r1,#0MOVGT r1,#1 • 使用条件比较指令 if (a==4 || a==10) x=0; CMP r0,#4CMPNE r0,#10MOVEQ r1,#0
分支指令 • Branch : B{<cond>} label • Branch with Link : BL{<cond>} subroutine_label • 处理器把偏移量左移两位,进行符号扩展后再与PC相加 • 跳转范围:± 32 Mbyte • 如何执行长跳转? 31 28 27 25 24 23 0 Cond 1 0 1 L 偏移量 Link bit 0 = Branch 1 = Branch with link 条件码区域
数据处理指令 • 包括: • 算术指令: ADD ADC SUB SBC RSB RSC • 逻辑指令: AND ORR EOR BIC • 比较指令: CMP CMN TST TEQ • 数据搬移: MOV MVN • 上述指令只能对寄存器操作,不能针对存储器。 • 语法: <操作>{<cond>}{S} Rd, Rn, Operand2 • 只有比较指令影响标志位 -不指定Rd • 数据搬移不指定Rn • 第二个操作数通过桶型移位器送到ALU中。
桶型移位器 LSL : Logical Left Shift ASR: Arithmetic Right Shift Destination Destination CF CF 0 (无符号数)乘2 除2,并保留符号位 LSR : Logical Shift Right ROR: Rotate Right Destination Destination CF CF ...0 (无符号数)除2 位循环 RRX: Rotate Right Extended Destination CF 位轮换,从 CF到MSB都参与操作
桶型移位器:第二个操作数 操作数2 操作数1 BarrelShifter ALU 寄存器, 可选择是否增加移位操作. • 移位值可以是: • 5 bit 无符号整数 • 放在另一个寄存器的低字节 • 用于常数乘法 立即数 • 8 bit ,大小范围0-255。 • 右移偶数位 • 允许直接加载32-bit 常数到寄存器中。 结果
立即数 (1) • 没有任何一条ARM 指令可包括一个32 bit的立即数 • 所有的ARM指令都是32 bits固定长度 • 数据处理指令格式中,第二个操作数有12位 • 4 bit 移位值 (0-15)乘于2,得到一个范围在0-30,步长为 2的移位值。 • 记住一条准则: “最后8位一定要移动偶数位”. 11 8 7 0 rot immed_8 Quick Quiz:0xe3a004ffMOV r0, #??? x2 ShifterROR
立即数 (2) • Examples: • 下列命令中,汇编器把立即数转换为移位操作: • MOV r0,#4096 ; uses 0x40 ror 26 • ADD r1,r2,#0xFF0000 ; uses 0xFF ror 16 • 也可使用 MVN来进行位反转: • MOV r0, #0xFFFFFFFF ; assembles to MVN r0,#0 • 使用无法用上述方法生成的数据,将产生错误 。 31 0 ror #0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 range 0-0x000000ff step 0x00000001 ror #8 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 range 0-0xff000000 step 0x01000000 ror #30 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 range 0-0x000003fc step 0x00000004
装载32 bit常数 • 为允许装载大常数,汇编器提供了一条伪指令: • LDR rd, =const • 它可能汇编成下列指令: • MOV or MVN。 或 • LDR指令,从数据池(Literal pools)读取常数。 • For example • LDR r0,=0xFF=>MOV r0,#0xFF • LDR r0,=0x55555555=>LDR r0,[PC,#Imm12]… … DCD 0x55555555 • 推荐使用这种方法把常数装入寄存器 。
Quiz #1 • 1. 写一条 ARM 指令,分别完成下列操作: a) r0 = 16 b) r0 = r1 / 16 (带符号的数字) c) r1 = r2 * 3 d) r0 = -r0 • 2. 下面哪些立即数是数据处理指令中有效的数据? a) 0x00AB0000 b) 0x0000FFFF c) 0xF000000F d) 0x08000012 e) 0x00001f80 f) 0xFFFFFFFF • 3. BIC指令做什么用? • 4. 为什么ARM 处理器增加了一条RSB 指令?
Quiz #2 - GCD • 新建一个 ‘ARM Executable Image’ 项目 • 新建一个 text文件 • 另存为 “gcd.s” • 加入到项目中 • Build 并执行 Start Yes r0 = r1? Stop No AREA myarea, CODE ENTRY MOV r0, #9 MOV r1, #15 start ; your code here stop B stop END r0 > r1? Yes No r0 = r0 - r1 r1 = r1 - r0 你只需要使用CMP、SUB和B指令。 充分使用条件执行! 大家可以尝试计算 2109 和 4161 的GCD
乘法 • 语法: • MUL{<cond>}{S} Rd, Rm, Rs Rd = Rm * Rs • MLA{<cond>}{S} Rd,Rm,Rs,Rn Rd = (Rm * Rs) + Rn • [U|S]MULL{<cond>}{S} RdLo, RdHi, Rm, Rs RdHi,RdLo := Rm*Rs • [U|S]MLAL{<cond>}{S} RdLo, RdHi, Rm, Rs RdHi,RdLo := (Rm*Rs)+RdHi,RdLo • 占用的周期数 • 基本 MUL 指令 • ARM7TDMI 上为2-5 周期 • StrongARM/XScale上为1-3 周期 • ARM9E/ARM102xE上为2 周期 • ARM9TDMI 比 ARM7TDMI多1 周期 • 累加再多1 周期 (不针对9E,尽管结果延迟多于1周期) • 对于“long”型数据,多1 周期 • 以上均为一般规则,确切细节查看相应手册。
单寄存器数据传送 LDR STR Word LDRB STRB Byte LDRH STRH Halfword LDRSB 带符号的byte load LDRSH 带符号的halfword load • 存储器系统必须支持所有访问宽度 • 语法: • LDR{<cond>}{<size>} Rd, <address> • STR{<cond>}{<size>} Rd, <address> e.g. LDREQB
地址访问 • LDR/STR访问的地址由基址寄存器加上偏移量来产生。 • 针对word和无符号byte 的访问, 偏移量可以是: • 一个无符号12-bit立即数 (如 0 - 4095 bytes).LDR r0,[r1,#8] • 一个寄存器,或再加上移位(由立即数指定)LDR r0,[r1,r2] LDR r0,[r1,r2,LSL#2] • 可以是从基址寄存器上加或减去偏移量:LDR r0,[r1,#-8] LDR r0,[r1,-r2] LDR r0,[r1,-r2,LSL#2] • 对于halfword和带符号的halfword / byte, 偏移量可以是: • 一个无符号8 bit 立即数 (如 0-255 bytes). • 一个寄存器 (不能偏移)。 • 可选择采用pre-indexed或post-indexed方式寻址
Pre or Post Indexed 寻址? • Pre-indexed: STR r0,[r1,#12] r0 偏移量 源寄存器for STR 0x5 12 0x5 0x20c r1 基址寄存器 0x200 0x200 通过STR r0,[r1,#12]!来自动更新基址寄存器 • Post-indexed: STR r0,[r1],#12 r1 偏移量 更新基址寄存器 0x20c 12 0x20c r0 源寄存器for STR 0x5 原基址寄存器 r1 0x5 0x200 0x200
Quiz #3 - Total of array • 编写一个ARM汇编程序,累加一个队列中的所有元素,碰上0时停止。结果放入 r4。 • 在源文件末尾按如下方式声明队列: myarray DCD 0x11 DCD 0x22 DCD 0 • 用r0指向队列的入口 ADR r0,myarray • 使用LDR r1,[r0],#4从队列中装载数据 • 累加并放入r4 • 循环,直到r1为0 • 停止,进入死循环 0 0x22 地址增加 r0 0x11
块数据传送 • LDM / STM指令允许一次传送1到16个寄存器到/从存储器中。 • 寄存器传送顺序不能被指定 • 最小数字的寄存器总是被传送到/从存储器的最低地址上。 LDMIA r10,{r0,r1,r4} • 基址寄存器指定存储器访问开始的地址 • 快传送指令针对下列情况很有效: • 从存储器中搬运一块数据 • 保存或恢复堆栈中的内容 • 如果是慢速存储器,会影响中断响应时间 r4 r1 地址增加 r10 r0
LDM / STM 操作 • 语法: <LDM|STM>{<cond>}<addressing_mode> Rb{!}, <寄存器 list> • 4 中寻址操作: LDMIA / STMIAIncrement After(先操作,后增加) LDMIB / STMIBIncrement Before(先增加,后操作) LDMDA / STMDADecrement After (先操作,后递减) LDMDB / STMDBDecrement Before (先递减,后操作) IA IB DA DB LDMxx r10, {r0,r1,r4} STMxx r10, {r0,r1,r4} r4 r4 r1 地址 增加 r1 r0 基址寄存器 (Rb) r10 r0 r4 r1 r4 r0 r1 r0
存储器块拷贝 • 可选项“ ! ”将导致LDM / STM指令去自动更新基址寄存器 • 后缀为IA, IB时,加上4 乘以 用于传送的寄存器的数目的值 • 后缀为DA, DB时,减去4乘以用于传送的寄存器的数目的值 • 示例: ; r12指向源数据起始地址 ; r14指向源数据尾地址 ; r13指向目的数据起始地址 loop LDMIA r12!, {r0-r11} ; 装载48 bytes STMIA r13!, {r0-r11} ;和存储them CMP r12, r14 ; check for the end BNE loop ;和loop until done • 此循环传送 48 bytes占用了31周期 • 时钟为33 MHz时传输速率超过50 Mbytes/sec 存储器增加 r13 r14 r12
堆栈 LDMFD sp!,{r4-r7,pc} 存储器顶 9753 9753 8420 8420 pc 9020 1234 Old SP 1234 pc 8034 lr 9048 lr 8034 1010 SP 1010 8034 8034 FFFF A0BE 8034 AOBE r7 12 r7 A0BE 16 1234 1234 r6 0 r6 1234 102E FF FF r5 14544 r5 FF SP 8765 100 SP 100 r4 1 r4 100 ABCD SP 100 r4 100 A0BE r7 A0BE FF r5 FF 1234 r6 1234 • ARM堆栈操作通过块传送指令来完成: • STMFD(Push) 块存储- Full Descending stack [STMDB] • LDMFD(Pop) 块装载- Full Descending stack [LDMIA] STMFD sp!,{r4-r7,lr} 8034 A0BE 1234 FF 100
SWP 1 2 3 • 在寄存器和存储器之间,由一次存储器读和一次存储器写组成的原子操作。完成一个字节或字的交换。 • 语法: • SWP{<cond>}{B} Rd, Rm, [Rn] • 可用作信号量 • 不能由armcc编译产生,必须使用汇编器。 Rn temp Rd Rm 存储器
软件中断 (SWI) 0 • 产生一个异常陷阱,跳转到SWI 硬件向量。 • SWI 处理程序可以检测SWI号,从而决定采取何种操作。 • 通过SWI机制,运行在用户模式下的应用程序,可请求操作系统执行一系列特权操作。 • 语法: • SWI{<cond>} <SWI number> 31 28 27 24 23 Cond 1 1 1 1 SWI number (ignored by processor) 条件域
PSR 传送指令 31 28 27 24 23 16 15 8 7 6 5 4 0 N Z C V Q I F T mode U n d e f i n e d J f s x c • MRS和MSR允许传送CPSR / SPSR中的内容到/从一个通用寄存器中。 • 语法: • MRS{<cond>} Rd,<psr> ; Rd = <psr> • MSR{<cond>} <psr[_fields]>,Rm ; <psr[_fields]> = Rm 在这里: • <psr> = CPSR or SPSR • [_fields] = ‘fsxc’的任意组合 • 也允许送一个立即数到psr_fields • MSR{<cond>} <psr_fields>,#Immediate • 用户模式下,所有位均可以被读取,但只有条件标志位 (_f)可被写。
协处理器指令 • ARM体系支持16个协处理器 • 针对每个协处理器的指令占用 ARM指令集中的固定部分 • 如果相应的协处理器不存在, 将发生一个未定义指令异常。 • 这有三种协处理器指令 • 协处理器数据处理指令 • CDP:初始化协处理器数据处理操作 • 协处理器寄存器传送指令 • MRC: 从 ARM 寄存器移到协处理器寄存器 • MCR:从协处理器寄存器移到ARM 寄存器 • 协处理器存储器传送指令 • LDC:从存储器装载到协处理器寄存器 • STC:从协处理器寄存器存储到存储器
Quiz #4 • 1. 写几条ARM 指令,使能IRQ中断 • 2. 下列 ARM 指令将做什么? a)LDRH r0,[r1,#6] b)LDR r0, =0x999 • 3.在装载或存储指令中, “!”表示什么? • 4. 当 执行SWI 指令时,会发生什么? • 5. SWP 指令的优势是什么?
Agenda ARM 指令集 • Thumb 指令集 v5TE体系结构扩展
Thumb • Thumb 是16-bit 指令集 • 代码密度优化 (总代码大小约为ARM指令的65%) • 使用窄总线存储器时可以大大提高性能。 • 是 ARM 指令集的一个子集。 • 核存在一个执行状态 – Thumb状态 • ARM和Thumb之间切换使用BX 指令 31 32-bit ARM 指令 0 ADDS r2,r2,#1 • 对于由编译器产生的大部分指令: • 没有条件执行 • 源、目的寄存器必须相同 • 仅能使用低寄存器 • 常数大小有限制 • 不能使用在线移位器 16-bit Thumb 指令 15 0 ADD r2,#1
ARM / Thumb Interworking • 使用Branch Exchange指令来完成 Interworking • BX Rn; Thumb 状态下的Bx指令 • BX<condition> Rn; ARM状态下的Bx指令 • 也可以只是执行一个绝对跳转,无须状态更换。 31 1 0 Rn ARM / Thumb 选择 0 - ARM 状态 1 - Thumb 状态 31 1 0 BX跳转的地址 0
写 Thumb汇编程序 • Thumb不是一个“好”指令集! • 最好用编译器来产生 • 约束并不一致 • 手动编码使用ARM指令集比较好 • 更多细节,参看: • ARM “Architecture Reference Manual” • Chapters A6和A7
Agenda ARM 指令集 Thumb 指令集 • v5TE体系结构扩展
v5TE结构 • v5TE体系包括全部的 v4T ARM和Thumb 指令集,还有: • 增强的interworking • 同时支持ARM / Thumb状态 • Breakpoint 指令 (ARM和Thumb) • CLZ(Count Leading Zeros)指令 • 扩展协处理器指令 - MCR2等等 • 支持饱和处理 • 封装的带符号的半字乘法指令 • 双字装载/ 存储指令 • Cache预装载指令 • 双字协处理器 传送指令 - MCRR/MRRC
你采用的处理器是哪种结构? • 处理器核 结构体系 7TDMI & 9TDMI v4T 9E-S rev1 v5TE 926EJ-S/1026EJ-S v5TEJ 1020E v5TE StrongARM v4 XScale Microarchitecture v5TE
Count Leading Zeros • CLZ{cond} Rd, Rm • 计算寄存器中的前导0(第一个1以前的0) • 源寄存器从最高位开始计算。 • 1个周期完成 (ARM9E-S/ARM102x) • 如果没有任何一位被置位,结果是32;如果 bit 31被置位,结果为0。 • Rm 左移 Rd位即可标准化Rm • 带符号的标准化需要额外的 1个周期 R0 = 0000 0010 1110 1101...0 CLZ R1, R0 0x6 R1 = MOV R0, R0 LSL R1 Rm = 1011 1011 0100 0000...0 EOR R1, R0, R0, LSL#1 CLZ R1, R1 MOV R0, R0, LSL R1
扩展协处理器指令 • CDP2, LDC2, STC2, MCR2, MRC2 • 新格式的标准协处理器指令为协处理器设计人员提供了附加的操作码空间。 • 同样是无条件执行的
参考材料 • ARM “Architecture Reference Manual” - 2nd editionedited by David Seal • ARM DDI 0100E is latest, covering v5TE DSP extensions • ISBN 0-201-737191 (Addison-Wesley) • PDF on ADS和‘Technical Documentation’ CDs • Steve Furber “ARM 系统-on-chip architecture” - 2nd edition • ISBN 0-201-67519-6 (Addison-Wesley) • Quick Reference Card • ARM QRC 0001E comes with ADS 1.2 • ADS 1.2 Assembler Guide • refers to ADS Examples directory