1 / 61

微机原理与接口技术 第三章  ARM 寻址方式与指令系统

微机原理与接口技术 第三章  ARM 寻址方式与指令系统. 主讲人:鞠 雷 山东大学 计算机科学与技术学院.   内容提要. ARM 编程模型. ARM 指令格式和寻址方式. ARM 指令集. Thumb 指令集. 思考题. 3.3 ARM 指令集. 3.3.1 数据处理指令. 3.3.2 跳转指令. 3.3.3 Load/Store 指令. 3.3.4 程序状态寄存器指令. 3.3.5 协处理器指令. 3.3.6 异常中断指令. 3.3.1 数据处理指令. 1. MOV 数据传送指令 ( Move)

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寻址方式与指令系统 主讲人:鞠 雷 山东大学 计算机科学与技术学院

  2.   内容提要 ARM编程模型 ARM指令格式和寻址方式 ARM指令集 Thumb指令集 思考题

  3. 3.3 ARM指令集 3.3.1 数据处理指令 3.3.2 跳转指令 3.3.3 Load/Store指令 3.3.4 程序状态寄存器指令 3.3.5 协处理器指令 3.3.6 异常中断指令

  4. 3.3.1 数据处理指令 1. MOV数据传送指令 (Move) MOV{<cond>}{S} <Rd>,<op1>; Rd—目的寄存器 op1-寄存器或立即数,若为寄存器可以先移位。 功能:将操作数op1表示的值传送到目的寄存器Rd中。 • 指定相同的寄存器来实现 NOP 指令的效果,还可以专门移位一个寄存器: MOV R0, R0 ; R0 = R0... NOP MOV R0, R0, LSL #3 ; R0 = R0 * 8 • 如果 R15 是目的寄存器,将修改程序计数器或标志。用于返回到调用代码,方法是把连接寄存器的内容传送到 R15: • MOV PC, R14 ;;退出到调用者 • MOVS PC, R14 ;退出到调用者并回复标志位 例如: MOV R0,#5;R0=5 MOV R0,R1; R0=R1 MOV R0,R1,LSL#5; R0= R1左移5位

  5. Move Immediate Value • The data processing instruction format has 12 bits available for operand2 • If used directly this would only give a range of 4096 • Instead it is used to store 8 bit constants, giving a range of 0 - 255. • These 8 bits can then be rotated right through an even number of positions (i.e. RORs by 0, 2, 4,..30). • 4 bits to control the 16 possible ROR rotation numbers • This gives a much larger range of constants that can be directly loaded, though some constants will still need to be loaded from memory

  6. Move Immediate Value • This gives us: • 0 - 255 [0 - 0xff] • 256,260,264,..,1020 [0x100-0x3fc, step 4, 0x40-0xff ROR 30] • 1024,1040,1056,..,4080 [0x400-0xff0, step 16, 0x40-0xff ROR 28] • 4096,4160, 4224,..,16320 [0x1000-0x3fc0, step 64, 0x40-0xff ROR 26] • These can be loaded using, for example: • MOV r0, #0x40, ROR 26 ; => MOV r0, #0x1000 (i.e. 4096) • To make this easier, the assembler will convert to this form for us if simply given the required constant: • MOV r0, #4096 ; => MOV r0, #0x1000 (i.e. 0x40 ROR 26)

  7. MVN数据取反传送指令 2.MVN数据取反传送指令(Move Negative) MVN{<cond>}{S} <Rd>,<op1>; 功能:将op1表示的值按位取反传送到目的寄存器Rd中(logical negation)。 Rd = !op1 例: MVN R0, R2 ; R0 = !(R2) • MVN R0, #0 ;R0 = -1 ?

  8. ADD加法指令 3. ADD加法指令(Addition) ADD{<cond>}{S} <Rd>,<Rn>,<op2>; • 功能:ADD 将把两个操作数加起来,把结果放置到目的寄存器中。Rd = Rn + op2 Op2为寄存器或立即数,若为寄存器可以先移位。 • 例: • ADD R0, R1, #5 ;R0 = R1 + 5 ADD R0, R1, R2 ;R0 = R1 + R2 ADD R0, R2, R3, LSL#1 ;R0 = R2 + (R3 ) X 2 8

  9. ADC带进位加法指令 4. ADC带进位加法指令 (Addition with Carry) ADC{<cond>}{S} <Rd>,<Rn>,<op2>; 功能:将寄存器Rn、操作数op2表示的值以及进位标志位三者相加,然后把结果存入目的寄存器Rd中。 Rd= Rn + op2 + carry 进位标志值 9

  10. ADC带进位加法指令 • 下列例子实现两个 64位数的加法运算。 64 位结果: 寄存器 R0、R1;低位存在R0 第一个 64 位数: 寄存器 R2、R3;低位存在R2 第二个 64 位数: 寄存器 R4、R5。低位存在R4 ADDS R0, R2, R4 ;加低位的字 ADC R1, R3, R5 ;加下一个字,不带进位 注意:相加时,应设置 S 后缀来更改进位标志。

  11. SUB减法指令 5. SUB减法指令(Subtraction) SUB{<cond>}{S} <Rd>,<Rn>,<op2>; • 功能:SUB 用操作数 Rn 减去操作数 op2,把结果放置到目的寄存器中。Rd = Rn - op2 Op2为寄存器或立即数,若为寄存器可以先移位。 例: SUB R0, R1, #5;R0 = R1 - 5 SUB R0, R1, R2;R0 = R1 – R2 SUB R0, R1, R2,LSL#5 ; R0 = R2 - (R2) X 32

  12. RSB反向减法指令 6. RSB反向减法指令(Reverse Subtraction) RSB{<cond>}{S} <Rd>,<Rn>,<op2>; • 功能:SUB 用操作数 op2 减去操作数 Rn,把结果放置到目的寄存器中 。Rd = op2 – Rn Op2为寄存器或立即数,若为寄存器可以先移位。 • 例: RSB R0, R1, R2 ;R0 = R2 - R1 RSB R0, R1, #256 ;R0 = 256 - R1 RSB R0, R2, R3,LSL#1 ;R0 = (R3 << 1) - R2

  13. SBC带借位减法指令 7. SBC带借位减法指令:(Subtraction with Carry) SBC{<cond>}{S} <Rd>,<Rn>,<op2>; • 功能:用寄存器Rn的值减去操作数op2表示的值,再减去进位标志取反的值,然后把结果存入目的寄存器Rd中。 Rd= Rn - op2 - !carry 注意: 减法有借位,carry=0 。

  14. SBC带借位减法指令 • 该指令用于实现超过32位的数的减法。 • 例如: 第一个64位操作数存放在寄存器R2,R3中;低位存在R2 第二个64位操作数存放在寄存器R4,R5中;低位存在R4 64位结果存放在R0,R1中。 SUBS R0,R2,R4;低32位相减,S表示结果影响条件 标志位的值 SBC R1,R3,R5;高32位相减

  15. RSC带借位的反向减法指令 8. RSC带借位的反向减法指令(Reverse Subtraction with Carry)(不要求) RSC{<cond>}{S} <Rd>,<Rn>,<op2>; • 功能:同于SBC,但倒换了两个操作数的前后位置。 Rd = op2 - Rn - !carry • 例如:第一个64位操作数存放在寄存器R2,R3中; 第二个64位操作数存放在寄存器R4,R5中; 64位结果存放在R0,R1中。低位在R2、R4、R0 SUBS R0,R2,R4;低32位相减,S表示结果影响 寄存器CPSR的值 RSC R1, R5,R3;高32位相减(或 SBC R1,R3,R5)

  16. MUL32位乘法指令 9.MUL32位乘法指令(Multiplication) MUL{<cond>}{S} <Rd>,<Rn>,<op2>; • 功能:MUL 提供 32位整数乘法。该指令根据S标志,决定操作是否影响CPSR的值,有S影响N、Z位。 Rn和op2的值为32位无符号数, op2 -必须为寄存器。 Rd = Rn * op2 仅保留最低32位 例如: MULS R0,R1,R2;R0=R1×R2,结果影响寄存器CPSR的值

  17. Using a multiplication instruction to multiply by a constant means first loading the constant into a register and then waiting a number of internal cycles for the instruction to complete. • A more optimum solution can often be found by using some combination of MOVs, ADDs, SUBs and RSBs with shifts. • Multiplications by a constant equal to a ((power of 2) ± 1) can be done in one cycle. • Example: r0 = r1 * 5Example: r0 = r1 + (r1 * 4) ï ADD r0, r1, r1, LSL #2 • Example: r2 = r3 * 105Example: r2 = r3 * 15 * 7Example: r2 = r3 * (16 - 1) * (8 - 1)ï RSB r2, r3, r3, LSL #4 ; r2 = r3 * 15ï RSB r2, r2, r2, LSL #3 ; r2 = r2 * 7

  18. MLA 32位乘加指令 10.MLA 32位乘加指令 (Multiplication with Accumulate) MLA{<cond>}{S} <Rd>,<Rn>,<op2>,<op3>; • 功能: MLA 的行为同于 MUL,但它把操作数 3 的值加到结果上,其中op2,op3必须为寄存器。 Rd =( Rn * op2) + op3,这在求总和时有用 • Rn、op2和op3的值为32位的有符号数或无符号数。 例如: MLA R0,R1,R2,R3; R0=R1×R2+R3

  19. ARM中除法的实现 嵌入式计算机CPU运算速度慢尽量避免除法 1. offset=(Offset+increment)%buffer_size; (50cycle) 2. offset+=increment; if(offset>=buffer_size) offset-=buffer_size;(3cycle)

  20. ARM中除法的实现 • V7之前的ARM处理器:函数形式(如C库函数,20-100 cycles) • ARM v7 • Cortex-M系列,硬件除法器 (2-12 cycles) • Cortex-R系列,硬件除法器 • Cortex-A系列,协处理器(VFP,NEON)

  21. AND逻辑与指令 11.AND逻辑与指令(logical AND) AND{<cond>}{S} <Rd>,<Rn>,<op2>; • 功能:AND 将在两个操作数上按位进行逻辑与,把结果放置到目的寄存器中;Rd = Rn AND op2。对屏蔽某些位很有用。 例如: AND R0, R0, #5 ; R0 = 保持 R0 的位 0 和 2,其余位清0 ANDS R0, R0, #0x01 ; 取R0的最低位

  22. ORR逻辑或指令 12.ORR逻辑或指令(logical OR) ORR{<cond>}{S} <Rd>,<Rn>,<op2>; • 功能:OR 将在两个操作数上按位进行逻辑或,把结果放置到目的寄存器中,Rd = Rn OR op2;对设置特定的位有用。 • 例如: ORR R0, R0, #5 ; R0 中的位 0 和 2置1 ,其余位不变 ORR R0, R0, #0x0F;R0低四位置1 MOV R1,R2,LSR #8 ; ORR R3,R1,R2,LSL#8; 注释有错

  23. EOR逻辑异或指令 13. EOR逻辑异或指令(logical Exclusive OR) EOR{<cond>}{S} <Rd>,<Rn>,<op2>; • 功能:EOR 将在两个操作数上按位进行逻辑异或,把结果放置到目的寄存器中,Rd = Rn EOR op2;对反转特定的位有用。 例如: EOR R0, R0, #5 ; R0 中的位 0 和 2取反 • EOR R1, R1, #x0F;将R1的低4位取反 • EOR R2, R1, R0; R2=R1^R0 • EORS R0, R5, #0x01; R5低位变反,结果保存到R0, 并影响标志位z.

  24. BIC位清除指令 14.BIC位清除指令(Bit Clear) BIC{<cond>}{S} <Rd>,<Rn>,<op2>; • 功能:BIC 是在一个字中清除位的一种方法,与 OR 位设置是相反的操作。 Rd = Rn AND (!op_2) • 操作数2是一个32位位掩码(mask)。掩码中某位为1,则清除Rn中的此位。掩码中为0的位, Rn中此位保持不变。 BIC R0, R0, #0x5 ;清除 R0 中的位 0和位2。其余位不变 BIC R1, R1, #0x0F; 清除R1的低四位,其余位不变 BIC R1,R2,R3; R1= R2 AND (!R3)

  25. CMP比较指令 15.CMP比较指令 (Compare) CMP{<cond>} <Rn>,<op1>; • 功能:将寄存器Rn的值和操作数op1所表示的值进行比较,根据结果更新CPSR中条件标志位的值,但不储存结果。 status = Rn – op1 • 该指令进行一次减法运算,但不存储结果,只更改条件标志位,后面的指令就可以根据条件标志位来决定是否执行。该指令不需要显式的指定S后缀来更改状态标志。 • 操作数op1为寄存器或立即数。 CMP R0,#5; 计算R0-5,根据结果设置条件标志位 ADDGT R0,R0,#5; 如果前次带符号比较结果为大于,则执行ADDGT指令

  26. TST位测试指令 16.TST位测试指令(Test bits) TST{<cond>} <Rn>,<op1>; • 功能:将寄存器Rn的值和操作数op1所表示的值按位做逻辑与操作,根据结果更新CPSR中条件标志位的值,但不储存结果。用于检查寄存器Rn是否设置了op1中相应的位。Status = Rn AND op1 • 操作数 Rn是要测试的数据字,操作数 op1是一个位掩码。经过测试后,设置 Zero 标志。不需要指定 S 后缀。 TST R0,#5; 测试R0中第0位和第2位是否为0 TST R0, #0x01;判断R0的最低位是否为0 • TST R1, #0x0F;判断R1的低4位是否全为0 • BEQ equal;

  27. 31 28 27 25 24 23 0 Cond 1 0 1 L Offset Link bit 0 = Branch 1 = Branch with link Condition field 3.3.2 跳转指令 B{<cond>} <addr>; • 功能:B是最简单的跳转指令。遇到一个B指令,ARM处理器将立即跳转到给定的地址addr,从那里继续执行。 例如: B exit;程序跳转到标号exit处 …… exit…… • 注意:addr的值是相对当前PC(即寄存器R15) 的值的一个偏移量;而不是一个绝对地址。它是24位有符号数。实际地址的值由汇编器来计算 。addr的值有符号扩展为32位后,左移两位,然后与PC值相加,即得到跳转的目的地址。跳转的范围为-32M~+32M。

  28. B跳转指令 What happens to the following two instructions? In DSP and older RISCs (MIPS,SPARC…): branch delay slot (executed, automatic re-ordered by assembler) In ARM, PowerPC, Alpha: pipeline refill with 3 cycle penalty (not executed) • addr的计算: 0x0000 0000 ADD R0 R1 R2 0x0000 0004 B exit 0x0000 0008 SUB R0 R2 R3 0x0000 000c MOV R4 R0 … 0x0000 001c exit: ADD R0 R1 R4 汇编器计算exit的值: 偏移量 = 0x 0000 001c – 0x0000 0004 = 0x 0000 0010 exit = 0b 0000 0000 0000 0000 0000 0100 = 0x 000004 实际执行时寻找跳转地址过程: 0x000004  0x000000040x00000010+PC(0x0000000b) - 8 (由于流水线造成)

  29. BL带返回的跳转指令 2. BL带返回的跳转指令 BL{<cond>} <addr>; • 功能:同B指令,但BL指令执行跳转操作的同时,还将PC(寄存器R15)的值保存到LR寄存器(寄存器R14)中。该指令用于实现子程序调用。程序的返回可通过把LR寄存器的值复制到PC寄存器中来实现 PC-4 例如: BL func;调用子程序func …… func …… MOV R15,R14;子程序返回

  30. 分支执行 if (a != 5){ a = a + 1; } Bypass: a = 5; LDR r0 [a] CMP r0 #5 BEQ Bypass ADD R0 R0 #1 Bypass: MOV r0 #5 LDR r0 [a] CMP r0 #5 ADDNE R0 R0 #1 MOV r0 #5 减少指令数量较小的内存占用 更流畅的流水线执行(pipeline refill penalty = 3 cycles when BEQ is executed)

  31. 分支执行 if((a==b)&&(c==d)) e++; 假设a, b, c ,d, e已经被分别载入到r0, r1, r2, r3, r4, 执行该程序段最少需要几条汇编指令? CMP r0,r1 CMPEQ r2,r3 ADDEQ r4,r4,#1

  32. 习题及答案 • R0,R1带符号数,R2,R3无符号数 • R3>R2, 转去EXCEED • CMP R3 R2; BHI EXCEED; • R1>R0, 转去EXCEED • CMP R1, R0; BGT EXCEED; • R2= 0,转去EXCEED • CMP R2, #0; BEQ ZERO; • R0 = R1, 转去EQU • CMP R0, R1; BEQ EQU; • 总结: • 无符号数比较: >= CS, <= CC, > HI, < LS • 有符号数比较: >= QE, <= LE , < LT, > GT

  33. CPSR中V位的设置 • 以下4中情况V设为1 (以4位数字运算为例) • 正数+正数=负数 (0100+0100=1000) (同时设C=0) • 负数+负数=正数 (1000+1001 = 0001) (同时设C=1) • 正数-负数=负数 (0111-1111 = 1000)(同时设C=0) • 负数-正数=正数 (1011-0111 = 0100) (同时设C=1) • 乘法运算?

  34. 3.3.3 Load/Store指令 • Load/Store指令用于寄存器和内存间数据的传送,Load用于把内存中的数据装载到寄存器中,而Store则用于把寄存器中的数据存入内存。 • Load/Store指令分为三类: • 单一数据传送指令(LDR和STR等); • 多数据传送指令(LDM和STM); • 数据交换指令(SWP和SWPB)。

  35. LDR字数据加载指令 1.LDR字数据加载指令: LDR{<cond>} <Rd>,<addr>; • 功能:把addr所表示的内存地址中的字数据装载到目标寄存器Rd中,同时还可以把合成的有效地址写回到基址寄存器。 Addr寻址方式: Rn表示基址寄存器,Rm表示变址寄存器,index表示偏移量(变址),为12位的无符号数。 1、操作数地址为基址加变址,执行后基址不变。 addr: [Rn,Rm] ((Rn)+(Rm))->(Rd);执行后Rn不变 [Rn +偏移/ Rm]所指数据装入后, Rn不变 LDR Rd,[Rn];把内存中地址为Rn的字数据装入寄存器Rd中; LDR Rd,[Rn,Rm];将内存中地址为Rn+Rm的字数据装入寄存器Rd中; LDR Rd,[Rn,#index] ;将内存中地址为Rn+index的字数据装入寄存器Rd中; LDR Rd,[Rn,Rm,LSL#5] ;将内存中地址为Rn+Rm×32的字数据装入寄存器Rd;

  36. LDR字数据加载指令 2、操作数地址为基址加变址,执行后基址改变 addr:[Rn,Rm]! ((Rn)+(Rm))->(Rd); 执行后 (Rn)+(Rm)->(Rn); [Rn +偏移/ Rm]所指数据装入后, Rn= Rn+偏移/ Rm LDR Rd,[Rn,Rm] !;将内存中地址为Rn+Rm的字数据装入寄存器Rd,并将新地址Rn+Rm写入Rn; LDR Rd,[Rn,#index] !;将内存中地址为Rn+index的字数据装入寄存器Rd,并将新地址Rn+index写入Rn; LDR Rd,[Rn,Rm,LSL#5]!;将内存中地址为Rn+Rm×32的字数据装入寄存器Rd,并将新地址Rn+Rm×32写入Rn

  37. LDR字数据加载指令 3、操作数地址为基址,执行后基址改变 addr:[Rn],Rm ((Rn))-> (Rd);执行后 (Rn)+(Rm)->(Rn); [Rn]所指数据装入后, Rn= Rn+偏移/ Rm LDR Rd,[Rn],Rm ;将内存中地址为Rn的字数据装入寄存器Rd,并将新地址Rn+Rm写入Rn; LDR Rd,[Rn],#index ;将内存中地址为Rn的字数据装入寄存器Rd,并将新地址Rn+index写入Rn; LDR Rd,[Rn],Rm,LSL#5;将内存中地址为Rn的字数据装入寄存器Rd,并将新地址Rn+Rm×32写入Rn。

  38. LDR字数据加载指令 LDR R0,[R1,R2,LSL#5]!; ((R1)+(R2) X 32)->R0 ; (R1)+(R2) X 32)-> R1 LDR R1,[R0,#0x12]; ((R0)+(12)->R1 ; (R0)不变 LDR R1,[R0,-R2]; ((R0)-(R2)->R1 ; (R0)不变 LDR R1,[R0] ((R0))->R1 ; (R0)不变 LDR R1,localdata; 直接寻址,localdata为内存变量的符号地址。 (localdata)-> R1 LDR R0,[R1],R2,LSL #2; ((R1))-> R0,执行后 (R1)+(R2) X 4-> R1 MOV R1,#UARTADD; 地址UART ADD装入R1 LDR R0,[R1];将外设端口数据输入到R0

  39. STR字数据存储指令 3. STR字数据存储指令: STR{<cond>} <Rd>,<addr>; • 功能:把寄存器Rd中的字数据(32位)保存到addr所表示的内存地址中,同时还可以把合成的有效地址写回到基址寄存器。 • 地址addr寻址方式同LDR指令。 例如: • STR R0,[R1,#5]! • STR R2,[R1,#16] • STR R0,[R7],#-8 • STR R2, [R9, #consta-struc];consta-struc是一个常量表达式,范围为-4096~4095(12位有符号数) • MOV R1,#UARTADD;将外设端口地址UARTADD装入R1中 • STR R0,[R1];将数据输出到外设端口寄存器中;

  40. Effect of endianess • The ARM can be set up to access its data in either little or big endian format. • Little endian: • Least significant byte of a word is stored in bits 0-7 of an addressed word. • Big endian: • Least significant byte of a word is stored in bits 24-31 of an addressed word. • This has no real relevance unless data is stored as words and then accessed in smaller sized quantities (halfwords or bytes). • Which byte / halfword is accessed will depend on the endianess of the system involved.

  41. r0 = 0x11223344 31 24 23 16 15 8 7 0 11 22 33 44 STR r0, [r1] 31 24 23 16 15 8 7 0 11 22 33 44 LDRB r2, [r1] 31 24 23 16 15 8 7 0 31 24 23 16 15 8 7 0 00 00 00 11 00 00 00 44 Endianess Example 31 24 23 16 15 8 7 0 Memory 44 33 22 11 r1 = 0x100 r1 = 0x100 Big-endian Little-endian r2 = 0x44 r2 = 0x11

  42. 应用举例:(1) 用ARM指令实现x=(a+b)-c: LDR R4, =a; (R4)=a,a为内存变量地址 LDR R0,[R4];((R4))->R0, (a)-> R0 LDR R5, =b; LDR R1,[R5] ; ((R5))->R1, (b)->R1 ADD R3,R0,R1; (a)+(b)->R3 LDR R4, =c LDR R2,[R4] ; ((R4))->R2, (c)->R2 SUB R3,R3,R2; a+b-c -> R3 LDR R4, =x ;(R4)=x STR R3,[R4] ; (a+b)- c存入x变量

  43. (2) 用ARM指令实现x=a*(b+c) ADR R4,b;变量b的地址装入R4中;LDR R4,=b LDR R0,[R4] ;(b)->R0 ADR R4,c ; LDR R4,=c LDR R1,[R4] ; (c)->R1 ADD R2,R0,R1 ;b+c ->R2 ADR R4,a ;LDR R4,=a LDR R0,[R4] ; (a)->R0 MUL R2,R2,R0; (b+c)*a->R2 ADR R4,x ;LDR R4,=x STR R2,[R4] ; (b+c)*a->x

  44. 批量数据加载/存储指令 内存操作:IAIBDADB 堆栈操作:FAFDEAED 5. LDM批量数据加载指令: LDM{<cond>}{<type>} <Rn>{!},<regs>{^}; • 功能:从一片连续的内存单元读取数据到各个寄存器中,内存单元的起始地址为基址寄存器Rn的值,各个寄存器由寄存器列表regs表示。该指令一般用于多个寄存器数据的出栈。 Rn:保存内存单元的起始地址。 Regs:寄存器列表,由若干个寄存器组成,寄存器之间 以“,”或“-”分隔。 • {!}:若选用了此后缀,则当指令执行完毕后,将最后的地址写入基址寄存器。 • ‘^’不带^表示用户和系统模式寄存器; • 带有^表示异常模式寄存器,此时若LDM包含R15,装载 R15 时恢复 SPSR至CPSR 位。

  45. 批量数据加载/存储指令 6. STM批量数据存储指令: STM{<cond>}{<type>} <Rn>{!},<regs>{^}; 功能:将各个寄存器的值存入一片连续的内存单元中,内存单元的起始地址为基址寄存器Rn的值,各个寄存器由寄存器列表regs表示。该指令一般用于多个寄存器数据的入栈。 批量数据存储、加载时,低编号寄存器对应低地址存储单元,与寄存器在指令中出现的次序无关。 45

  46. 批量数据加载/存储指令 • 指令中,type字段有以下几种: 满栈(Full):栈顶存储单元含有有效数据。 空栈(Empty):栈顶存储单元不含有有效数据。 递增(Aaccumulate):入栈指针加4,出栈指针减4。 递减( Decrease ):入栈指针减4,出栈指针加4。 • 4种类型的堆栈 FD:满递减堆栈;Full decrease 入栈指针先减再入栈,出栈先出指针再加 入栈:STMFD R13!,{R0,R1} 出栈:LDMFD R13!,{R2,R3} FA:满递增堆栈;Full accumulate 入栈指针先加再入栈,出栈先出指针再减 入栈:STMFA 出栈:LDMFA ED:空递减堆栈;Empty decrease 入栈先入栈指针再减,出栈指针先加再出栈 • EA:空递增堆栈;Empty accumulte • 入栈先入栈指针再加,出栈指针先减再出栈

  47. 批量数据加载/存储指令 • 指令中,type字段有以下几种: 4种内存操作 IA:STM/LDM每次传送后地址加4;Increase after STMIA R13!,{R0,R1} LDMIA R13!,{R2,R3} IB:STM/LDM每次传送前地址加4;Increase before STMIB R13!,{R0,R1} LDMIB R13!,{R2,R3} DA:STM/LDM每次传送后地址减4;Decrease after STMDA R13!,{R0,R1} LDMDA R13!,{R2,R3} DB:STM/LDM每次传送前地址减4;Decrease before STMIDB R13!,{R0,R1} LDMDB R13!,{R2,R3}

  48. 36338832 14543862 LDMIA:每次传送后地址加4; 15548545 0x123456a0 0x12345690 0x1234568c 0x12345688 0x12345684 0x12345680 0x1234567c 0x12345678 LDMIB:每次传送前地址加4; 54693645 LDMDA:每次传送后地址减4; 66663333 R3 R1 R0 R3 R1 R0 R13 15548545 54693645 66663333 14543862 15548545 54693645 00008888 59595959 LDMDB:每次传送前地址减4; 0x12345684 66663333 00008888 59595959 26262626 00008888 59595959 26262626 内存中的数据 批量数据加载/存储指令 • IA、IB、DA、DB指定了地址加还是减,是传送前还是传送后 。例如:LDMIA/IB/DA/DB R13!,{R0-R1,R3};各指令执行完后,结果如图所示: STMIA/IB/DA/DB 地址变化与 LDMIA/IB/DA/DB 相同.

  49. 批量数据加载/存储指令 FD、ED、FA、和EA指定是满栈还是空栈,是升序栈还是降序栈,用于堆栈寻址。一个满栈的栈指针指向上次写的最后一个数据单元,而空栈的栈指针指向第一个空闲单元。一个降序栈是在内存中反向增长而升序栈在内存中正向增长。如下图所示,数据以16进制存储。 36338832 36338832 14543862 14543862 EA:空递增堆栈; STM入栈 ↑ LDM出栈 ↓ 15548545 15548545 0x123456a0 0x12345690 0x1234568c 0x12345688 0x12345684 0x12345680 0x1234567c 0x12345678 0x123456a0 0x12345690 0x1234568c 0x12345688 0x12345684 0x12345680 0x1234567c 0x12345678 0x123456a0 0x12345690 0x1234568c 0x12345688 0x12345684 0x12345680 0x1234567c 0x12345678 0x123456a0 0x12345690 0x1234568c 0x12345688 0x12345684 0x12345680 0x1234567c 0x12345678 54693645 54693645 54693645 54693645 栈指针 66663333 66663333 66663333 66663333 FA:满递增堆栈; STM 入栈 ↑ LDM出栈 ↓ 00008888 00008888 ED:空递减堆栈; STM入栈 ↓LDM出栈 ↑ FD:满递减堆栈; STM入栈 ↓LDM出栈 ↑ 59595959 59595959 栈指针 26262626 26262626 栈指针 栈指针 49

  50. 批量数据加载/存储指令 • 例如:使用LDM/STM进行现场寄存器保护,常在子程序中或异常处理使用: SENDBYTE STMFD SP!,{R0-R7,LR};寄存器入栈 ...... BL DELAY;调用DELAY子程序 DELAY ...... ...... LDMFD SP!,{R0-R7,PC};恢复寄存器,并返回 例如: 1、STMEA R13!, {R0-R12,PC};将寄存器R0~R12以及程序计数器PC的值 保存到R13指示的堆栈中。 2、使用LDM/STM进行数据复制: ...... LDR R0,=SrcData;设置源数据地址 LDR R1,=DstData;设置目标地址 LDMIA R0,{R2-R9};加载8字数据到寄存器R2~R9 STMIA R1,{R2-R9};存储寄存器R2~R9到目标地址

More Related