1 / 87

ARM 指令集与编程

ARM 指令集与编程. 总体介绍:指令分类,特点,格式,条件码 数据处理指令:数据传输指令,算术指令,逻辑指令,比较指令,乘法指令 ( 略 ) ,前导零计数 ( 略 ) 程序状态访问指令 跳转指令 单数据访存指令 多数据访存指令 其它指令:信号量操作指令,异常中断产生指令,协处理器指令 ( 略 ) 伪指令 ( 略 ) 基于 ARM 的编程. 1 总体介绍. 指令分类、特点、格式、条件码. 1.1 指令分类. ARM 指令集总体分为 6 类指令 数据处理指令:数据传输指令,算术指令,逻辑指令,比较指令,乘法指令,前导零计数。

colum
Download Presentation

ARM 指令集与编程

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. ARM指令集与编程 • 总体介绍:指令分类,特点,格式,条件码 • 数据处理指令:数据传输指令,算术指令,逻辑指令,比较指令,乘法指令(略),前导零计数(略) • 程序状态访问指令 • 跳转指令 • 单数据访存指令 • 多数据访存指令 • 其它指令:信号量操作指令,异常中断产生指令,协处理器指令(略) • 伪指令(略) • 基于ARM的编程 ARM指令集与编程

  2. 1 总体介绍 指令分类、特点、格式、条件码

  3. 1.1 指令分类 ARM指令集总体分为6类指令 • 数据处理指令:数据传输指令,算术指令,逻辑指令,比较指令,乘法指令,前导零计数。 • 程序状态访问指令:mrs和msr。 • 跳转指令:b和bl。 • 访存指令:单数据访存指令,多数据访存指令,信号量操作指令。 • 异常中断产生指令:swi和bkpt。 • 协处理器指令。 ARM指令集与编程

  4. 1.2 指令特点 • 所有指令都是32bit。 • 大多数指令都在单周期内完成。 • 所有指令都可以条件执行。 • load/store体系结构。 • 指令集可以通过协处理器扩展 ARM指令集与编程

  5. 31 28 27 25 24 21 20 19 16 15 12 11 8 7 0 Cond 001 Opcode S Rn Rd Operand2 1.3 ARM指令的格式 <Opcode>{<cond>}{s} <Rd>, <Rn>, <Operand2> • Cond:指令的条件码。 • Opcode:指令操作码。 • S:操作是否影响cpsr。 • Rn:包含第一个操作数的寄存器编码。 • Rd:目标寄存器编码。 • Operand2:第2操作数。 ARM指令集与编程

  6. 1.3 ARM指令的格式(续) ARM指令集与编程

  7. 1.4 ARM指令的条件执行 所有的ARM指令可包含一个可选的条件码,只有在cpsr中的条件标志位满足指定的条件时,指令才会被执行。不符合条件的代码依然占用一个时钟周期(相当于一个NOP指令)。 if ( (a == b) && (c == d) ) { e++; } // r0, r1, r2, r3, r4 : a, b, c, d, e cmp r0, r1 cmpeq r2, r3 addeq r4, r4, #1 ARM指令集与编程

  8. 1.4.1 ARM指令的条件域 • EQ/NE: 等于/不等于(equal / not equal) • HS/LO: 无符号数高于或等于/无符号数小于(higher or same/lower) • HI/LS: 无符号数高于/无符号数低于或等于(higher/lower or same) • GE/LT: 有符号数大于或等于/有符号数小于(greater or equal / less than) • GT/LE: 有符号数大于/有符号数小于或等于(greater than / less or equal) • MI/PL: 负/非负 • VS/VC: 溢出/不溢出(overflow set / overflow clear) • CS/CC: 进位/无进位(carry set / carry clear) ARM指令集与编程

  9. 1.4.2 ARM指令的条件码 ARM指令集与编程

  10. 1.4.2 ARM指令的条件码(续) 注:AL是默认的,NV不建议使用。 ARM指令集与编程

  11. 目录 • 总体介绍:指令分类,特点,格式,条件码 • 数据处理指令:数据传输指令,算术指令,逻辑指令,比较指令,乘法指令(略),前导零计数(略) • 程序状态访问指令 • 跳转指令 • 单数据访存指令 • 多数据访存指令 • 其它指令:信号量操作指令,异常中断产生指令,协处理器指令(略) • 伪指令(略) • 基于ARM的编程 ARM指令集与编程

  12. 2 数据处理指令 • 数据传输指令:mov和mvn • 算数指令:add、adc、sub、sbc,rsb和rsc • 逻辑指令:and、orr、eor和bic • 比较指令:cmp、cmn、tst和teq ARM指令集与编程

  13. 2.1 数据处理指令的特点 • 所有的操作数要么来自寄存器,要么来自立即数,不会来自内存。 • 如果有结果,则结果一定是为32位宽,并且放在一个寄存器中,不会写入内存。(有一个例外:长乘法指令产生64位结果) • 每一个操作数寄存器和结果寄存器都在指令中独立指出,即:ARM指令采用3地址模式:<Operation> Rd, Rn, Rm ARM指令集与编程

  14. 31 28 27 25 24 21 20 19 16 15 12 11 8 7 0 Cond 00X opcode S Rn Rd 第 2 操作数 11 8 7 0 方式1:#immed #rot #immed_8 add r0, r1, #0xff 11 4 3 0 方式2:Rm 0 0 0 0 0 0 0 0 Rm 11 8 7 4 3 0 方式3:Rm LSL Rs Rs 0 0 0 0 Rm add r0, r1, r1, LSL r2 11 7 6 4 3 0 方式4:Rm LSL #immed_5 (#immed_5取值范围0-31) #immed_5 shift Rm add r0, r1, r1, LSL #31 2.2 四种寻址方式和s后缀 add r0, r1, r2 ARM指令集与编程

  15. 寄存器,可能需要移位。 • 如需移位,移位值可为: • 5bit的无符号整数(0-31) • 在指令的最低字节指定的另一寄存器 • 立即数 • 8比特数 • 8比特数循环右移偶数位 • 右移位数由汇编器自动计算 2.2.1 四种寻址方式的硬件支持 ARM指令集与编程

  16. 2.2.2 立即数寻址 • ARM指令中的立即数,由一个8bit的常数循环右移偶数位得到: 立即数 =(0->255) 循环右移 2N位 • 例子: • 合法立即数:0x3fc,0x0,0xf0000000,0xf0000001 • 非法立即数:0x1fe,0xffff,0x1010,0xf0000010 ARM指令集与编程

  17. 2.2.2 立即数寻址(续) • 同一个立即数可能有多个表示方法。如: • 0x3f0 = 0x3f 循环右移 28位 • 0x3f0 = 0xfc 循环右移 30位 • 对立即数的编码规则: • 如果立即数在0 – 0xff之间,移位数为0。 • 否则,就取决于编译器了。指令“mov r0, #0x3f0”在ADS1.2中被编译为0xe3a00ffc,在arm-elf-gcc-2.95.3中被编译为0xe3a00e3f。 ARM指令集与编程

  18. 2.2.2 立即数寻址(续) • 对于有互补操作的指令,编译器可以做智能的转换,比如: • mvn r1, 0xffffff00 -> mov r1, 0xff • add r1, r1, #0xffffff00 -> sub r1, r1, #0x100 • adc r1, r1, #0xffffff00 -> sbc r1, r1, #0xff • and r1, r1,#0xffffff00 -> bic r1, r1, #0xff 这样,一些原本非法的立即数也可以正常编译通过。如果一个立即数,经过上述转换后是合法的,那么它也可以用在数据操作指令中。 ARM指令集与编程

  19. 2.2.3 寄存器移位寻址 ASR 算术右移 LSL 逻辑左移 LSR 逻辑右移 ROR 循环右移 RRX 扩展的循环右移 ARM指令集与编程

  20. 2.2.3 寄存器移位寻址(续) • 如果移位的位数由立即数(5bit,取值范围0 - 31)给出,就叫作 immediate specified shift;如果由Rs的低5位决定,就叫做register specified shift。 • Register specified shift的两点问题: • 不能使用pc:如果将pc寄存器用在Rn,Rd,Rm和Rs的位置上时,会产生不可预知的结果。 • 额外代价(overhead):需要更多的周期才能完成指令,因为ARM没有能力一次读取3个寄存器。 • Immediate specified shift 没有上述问题。 ARM指令集与编程

  21. 2.2.3 寄存器移位寻址(续) • 在register specified shift寻址方式下使用pc寄存器,编译器提示如下警告: • 在ADS1.2种编译产生如下警告之一: • Warning A1477W:This register combination results in UNPREDICTABLE behavior • Warning : A1320E: Undefined effect (using PC as Rn or Rm in register specified shift) • Warning : A1319E: Undefined effect (using PC as Rs) • 但是在arm-elf-gcc-2.95.3中没有报告错误。 ARM指令集与编程

  22. 2.2.4 后缀s • 数据处理指令可以选择s后缀,以影响状态标志。但是比较指令(cmp、cmn、tst和teq)不需要后缀s,它们总会直接影响cpsr中的状态标志。 • 在数据操作指令中,除了比较指令以外,其它的指令如果带有s后缀,同时又以pc为目标寄存器进行操作,则操作的同时从spsr恢复cpsr。比如: • movs pc, #0xff /* cpsr = spsr; pc = 0xff */ • adds pc, r1, #0xffffff00 /* cpsr = spsr; pc = r1 + 0xffffff00 */ • ands pc, r1, r2 /* cpsr = spsr; pc = r1 & r2; */ • 如果在user或者system模式下使用带有s后缀的数据操作指令,同时以pc为目标寄存器,那么会产生不可预料的结果。因为user和system模式下没有spsr。 ARM指令集与编程

  23. 2.3 数据传输指令 • 语法 • <Operation>{<cond>}{s} <Rd>, #<immed> • <Operation>{<cond>}{s} <Rd>, <Rm> • <Operation>{<cond>}{s} <Rd>, <Rm>, LSL #<immed_5> • <Operation>{<cond>}{s} <Rd>, <Rm>, LSL <Rs> • 伪代码 if ConditionPassed(cond) then Rd = 第2操作数 if s == 1 and Rd == pc then cpsr == spsr else if s == 1 then set NZCV flags in cpsr ARM指令集与编程

  24. 2.3 数据传输指令(续) • 举例 • mov r0, r1 /* r0 = r1,不修改cpsr */ • mov r0, #0x0 /* r0 = 0,不修改cpsr */ • movs r0, #0x0 /* r0 = 0,同时设置cpsr的Z位 */ • movs r0, #-10 /* r0 = 0xfffffff6,同时设置cpsr的N位 */ • mvn r0, r2 /* r0 = NOT r2,不修改cpsr */ • mvn r0, 0xffffffff /* r0 = 0x0,不修改cpsr */ • mvns r0, 0xffffffff /* r0 = 0x0,同时设置cpsr的Z位 */ • mov r0, r1, LSL #1 /* r0 = r1 << 1 */ • mov r0, r1, LSR r2 /* r0 = r1 >> r2 */ ARM指令集与编程

  25. 2.3 数据传输指令(续) • 说明 • mvn意为“取反传输”,它把源寄存器的每一位取反,将得到的结果写入结果寄存器。 • movs和mvns指令对pc寄存器赋值时有特殊含义,表示要求在赋值的同时从spsr中恢复cpsr。 • 对于mov和mvn指令,编译器会进行智能的转化。比如指令“mov r1, 0xffffff00”中的立即数是非法的。在编译时,编译器将其转化为“mvn r1, 0xff”,这样就不违背立即数的要求。所以对于mov和mvn指令,可以认为:合法的立即数反码也是合法的立即数。 ARM指令集与编程

  26. 2.4 算术指令 • 语法 • <Operation>{<cond>}{s} <Rd>, <Rn>, #<immed> • <Operation>{<cond>}{s} <Rd>, <Rn>, <Rm> • <Operation>{<cond>}{s} <Rd>, <Rn>, <Rm>, LSL #<immed_5> • <Operation>{<cond>}{s} <Rd>, <Rn>, <Rm>, LSL <Rs> • 伪代码(以加法add为例) if ConditionPassed(cond) then Rd = Rn + 第2操作数 if s == 1 and Rd == pc then cpsr = spsr else if s == 1 then set NZCV flags in cpsr ARM指令集与编程

  27. 2.4 算术指令(续) • 举例 • add r0, r1, r2 /* r0 = r1 + r2 */ • adc r0, r1, r2 /* r0 = r1 + r2 + carry */ • sub r0, r1, r2 /* r0 = r1 – r2 */ • sbc r0, r1, r2 /* r0 = r1 – r2 + carry -1 */ • rsb r0, r1, r2 /* r0 = r2 – r1 */ • rsc r0, r1, r2 /* r0 = r2 – r1 + carry – 1 */ • add r0, r1, r1, LSL #31 /* r0 = r1 + r1 << 31 */ • add r0, r1, r1, LSL r2 /* r0 = r1 + r1 << r2 */ • 说明 • adds和adcs在进位时将cpsr的C标志置1;否则置0。 • subs和sbcs在产生借位时将cpsr的C标志置0;否则置1。 ARM指令集与编程

  28. 2.5 逻辑指令 • 语法 • <Operation>{<cond>}{s} <Rd>, <Rn>, #<immed> • <Operation>{<cond>}{s} <Rd>, <Rn>, <Rm> • <Operation>{<cond>}{s} <Rd>, <Rn>, <Rm> LSL #<immed_5> • <Operation>{<cond>}{s} <Rd>, <Rn>, <Rm> LSL <Rs> • 伪代码(以and为例) If ConditionPassed(cond) then Rd = Rn AND 第2操作数 if s == 1 and Rd == pc then cpsr = spsr else if s == 1 then set NZCV flags in cpsr ARM指令集与编程

  29. 2.5 逻辑指令(续) • 举例 • and r0, r1, r2 /* r0 = r1 AND r2 */ • and r1, r1,#0xffffff00 /* r1 = r1 AND 0xffffff00 */ • orr r0, r1, r2 /* r0 = r1 OR r2 */ • eor r0, r1, r2 /* r0 = r1 XOR r2 */ • bic r0, r1, r2 /* r0 = r1 AND NOT r2 */ • bic r1, r1, #0x0f /* 清空r1的低4位 */ • and r0, r1, r1, LSL #31 /* r0 = r1 AND (r1 << 31) */ • and r0, r1, r1, LSR r2 /* r0 = r1 AND (r1 >> r2) */ ARM指令集与编程

  30. 2.6 比较指令 • 语法 • <Operation>{<cond>} <Rn>, #<immed> • <Operation>{<cond>} <Rn>, <Rm> • <Operation>{<cond>} <Rn>, <Rm>, LSL #<immed_5> • <Operation>{<cond>} <Rn>, <Rm>, LSL <Rs> • 伪代码(以cmp为例) If ConditionPassed(cond) then alu_out = Rn – 第2操作数 set NZCV flags in cpsr ARM指令集与编程

  31. 2.6 比较指令(续) • 举例 • cmp r1, r2 /*根据r1 – r2的结果设置cpsr,结果不写回*/ • cmn r1, r2 /*根据r1 + r2的结果设置cpsr,结果不写回*/ • tst r1, r2 /*根据r1 AND r2的结果设置cpsr,结果不写回*/ • teq r1, r2 /*根据r1 XOR r2的结果设置cpsr,结果不写回*/ • cmp r2, #5 /*根据r2 – 5的结果设置cpsr,结果不写回*/ • cmp r1, r2, LSL #5 /* 根据r1 – (r2 << 5)设置cpsr */ • cmp r1, r2, LSL r3 /* 根据r1 – (r2 << r3)设置cpsr */ • 说明 • 如果不考虑结果的写回,cmp、cmn、tst和teq分别等价于subs、adds、ands和eors。 ARM指令集与编程

  32. 目录 • 总体介绍:指令分类,特点,格式,条件码 • 数据处理指令:数据传输指令,算术指令,逻辑指令,比较指令,乘法指令(略),前导零计数(略) • 程序状态访问指令 • 跳转指令 • 单数据访存指令 • 多数据访存指令 • 其它指令:信号量操作指令,异常中断产生指令,协处理器指令(略) • 伪指令(略) • 基于ARM的编程 ARM指令集与编程

  33. 3 程序状态访问指令 • 当需要修改cpsr/spsr的内容时,首先要读取它的值到一个通用寄存器,然后修改某些位,最后将数据写回到状态寄存器。 • cpsr/spsr不是通用寄存器,不能使用mov指令来读写。在ARM处理器中,只有mrs指令可以读取cpsr/spsr;只有msr可以写cpsr/spsr。 ARM指令集与编程

  34. 3.1 读指令mrs • 语法 • mrs{<cond>} <Rd>, cpsr|spsr • 伪代码 if ConditionPassed(cond) then if R == 1 then Rd = spsr else Rd = cpsr ARM指令集与编程

  35. 3.1读指令mrs(续) • 举例 • mrs r0, cpsr /* 读取cpsr到r0 */ • mrs r3, spsr /* 读取spsr到r3 */ • 说明 • user和system模式没有spsr,因此这些模式下不能读取spsr。 ARM指令集与编程

  36. 31 28 27 26 25 24 23 22 21 20 19 16 15 12 11 0 cond 0 0 # 1 0 R 1 0 f s x c 1111 操作数 域屏蔽 cpsr/spsr 11 8 7 0 1 #rot 8位立即数 立即数对准 11 4 3 0 0 0 0 0 0 0 0 0 0 Rm 操作数寄存器 3.2 写指令msr的二进制格式 ARM指令集与编程

  37. 3.2.1 写指令msr的语法 • msr{<cond>} <psr>_<fields>, #<immed> • msr{<cond>} <psr>_<fields>, <Rm> • <immed>表示合法的立即数:8bit循环右移偶数位 • <psr>代表cpsr或spsr • <fields>指定传送的区域,可进一步细分(只能小写) • c 控制域字节(psr[7:0]) • x 扩展域字节(psr[15:8]) • s 状态域字节(psr[23:16]) • f 标志域字节(psr[31:24]) ARM指令集与编程

  38. 3.2.2 写指令msr的伪代码 • 伪代码 if ConditionPassed(cond) then if opcode[25] == 1 operand = 8立即数 Rotate_Right (#rot * 2) else /* opcode[25] == 0 */ operand = Rm if R == 0 then if field_mask[0] == 1 and InAPrivilegeMode() then cpsr[7:0] = operand[7:0] if field_mask[1] == 1 and InAPrivilegeMode() then cpsr[15:8] == operand[15:8] if field_mask[2] == 1 and InAPrivilegeMode() then cpsr[23:16] == operand[23:16] if field_mask[3] == 1 then cpsr[31:24] = operand[31:24] else /* R == 1 */ if field_mask[0] == 1 and CurrentModeHasSPSR() then spsr[7:0] = operand[7:0] if field_mask[1] == 1 and CurrentModeHasSPSR() then spsr[15:8] == operand[15:8] if field_mask[2] == 1 and CurrentModeHasSPSR() then spsr[23:16] == operand[23:16] if field_mask[3] == 1 and CurrentModeHasSPSR() then spsr[31:24] = operand[31:24] ARM指令集与编程

  39. 3.2.3 msr举例和说明 • 举例 • msr cpsr_c, #0xd3 /* 切换到SVC模式*/ • msr cpsr_cxsf, r3 /* cpsr = r3 */ • 说明 • user和system模式没有spsr,因此这些模式下不能对spsr操作。 • 由于权限问题,在user模式下对cpsr[23:0]修改无效。 • 如果使用立即数,要使用合法的立即数。 • 程序不能同过“msr修改cpsr的T位”来完成ARM/Thumb态的切换。必须使用bx指令,因为bx属于分支指令,它会打断流水线,实现处理器状态切换。 • 如果要修改读出的值,仅修改必要的位,其它位保持不变,这样保持了最大兼容性。 ARM指令集与编程

  40. 目录 • 总体介绍:指令分类,特点,格式,条件码 • 数据处理指令:数据传输指令,算术指令,逻辑指令,比较指令,乘法指令(略),前导零计数(略) • 程序状态访问指令 • 跳转指令 • 单数据访存指令 • 多数据访存指令 • 其它指令:信号量操作指令,异常中断产生指令,协处理器指令(略) • 伪指令(略) • 基于ARM的编程 ARM指令集与编程

  41. 4 跳转指令 • 语法 • b{<cond>} label • bl{<cond>} label • 说明 • 寻址范围 +32MB ARM指令集与编程

  42. 4 跳转指令(续) • 当转移指令执行时,处理器将指令中的offset(24bit)左移2bit,变成26bit,表示+ 32M的范围。 • pc从新的地址执行,流水线重新填充。 • 如果是“bl”指令,将返回地址写入lr寄存器。子程序返回时只需要用lr恢复pc就可以: • mov pc, lr • “b”指令不影响lr寄存器 ARM指令集与编程

  43. 目录 • 总体介绍:指令分类,特点,格式,条件码 • 数据处理指令:数据传输指令,算术指令,逻辑指令,比较指令,乘法指令(略),前导零计数(略) • 程序状态访问指令 • 跳转指令 • 单数据访存指令 • 多数据访存指令 • 其它指令:信号量操作指令,异常中断产生指令,协处理器指令(略) • 伪指令(略) • 基于ARM的编程 ARM指令集与编程

  44. 5 单数据访存指令 • 第一类: • 读写字: ldr / str • 读写无符号字节: ldrb / strb • 第二类: • 读写无符号半字: ldrh / strh • 读有符号半字: ldrsh • 读有符号字节: ldrsb ARM指令集与编程

  45. 31 28 27 26 25 24 23 22 21 20 19 16 15 12 11 8 7 0 cond 01 I P U B W L Rn Rd 第 2 操作数 0/1 : 立即数(方式1)/寄存器(方式2,3) 0/1 : str/ldr 0/1 : 无/有(!) 0/1 : 后变址/前变址 0/1 : 字/无符号字节 11 0 0/1 : 加/减(第2操作数) 方式1:#immed_12(取值范围0 – 0xfff) 例子:ldr r0, [r1, #+0xfff] #immed_12 11 4 3 0 方式2:Rm 例子:ldr r0, [r1, +r2] 0 0 0 0 0 0 0 0 0 0 Rm 11 7 6 5 4 3 0 方式3:Rm LSL #immed_5(取值范围0-31) 例子:ldr r0, [r1, r2 LSL #31] #immed_5 shift 0 Rm 5.1 第一类指令的指令格式 ARM指令集与编程

  46. 5.2 第一类指令的语法 • 语法 • ldr|str{<cond>}{b} <Rd>, [<Rn>, #+<immed_12]{!} • ldr|str{<cond>}{b} <Rd>, [<Rn>, +<Rm>]{!} • ldr|str{<cond>}{b} <Rd>, [<Rn>, +<Rm>, <shift> #<immed_5>]{!} • ldr|str{<cond>}{b} <Rd>, [<Rn>], #+<immed_12 • ldr|str{<cond>}{b} <Rd>, [<Rn>], +<Rm> • ldr|str{<cond>}{b} <Rd>, [<Rn>], +<Rm>, <shift> #<immed_5> • 举例 • ldrb r0, [r1, #+0xfff] /* 把r1+0xfff地址的字节读入r0 */ • ldr r0, [r1, +r2]! /*把r1+r2地址的32比特数读入r0,然后r1= r1+r2 */ • str r0, [r1, +r2, LSL #31] /* 把r0(32bit)写到地址r1+(r2<<31) */ • ldr r0, [r1], #+0xfff /* 把r1地址的数读入r0,然后r1=r1+0xfff */ • ldr r0, [r1], +r2 /* 把r1地址的数读入r0,然后r1=r1+r2 */ • ldr r0, [r1], +r2, LSL #31 /* 把r1地址的数读入r0,然后r1=r1+(r2<<31) */ ARM指令集与编程

  47. 5.2 第一类指令说明 • 说明 • ldr / str 读/写一个32bit字到/从一个32bit的寄存器,要求读/写地址字对齐。 • ldrb:读一个8bit字节到一个32bit的寄存器,不要求地址对齐,寄存器的高24位清零。 • strb:将寄存器的低8位,写入内存的某个地址。不要求地址对齐。 ARM指令集与编程

  48. 5.3 第二类指令 • 语法 • 同第一类指令 • 说明 • ldrh:读取16bit半字到一个32bit寄存器,要求地址半字对齐,目标寄存的高16bit清零。 • strh:将寄存器的低16bit存放到内存中,要求地址半字对齐。 • ldrsh:将内存中的一个16bit半字读到一个32bit寄存器中,要求地址半字对齐。寄存器高16bit根据符号位扩展。 • ldrsb:将内存中的一个8bit字节读到一个32bit寄存器中,寄存器高24bit根据符号位扩展。不要求地址对齐。 ARM指令集与编程

  49. 31 28 27 26 25 24 23 22 21 20 19 16 15 12 11 8 7 0 cond 01 I P U B W L Rn Rd 第 2 操作数 0/1 : 立即数(方式1)/寄存器(方式2,3) 0/1 : str/ldr 0/1 : 无/有(!) 0/1 : 后变址/前变址 0/1 : 字/无符号字节 11 0 0/1 : 加/减(第2操作数) 方式1:#immed_12(取值范围0 – 0xfff) 例子:ldr r0, [r1, #+0xfff] #immed_12 11 4 3 0 方式2:Rm 例子:ldr r0, [r1, +r2] 0 0 0 0 0 0 0 0 0 0 Rm 11 7 6 5 4 3 0 方式3:Rm LSL #immed_5(取值范围0-31) 例子:ldr r0, [r1, r2 LSL #31] #immed_5 shift 0 Rm 5.4 前/后变址 ARM指令集与编程

  50. 5.4.1 简单的基址寻址 • 基址寄存器数据访问 • str r0, [r1] ldr r2, [r1] ARM指令集与编程

More Related