ARM指令集与编程_第1页
ARM指令集与编程_第2页
ARM指令集与编程_第3页
ARM指令集与编程_第4页
ARM指令集与编程_第5页
已阅读5页,还剩82页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

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

2、:单数据访存指令,多数据访存指令,信号量操作指令。 异常中断产生指令:swi和bkpt。 协处理器指令。ARM指令集与编程41.2 指令特点 所有指令都是32bit。 大多数指令都在单周期内完成。 所有指令都可以条件执行。 load/store体系结构。 指令集可以通过协处理器扩展ARM指令集与编程51.3 ARM指令的格式s , , Cond:指令的条件码。 Opcode:指令操作码。 S:操作是否影响cpsr。 Rn:包含第一个操作数的寄存器编码。 Rd:目标寄存器编码。 Operand2:第2操作数。Cond001OpcodeSRnRdOperand2011121516192021242

3、527283178ARM指令集与编程61.3 ARM指令的格式(续)ARM指令集与编程71.4 ARM指令的条件执行所有的ARM指令可包含一个可选的条件码,只有在cpsr中的条件标志位满足指定的条件时,指令才会被执行。不符合条件的代码依然占用一个时钟周期(相当于一个NOP指令)。/ r0, r1, r2, r3, r4 : a, b, c, d, ecmpr0, r1cmpeq r2, r3addeq r4, r4, #1if ( (a = b) & (c = d) ) e+;ARM指令集与编程81.4.1 ARM指令的条件域EQ/NE: 等于/不等于(equal / not equa

4、l)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指令集与编程

5、91.4.2 ARM指令的条件码0000EQZ置位相等/等于00001NEZ清0不等0010CS/HSC置位进位/无符号高于或等于0011CC/LOC清0无进位/无符号低于0100MIN置位负数0101PLN清0非负数0110VSV置位溢出0111VCV清0无溢出ARM指令集与编程101.4.2 ARM指令的条件码(续)1000HIC置位且Z清0无符号高于1001LSC清0或Z置位无符号低于或等于1010GEN等于V有符号大于或等于1011LTN不等于V有符号小于1100GTZ清0且N等于V有符号大于1101LEZ置位或N不等于V有符号小于或等于1110AL任何状态总是(always)1111

6、NV无从不(never)注:AL是默认的,NV不建议使用。ARM指令集与编程11目录1.总体介绍:指令分类,特点,格式,条件码2.数据处理指令:数据传输指令,算术指令,逻辑指令,比较指令,乘法指令(略),前导零计数(略)3.程序状态访问指令4.跳转指令5.单数据访存指令6.多数据访存指令7.其它指令:信号量操作指令,异常中断产生指令,协处理器指令(略)8.伪指令(略)9.基于ARM的编程ARM指令集与编程122 数据处理指令 数据传输指令:mov和mvn 算数指令:add、adc、sub、sbc,rsb和rsc 逻辑指令:and、orr、eor和bic 比较指令:cmp、cmn、tst和teq

7、ARM指令集与编程132.1 数据处理指令的特点 所有的操作数要么来自寄存器,要么来自立即数,不会来自内存。 如果有结果,则结果一定是为32位宽,并且放在一个寄存器中,不会写入内存。(有一个例外:长乘法指令产生64位结果) 每一个操作数寄存器和结果寄存器都在指令中独立指出,即:ARM指令采用3地址模式: Rd, Rn, RmARM指令集与编程142.2 四种寻址方式和s后缀add r0, r1, r2add r0, r1, #0 xffadd r0, r1, r1, LSL r2CondSRnRd第第 2 操作数操作数078111215161920opcode212400X25272831#i

8、mmed_8#rot078110 0 0 0 0 0 0 0Rm03411方式1:#immed方式2:Rm0 0 0 0 Rm03411Rs78方式3:Rm LSL RsshiftRm03411#immed_567方式4:Rm LSL #immed_5(#immed_5取值范围0-31)add r0, r1, r1, LSL #31ARM指令集与编程152.2.1 四种寻址方式的硬件支持寄存器,可能需要移位。如需移位,移位值可为:5bit的无符号整数(0-31)在指令的最低字节指定的另一寄存器立即数 8比特数8比特数循环右移偶数位右移位数由汇编器自动计算ARM指令集与编程162.2.2 立即数

9、寻址 ARM指令中的立即数,由一个8bit的常数循环右移偶数位得到:立即数 =(0-255) 循环右移 2N位 例子: 合法立即数:0 x3fc,0 x0,0 xf0000000,0 xf0000001 非法立即数:0 x1fe,0 xffff,0 x1010,0 xf0000010ARM指令集与编程172.2.2 立即数寻址(续) 同一个立即数可能有多个表示方法。如: 0 x3f0 = 0 x3f 循环右移 28位 0 x3f0 = 0 xfc 循环右移 30位 对立即数的编码规则: 如果立即数在0 0 xff之间,移位数为0。 否则,就取决于编译器了。指令“mov r0, #0 x3f0”

10、在ADS1.2中被编译为0 xe3a00ffc,在arm-elf-gcc-2.95.3中被编译为0 xe3a00e3f。ARM指令集与编程182.2.2 立即数寻址(续) 对于有互补操作的指令,编译器可以做智能的转换,比如: mvn r1, 0 xffffff00-mov r1, 0 xff add r1, r1, #0 xffffff00 -sub r1, r1, #0 x100 adc r1, r1, #0 xffffff00 -sbc r1, r1, #0 xff and r1, r1,#0 xffffff00 -bic r1, r1, #0 xff这样,一些原本非法的立即数也可以正常编

11、译通过。如果一个立即数,经过上述转换后是合法的,那么它也可以用在数据操作指令中。ARM指令集与编程192.2.3 寄存器移位寻址ASR 算术右移LSL 逻辑左移LSR 逻辑右移ROR循环右移RRX扩展的循环右移ARM指令集与编程202.2.3 寄存器移位寻址(续) 如果移位的位数由立即数(5bit,取值范围0 - 31)给出,就叫作 immediate specified shift;如果由Rs的低5位决定,就叫做register specified shift。 Register specified shift的两点问题: 不能使用pc:如果将pc寄存器用在Rn,Rd,Rm和Rs的位置上时,

12、会产生不可预知的结果。 额外代价(overhead):需要更多的周期才能完成指令,因为ARM没有能力一次读取3个寄存器。 Immediate specified shift 没有上述问题。ARM指令集与编程212.2.3 寄存器移位寻址(续) 在register specified shift寻址方式下使用pc寄存器,编译器提示如下警告: 在ADS1.2种编译产生如下警告之一: Warning A1477W:This register combination results in UNPREDICTABLE behavior Warning : A1320E: Undefined effect

13、 (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指令集与编程222.2.4 后缀s 数据处理指令可以选择s后缀,以影响状态标志。但是比较指令(cmp、cmn、tst和teq)不需要后缀s,它们总会直接影响cpsr中的状态标志。 在数据操作指令中,除了比较指令以外,其它的指令如果带有s后缀,同时又以pc为目标寄存器进行操作,则操作的同时从spsr恢复cpsr。比如: movs

14、 pc, #0 xff/* cpsr = spsr; pc = 0 xff */ adds pc, r1, #0 xffffff00 /* cpsr = spsr; pc = r1 + 0 xffffff00 */ ands pc, r1, r2/* cpsr = spsr; pc = r1 & r2; */ 如果在user或者system模式下使用带有s后缀的数据操作指令,同时以pc为目标寄存器,那么会产生不可预料的结果。因为user和system模式下没有spsr。ARM指令集与编程232.3 数据传输指令语法 s , # s , s , , LSL # s , , LSL 伪代码

15、if ConditionPassed(cond) thenRd = 第2操作数if s = 1 and Rd = pc thencpsr = spsrelse if s = 1 thenset NZCV flags in cpsrARM指令集与编程242.3 数据传输指令(续)举例 mov r0, r1/* r0 = r1,不修改cpsr */ movr0, #0 x0/* r0 = 0,不修改cpsr */ movsr0, #0 x0/* r0 = 0,同时设置cpsr的Z位 */ movsr0, #-10 /* r0 = 0 xfffffff6,同时设置cpsr的N位 */ mvnr0,

16、r2/* r0 = NOT r2,不修改cpsr */ mvnr0, 0 xffffffff/* r0 = 0 x0,不修改cpsr */ mvnsr0, 0 xffffffff/* r0 = 0 x0,同时设置cpsr的Z位 */ movr0, r1, LSL #1/* r0 = r1 r2 */ARM指令集与编程252.3 数据传输指令(续) 说明 mvn意为“取反传输”,它把源寄存器的每一位取反,将得到的结果写入结果寄存器。 movs和mvns指令对pc寄存器赋值时有特殊含义,表示要求在赋值的同时从spsr中恢复cpsr。 对于mov和mvn指令,编译器会进行智能的转化。比如指令“mov

17、 r1, 0 xffffff00”中的立即数是非法的。在编译时,编译器将其转化为“mvn r1, 0 xff”,这样就不违背立即数的要求。所以对于mov和mvn指令,可以认为:合法的立即数反码也是合法的立即数。ARM指令集与编程262.4 算术指令语法 s , , # s , , s , , , LSL # s , , , LSL 伪代码(以加法add为例)if ConditionPassed(cond) thenRd = Rn + 第2操作数if s = 1 and Rd = pc thencpsr = spsrelse if s = 1 thenset NZCV flags in cpsr

18、ARM指令集与编程272.4 算术指令(续) 举例 addr0, r1, r2 /* r0 = r1 + r2 */ adc r0, r1, r2/* r0 = r1 + r2 + carry */ subr0, r1, r2 /* r0 = r1 r2 */ sbcr0, r1, r2/* r0 = r1 r2 + carry -1 */ rsbr0, r1, r2/* r0 = r2 r1 */ rscr0, r1, r2/* r0 = r2 r1 + carry 1 */ addr0, r1, r1, LSL #31/* r0 = r1 + r1 31 */ addr0, r1, r1,

19、 LSL r2/* r0 = r1 + r1 r2 */ 说明 adds和adcs在进位时将cpsr的C标志置1;否则置0。 subs和sbcs在产生借位时将cpsr的C标志置0;否则置1。ARM指令集与编程282.5 逻辑指令语法 s , , # s , , s , , LSL # s , , LSL 伪代码(以and为例)If ConditionPassed(cond) thenRd = Rn AND 第2操作数if s = 1 and Rd = pc thencpsr = spsrelse if s = 1 thenset NZCV flags in cpsrARM指令集与编程292.5

20、 逻辑指令(续) 举例 andr0, r1, r2/* r0 = r1 AND r2 */ and r1, r1,#0 xffffff00/* r1 = r1 AND 0 xffffff00 */ orrr0, r1, r2/* r0 = r1 OR r2 */ eorr0, r1, r2/* r0 = r1 XOR r2 */ bicr0, r1, r2/* r0 = r1 AND NOT r2 */ bicr1, r1, #0 x0f/* 清空r1的低4位 */ andr0, r1, r1, LSL #31/* r0 = r1 AND (r1 r2) */ARM指令集与编程302.6 比较

21、指令 语法 , # , , , LSL # , , LSL 伪代码(以cmp为例)If ConditionPassed(cond) thenalu_out = Rn 第2操作数 set NZCV flags in cpsrARM指令集与编程312.6 比较指令(续) 举例 cmpr1, r2 /*根据r1 r2的结果设置cpsr,结果不写回*/ cmn r1, r2 /*根据r1 + r2的结果设置cpsr,结果不写回*/ tstr1, r2 /*根据r1 AND r2的结果设置cpsr,结果不写回*/ teqr1, r2 /*根据r1 XOR r2的结果设置cpsr,结果不写回*/ cmpr

22、2, #5 /*根据r2 5的结果设置cpsr,结果不写回*/ cmpr1, r2, LSL #5/* 根据r1 (r2 5)设置cpsr */ cmpr1, r2, LSL r3/* 根据r1 (r2 r3)设置cpsr */ 说明 如果不考虑结果的写回,cmp、cmn、tst和teq分别等价于subs、adds、ands和eors。ARM指令集与编程32目录1.总体介绍:指令分类,特点,格式,条件码2.数据处理指令:数据传输指令,算术指令,逻辑指令,比较指令,乘法指令(略),前导零计数(略)3.程序状态访问指令4.跳转指令5.单数据访存指令6.多数据访存指令7.其它指令:信号量操作指令,异

23、常中断产生指令,协处理器指令(略)8.伪指令(略)9.基于ARM的编程ARM指令集与编程333 程序状态访问指令 当需要修改cpsr/spsr的内容时,首先要读取它的值到一个通用寄存器,然后修改某些位,最后将数据写回到状态寄存器。 cpsr/spsr不是通用寄存器,不能使用mov指令来读写。在ARM处理器中,只有mrs指令可以读取cpsr/spsr;只有msr可以写cpsr/spsr。ARM指令集与编程343.1 读指令mrs 语法 mrs , cpsr|spsr 伪代码if ConditionPassed(cond) thenif R = 1 thenRd = spsrelse Rd = c

24、psrARM指令集与编程353.1读指令mrs(续) 举例 mrsr0, cpsr/* 读取cpsr到r0 */ mrsr3, spsr/* 读取spsr到r3 */ 说明 user和system模式没有spsr,因此这些模式下不能读取spsr。ARM指令集与编程363.2 写指令msr的二进制格式0condR1 0f s x c1111操作数操作数011121516192021221 02324#250 02627283118位立即数#rot078110 0 0 0 0 0 0 0Rm03411cpsr/spsr域屏蔽立即数对准操作数寄存器ARM指令集与编程373.2.1 写指令msr的语法

25、 msr _, # msr _, 表示合法的立即数:8bit循环右移偶数位 代表cpsr或spsr 指定传送的区域,可进一步细分(只能小写) c控制域字节(psr7:0) x扩展域字节(psr15:8) s状态域字节(psr23:16) f标志域字节(psr31:24)ARM指令集与编程383.2.2 写指令msr的伪代码 伪代码if ConditionPassed(cond) thenif opcode25 = 1operand = 8立即数 Rotate_Right (#rot * 2)else /* opcode25 = 0 */operand = Rmif R = 0 thenif f

26、ield_mask0 = 1 and InAPrivilegeMode() then cpsr7:0 = operand7:0if field_mask1 = 1 and InAPrivilegeMode() then cpsr15:8 = operand15:8if field_mask2 = 1 and InAPrivilegeMode() then cpsr23:16 = operand23:16if field_mask3 = 1 then cpsr31:24 = operand31:24else /* R = 1 */if field_mask0 = 1 and CurrentMod

27、eHasSPSR() then spsr7:0 = operand7:0if field_mask1 = 1 and CurrentModeHasSPSR() then spsr15:8 = operand15:8if field_mask2 = 1 and CurrentModeHasSPSR() then spsr23:16 = operand23:16if field_mask3 = 1 and CurrentModeHasSPSR() then spsr31:24 = operand31:24ARM指令集与编程393.2.3 msr举例和说明举例msrcpsr_c, #0 xd3/*

28、切换到SVC模式*/msrcpsr_cxsf, r3/* cpsr = r3 */说明user和system模式没有spsr,因此这些模式下不能对spsr操作。由于权限问题,在user模式下对cpsr23:0修改无效。如果使用立即数,要使用合法的立即数。程序不能同过“msr修改cpsr的T位”来完成ARM/Thumb态的切换。必须使用bx指令,因为bx属于分支指令,它会打断流水线,实现处理器状态切换。如果要修改读出的值,仅修改必要的位,其它位保持不变,这样保持了最大兼容性。ARM指令集与编程40目录1.总体介绍:指令分类,特点,格式,条件码2.数据处理指令:数据传输指令,算术指令,逻辑指令,比

29、较指令,乘法指令(略),前导零计数(略)3.程序状态访问指令4.跳转指令5.单数据访存指令6.多数据访存指令7.其它指令:信号量操作指令,异常中断产生指令,协处理器指令(略)8.伪指令(略)9.基于ARM的编程ARM指令集与编程414 跳转指令 语法 b label bl label 说明 寻址范围 +32MBARM指令集与编程424 跳转指令(续) 当转移指令执行时,处理器将指令中的offset(24bit)左移2bit,变成26bit,表示+ 32M的范围。 pc从新的地址执行,流水线重新填充。 如果是“bl”指令,将返回地址写入lr寄存器。子程序返回时只需要用lr恢复pc就可以: mov

30、 pc, lr “b”指令不影响lr寄存器ARM指令集与编程43目录1.总体介绍:指令分类,特点,格式,条件码2.数据处理指令:数据传输指令,算术指令,逻辑指令,比较指令,乘法指令(略),前导零计数(略)3.程序状态访问指令4.跳转指令5.单数据访存指令6.多数据访存指令7.其它指令:信号量操作指令,异常中断产生指令,协处理器指令(略)8.伪指令(略)9.基于ARM的编程ARM指令集与编程445 单数据访存指令 第一类: 读写字:ldr / str 读写无符号字节:ldrb / strb 第二类: 读写无符号半字:ldrh / strh 读有符号半字:ldrsh 读有符号字节:ldrsbARM

31、指令集与编程455.1 第一类指令的指令格式0 0 0 0 0 0 0 0 0 0Rm03411方式2:Rm例子:ldr r0, r1, +r2011#immed_12方式1:#immed_12(取值范围0 0 xfff)例子:ldr r0, r1, #+0 xfffshiftRm03411#immed_567方式3:Rm LSL #immed_5(取值范围0-31)例子:ldr r0, r1, r2 LSL #31050/1 : str/ldr0/1 : 无/有(!)0/1 : 后变址/前变址0/1 : 字/无符号字节condRnRd第第 2 操作数操作数078111215161920220

32、12728312324U B W L2126PI250/1 : 加/减(第2操作数)0/1 : 立即数(方式1)/寄存器(方式2,3)ARM指令集与编程465.2 第一类指令的语法语法ldr|strb , , #+immed_12!ldr|strb , , +!ldr|strb , , +, #!ldr|strb , , #+immed_12ldr|strb , , +ldr|strb , , +, #举例ldrb r0, r1, #+0 xfff/* 把r1+0 xfff地址的字节读入r0 */ldr r0, r1, +r2!/*把r1+r2地址的32比特数读入r0,然后r1= r1+r2

33、*/str r0, r1, +r2, LSL #31 /* 把r0(32bit)写到地址r1+(r231) */ldr r0, r1, #+0 xfff/* 把r1地址的数读入r0,然后r1=r1+0 xfff */ldr r0, r1, +r2/* 把r1地址的数读入r0,然后r1=r1+r2 */ldr r0, r1, +r2, LSL #31 /* 把r1地址的数读入r0,然后r1=r1+(r231) */ARM指令集与编程475.2 第一类指令说明 说明 ldr / str 读/写一个32bit字到/从一个32bit的寄存器,要求读/写地址字对齐。 ldrb:读一个8bit字节到一个3

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

35、指令集与编程495.4 前/后变址0 0 0 0 0 0 0 0 0 0Rm03411方式2:Rm例子:ldr r0, r1, +r2011#immed_12方式1:#immed_12(取值范围0 0 xfff)例子:ldr r0, r1, #+0 xfffshiftRm03411#immed_567方式3:Rm LSL #immed_5(取值范围0-31)例子:ldr r0, r1, r2 LSL #31050/1 : str/ldr0/1 : 无/有(!)0/1 : 后变址后变址/前变址前变址0/1 : 字/无符号字节condRnRd第第 2 操作数操作数07811121516192022

36、012728312324U B W L2126PI250/1 : 加/减(第2操作数)0/1 : 立即数(方式1)/寄存器(方式2,3)ARM指令集与编程505.4.1 简单的基址寻址 基址寄存器数据访问 str r0, r1 ldr r2, r1ARM指令集与编程515.4.2 前变址寻址 str r0,r1,#12! ; mem32r1+12 = r0;r1 = r1 + 12;ARM指令集与编程525.4.3 后变址寻址数据访问 str r0, r1, #12 mem32r1 = r0; r1 = r1 + 12;ARM指令集与编程535.5 三种寻址方式(第一类)0 0 0 0 0 0

37、 0 0 0 0Rm03411方式2:Rm例子:ldr r0, r1, +r2011#immed_12方式1:#immed_12(取值范围0 0 xfff)例子:ldr r0, r1, #+0 xfffshiftRm03411#immed_567方式3:Rm LSL #immed_5(取值范围0-31)例子:ldr r0, r1, r2 LSL #31050/1 : str/ldr0/1 : 无/有(!)0/1 : 后变址/前变址0/1 : 字/无符号字节condRnRd第第 2 操作数操作数07811121516192022012728312324U B W L2126PI250/1 : 加

38、/减(第2操作数)0/1 : 立即数(方式1)/寄存器(方式2,3)ARM指令集与编程545.5 寻址方式1立即数寻址ldr|strb , , #+immed_12!ldr|strb , , #+immed_12说明:无叹号的前变址,当pc作为Rn时,内存基地址为当前指令地址加8字节偏移;后变址或有叹号的前变址,当pc作为Rn时,会产生不可预知的结果在ADS1.2中,提示错误Error : A1324E Undefined effect (PC + writeback)在arm-elf-gcc-2.95.3中,没有提示后变址或有叹号的前变址,如果Rn和Rd是同一个寄存器,编译出错在ADS1.2

39、中,提示错误Error : A1325E: Undefined effect (destination same as written-back base)在arm-elf-gcc-2.95.3中,提示Warning: destination register same as write-back base如果immed_12超过0 xfff,编译会出错在ADS1.2中,提示错误Error : A1174E: Data transfer offset out of range在arm-elf-gcc-2.95.3中,提示Error: address offset too largeARM指令集

40、与编程555.5 寻址方式2寄存器寻址ldr|strB , , +!ldr|strB , , +说明: 无论如何,pc都不能作Rm。 无叹号的前变址,当pc作为Rn时,内存基地址为当前指令地址加8字节偏移;后变址或有叹号的前变址,当pc作为Rn时,会产生不可预知的结果。 后变址或有叹号的前变址,如果Rn和Rd是同一个寄存器,会出现不可预知的结果。ARM指令集与编程565.5 寻址方式3-寄存器移位寻址ldr|strB , , +, #!ldr|strB , , +, #说明: 无论如何,pc都不能作Rm。 无叹号的前变址,当pc作为Rn时,内存基地址为当前指令地址加8字节偏移;后变址或有叹号的

41、前变址,当pc作为Rn时,会产生不可预知的结果。 后变址或有叹号的前变址,如果Rn和Rd是同一个寄存器,会出现不可预知的结果。 如果immed_5超过31,编译器报错。ARM指令集与编程57目录1.总体介绍:指令分类,特点,格式,条件码2.数据处理指令:数据传输指令,算术指令,逻辑指令,比较指令,乘法指令(略),前导零计数(略)3.程序状态访问指令4.跳转指令5.单数据访存指令6.多数据访存指令7.其它指令:信号量操作指令,异常中断产生指令,协处理器指令(略)8.伪指令(略)9.基于ARM的编程ARM指令集与编程586 多数据访存指令 批量访存指令可以实现一组(1-16)寄存器和一块(4-64

42、字节)连续内存单元之间的数据传输。ARM指令集与编程596.1 指令格式ARM指令集与编程606.2 ldm/stm指令的语法语法 ldm|stm !, 有4种: IA (Increment After)事后递增 IB (Increment Before)事先递增 DA (Decrement After)事后递减 DB (Decrement Before)事先递减例子 ldmia r0, r5-r8/* 将内存中(r0)到(r0+12)4个字读取到r5r8的4个寄存器中 */ ldmib r0, r5-r8/* 将内存中(r0+4)到(r0+16)4个字读取到r5r8的4个寄存器中 */ ld

43、mda r0, r5-r8/* 将内存中(r0-12)到(r0)4个字读取到r5r8的4个寄存器中 */ ldmdb r0, r5-r8/* 将内存中(r0-16)到(r0)4个字读取到r5r8的4个寄存器中 */ARM指令集与编程616.2 ldm/stm指令的语法(续) 说明 递增方式和递减方式处理寄存器列表和内存地址对应关系时采用不同的顺序,见前面的例子。可以总结为:编号低的寄存器对应低内存地址。 pc不能作为stm指令的,否则结果不可预知。 感叹号“!”表示执行后将更新。 “”不能在usr和system模式下使用,否则结果不可预知。在其它模式下使用时,含义和寄存器列表是否包含pc有关,

44、见后面的详述。ARM指令集与编程626.3 ldm指令的三种用法编号!pcldm指令不同的功能用法1是是是同(5),但是更新32是是否编译警告(ADS1.2):Warning : A1329W: Unsafe instruction (forced user mode xfer with write-back to base)23是否是同(7),但是更新14是否否同(8),但是更新,且不能出现在中15否是是数据读取的同时,拷贝spsr到cpsr36否是否采用user模态下的寄存器27否否是同(8),可用于程序跳转。18否否否正常读取1ARM指令集与编程636.4 stm指令的两种用法编号!ld

45、m指令不同的功能用法1是是同(3),但是更新22是否同(4),但是更新。当是中编号最小的寄存器时,指令将的初值保存;否则结果不可预测。13否是采用user模态下的寄存器24否否正常写入1ARM指令集与编程646.5 多数据访存的程序例子/* r12 指向源数据起点 */* r14 指向源数据终点 */* r13 指向目标地址 */loop:ldmia r12!, r0-r11 /* 读48字节 */stmia r13!, r0-r11 /* 写48字节 */cmp r12, r14 /* 是否到末尾 */bne loop /* 重复循环 */ARM指令集与编程656.6 模拟栈 ARM指令集中

46、没有用于栈的操作指令,但是可以用多数据访存指令来模拟。ARM指令集与编程666.6.1 栈的分类 栈的分类(按指针): 栈指针指向最后一个被占用的地址 (Full Stack) 在push前需要先将栈指针减小 栈指针指向下一个被占用的地址 (Empty Stack) 在push之后需要将栈指针减小 栈的分类(按方向): 上升的栈(Ascending Stack) 向高地址扩展 下降的栈(Descending Stack) 向低地址扩展ARM指令集与编程676.6.2 模拟压栈操作块数据访问指令 栈访问指令说明stmdastmed下降型空栈stmiastmea上升型空栈stmdbstmfd下降型

47、满栈stmibstmfa上升型满栈ARM指令集与编程686.6.3 模拟退栈操作块数据访问指令 栈访问指令说明ldmdaldmfa上升型满栈ldmialdmfd下降型满栈ldmdbldmea上升型空栈ldmibldmed下降型空栈ARM指令集与编程696.6.4 模拟栈操作 模拟stack的访问 stmfd / ldmfd : Full Descending Stack stmfa / ldmfa : Full Ascending Stack. stmed / ldmed : Empty Descending Stack stmea / ldmea : Empty Ascending Stac

48、k 常见的情况 stmfd sp!, r0-r12, lr / 保存所有有寄存器(包括返回地址) ldmfd sp!, r0-r12, pc / 恢复所有寄存器(包括pc)ARM指令集与编程706.6.5 栈操作图示ARM指令集与编程71目录1.总体介绍:指令分类,特点,格式,条件码2.数据处理指令:数据传输指令,算术指令,逻辑指令,比较指令,乘法指令(略),前导零计数(略)3.程序状态访问指令4.跳转指令5.单数据访存指令6.多数据访存指令7.其它指令:信号量操作指令,异常中断产生指令,协处理器指令(略)8.伪指令(略)9.基于ARM的编程ARM指令集与编程727 其它指令 信号量操作指令:

49、用于进程间的同步互斥,提供对信号量的原子操作。 异常中断产生指令:用于系统调用和调试。ARM指令集与编程737.1信号量操作指令 语法 swp|swpb , , 例子 swp r1, r2, r3/* 将内存单元(r3)中的字读取到r1,同时将r2中的数据写入内存单元(r3)中 */ swp r1, r1, r2/* 将r1寄存器内容和内存单元(r2)的内容互换 */ 说明 swpb读取8bit数据到寄存器后会对高24位清零,写到内存的8bit数来自寄存器低8位ARM指令集与编程747.1信号量操作指令(续)ARM指令集与编程757.2 异常产生指令 指令格式 语法 swi 说明 主要用于用户程序调用操作系统的API。参数传递通常有两种方法: 指令中的24bit立即数指定API号,参数通过寄存器传递。 忽略指令中的24bit立即数,r0指定API号,其它参数通过其它寄存器传递。condImmed_240231 1 1 127283124ARM指令集与编程767.3 中断产生指令 语法 bkpt 说明 用于产生软件断点中断。 主要用于调试。 ARMv5及以上版本支持。ARM指令集与编程77目录1.总体介绍:指令分类,特点,格式,条件码2.数据处理指令:数据传

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论