微机原理与接口技术 第三章 arm 寻址方式与指令系统
DESCRIPTION
微机原理与接口技术 第三章 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) - PowerPoint PPT PresentationTRANSCRIPT
微机原理与接口技术第三章 ARM 寻址方式与指令系统微机原理与接口技术
第三章 ARM 寻址方式与指令系统
主讲人:鞠 雷
山东大学 计算机科学与技术学院
2
内容提要 内容提要
思考题
Thumb 指令集
ARM 指令集
ARM 指令格式和寻址方式
ARM 编程模型
3
3.3 ARM 指令集 3.3 ARM 指令集
3.3.1 数据处理指令
3.3.3 Load/Store 指令
3.3.2 跳转指令
3.3.4 程序状态寄存器指令
3.3.6 异常中断指令
3.3.5 协处理器指令
4
3.3.1 数据处理指令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
例如:MOV R0 ,# 5 ; R0=5
MOV R0 , R1 ; R0=R1
MOV R0 , R1 , LSL # 5;
R0= R1 左移 5 位
如果 R15 是目的寄存器,将修改程序计数器或标志。用于返回到调用代码,方法是把连接寄存器的内容传送到 R15:
MOV PC, R14 ; ; 退出到调用者 MOVS PC, R14 ; 退出到调用者并回复标志位
Move Immediate ValueMove 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
Move Immediate ValueMove 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 数据取反传送指令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
ADD 加法指令ADD 加法指令
3. ADD 加法指令 (Addition)
ADD{<cond>}{S} <Rd>,<Rn>,<op2>;
功能: ADD 将把两个操作数加起来,把结果放置到目的寄存器中。 Rd = Rn + 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
Op2 为寄存器或立即数,若为寄存器可以先移位。
ADC 带进位加法指令ADC 带进位加法指令
4. ADC 带进位加法指令 (Addition with Carry)
ADC{<cond>}{S} <Rd>,<Rn>,<op2>;
功能:将寄存器 Rn 、操作数 op2 表示的值以及进位标志位三者相加,然后把结果存入目的寄存器 Rd 中。
Rd= Rn + op2 + carry 进位标志值
9
10
ADC 带进位加法指令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 减法指令SUB 减法指令5. SUB 减法指令 (Subtraction)
SUB{<cond>}{S} <Rd>,<Rn>,<op2>;
功能: SUB 用操作数 Rn 减去操作数 op2 ,把结果放置到目的寄存器中。 Rd = Rn - 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
Op2 为寄存器或立即数,若为寄存器可以先移位。
12
RSB 反向减法指令RSB 反向减法指令
6. RSB 反向减法指令 (Reverse Subtraction)
RSB{<cond>}{S} <Rd>,<Rn>,<op2>;
功能: SUB 用操作数 op2 减去操作数 Rn ,把结果放置到目的寄存器中 。 Rd = op2 – Rn
例 :
RSB R0, R1, R2 ; R0 = R2 - R1
RSB R0, R1, #256 ; R0 = 256 - R1
RSB R0, R2, R3,LSL#1 ; R0 = (R3 << 1) - R2
Op2 为寄存器或立即数,若为寄存器可以先移位。
13
SBC 带借位减法指令SBC 带借位减法指令7. SBC 带借位减法指令 :(Subtraction with Carry)
SBC{<cond>}{S} <Rd>,<Rn>,<op2>;
功能:用寄存器 Rn 的值减去操作数 op2 表示的值,再减去进位标志取反的值,然后把结果存入目的寄存器 Rd中。 Rd= Rn - op2 - !carry
注意 : 减法有借位, carry = 0 。
14
SBC 带借位减法指令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 带借位的反向减法指令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 位乘法指令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 的值
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 位乘加指令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
ARM 中除法的实现ARM 中除法的实现嵌入式计算机 CPU 运算速度慢尽量避免除法
1. offset=(Offset+increment) % buffer_size ; ( 50cycle )2. offset+=increment ; if(offset>=buffer_size) offset-=buffer_size ;( 3cycle )
ARM 中除法的实现ARM 中除法的实现 V7 之前的 ARM 处理器:函数形式(如 C 库函数 ,20-100
cycles ) ARM v7
Cortex-M 系列,硬件除法器 ( 2-12 cycles ) Cortex-R 系列,硬件除法器 Cortex-A 系列,协处理器 (VFP , NEON)
21
AND 逻辑与指令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 逻辑或指令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 逻辑异或指令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 位清除指令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)
CMP 比较指令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 位测试指令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
3.3.2 跳转指令 3.3.2 跳转指令 B{<cond>} <addr>;
功能: B 是最简单的跳转指令。遇到一个 B 指令, ARM处理器将立即跳转到给定的地址 addr ,从那里继续执行。
注意: addr 的值是相对当前 PC( 即寄存器 R15) 的值的一个偏移量;而不是一个绝对地址。它是 24 位有符号数。实际地址的值由汇编器来计算 。 addr 的值有符号扩展为 32 位后,左移两位,然后与 PC 值相加,即得到跳转的目的地址。跳转的范围为- 32M~+ 32M 。
例如:
B exit ; 程序跳转到标号 exit处
……
exit……
2831 24 0
Cond 1 0 1 L Offset
Condition field
Link bit 0 = Branch
1 = Branch with link
232527
B 跳转指令B 跳转指令 addr 的计算 :
0x0000 0000 ADD R0 R1 R20x0000 0004 B exit0x0000 0008 SUB R0 R2 R30x0000 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 0x000000040x00000010+PC(0x0000000b)
- 8 (由于流水线造成 )
What happens to the following two instructions?
1. In DSP and older RISCs (MIPS,SPARC…): branch delay slot (executed, automatic re-ordered by assembler)
2. In ARM, PowerPC, Alpha: pipeline refill with 3 cycle penalty (not executed)
29
BL 带返回的跳转指令BL 带返回的跳转指令2. BL 带返回的跳转指令
BL{<cond>} <addr>; 功能:同 B 指令,但 BL 指令执行跳转操作的同时,还将
PC (寄存器 R15 )的值保存到 LR 寄存器(寄存器R14 )中。该指令用于实现子程序调用 。程序的返回可通过把 LR 寄存器的值复制到 PC 寄存器中来实现
例如: BL func ; 调用子程序 func
……
func
……
MOV R15 , R14 ; 子程序返回
PC-4
分支执行分支执行
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
1. 减少指令数量较小的内存占用2. 更流畅的流水线执行 (pipeline refill penalty = 3 cycles
when BEQ is executed)
分支执行分支执行 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
习题及答案习题及答案 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
CPSR 中 V 位的设置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 指令3.3.3 Load/Store 指令
Load/Store 指令用于寄存器和内存间数据的传送, Load 用于把内存中的数据装载到寄存器中,而 Store 则用于把寄存器中的数据存入内存。
Load/Store 指令分为三类: 单一数据传送指令( LDR 和 STR等);
多数据传送指令( LDM 和 STM );
数据交换指令( SWP 和
SWPB )。
35
LDR 字数据加载指令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 字数据加载指令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 字数据加载指令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 字数据加载指令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 字数据存储指令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] ; 将数据输出到外设端口寄存器中;
Effect of endianessEffect 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.
Endianess ExampleEndianess Example
Big-endianLittle-endianr1 = 0x100
r0 = 0x1122334431 24 23 16 15 8 7 0
11 22 33 44
31 24 23 16 15 8 7 0
11 22 33 44
31 24 23 16 15 8 7 0
44 33 22 11
31 24 23 16 15 8 7 0
00 00 00 44
31 24 23 16 15 8 7 0
00 00 00 11
r2 = 0x44 r2 = 0x11
STR r0, [r1]
LDRB r2, [r1]
r1 = 0x100Memory
应用举例:( 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 变量
42
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
批量数据加载 / 存储指令批量数据加载 / 存储指令5. LDM批量数据加载指令 :
LDM{<cond>}{<type>} <Rn>{!} , <regs>{^} ;
功能:从一片连续的内存单元读取数据到各个寄存器中,内存单元的起始地址为基址寄存器 Rn 的值,各个寄存器由寄存器列表 regs 表示。该指令一般用于多个寄存器数据的出栈。
{!} :若选用了此后缀,则当指令执行完毕后,将最后的地址写入基址寄存器。
‘^’ 不带 ^ 表示用户和系统模式寄存器 ;
带有 ^ 表示异常模式寄存器 , 此时若 LDM包含 R15 ,装载 R15 时恢复 SPSR至 CPSR 位。
内存操作 : IA IB DA DB
堆栈操作 : FA FD EA ED
Rn :保存内存单元的起始地址。Regs :寄存器列表,由若干个寄存器组成,寄存器之间以“,”或“ -”分隔。
45
批量数据加载 / 存储指令批量数据加载 / 存储指令
6. STM批量数据存储指令 :
STM{<cond>}{<type>} <Rn>{!} , <regs>{^} ;
功能:将各个寄存器的值存入一片连续的内存单元中,内存单元的起始地址为基址寄存器 Rn 的值,各个寄存器由寄存器列表 regs 表示。该指令一般用于多个寄存器数据的入栈。
批量数据存储、加载时,低编号寄存器对应低地址存储单元,与寄存器在指令中出现的次序无关。
46
批量数据加载 / 存储指令批量数据加载 / 存储指令 指令中, type 字段有以下几种:
4 种类型的堆栈
FD:满递减堆栈; Full decrease
入栈指针先减再入栈,出栈先出指针再加 入栈: STMFD R13!,{R0,R1}
出栈: LDMFD R13!,{R2,R3}
FA:满递增堆栈; Full accumulate
入栈指针先加再入栈,出栈先出指针再减 入栈: STMFA 出栈: LDMFA
ED:空递减堆栈; Empty decrease
入栈先入栈指针再减,出栈指针先加再出栈EA:空递增堆栈; Empty accumulte
入栈先入栈指针再加,出栈指针先减再出栈
满栈( Full ):栈顶存储单元含有有效数据。空栈( Empty ):栈顶存储单元不含有有效数据。递增( Aaccumulate ):入栈指针加 4 ,出栈指针减 4 。递减( Decrease ):入栈指针减 4 ,出栈指针加4 。
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
26262626
59595959
00008888
66663333
54693645
15548545
14543862
36338832
0x123456a0
0x12345690
0x1234568c
0x12345688
0x12345684
0x12345680
0x1234567c
0x12345678
0x12345684
R13
内存中的数据
批量数据加载 / 存储指令批量数据加载 / 存储指令IA 、 IB 、 DA 、 DB 指定了地址加还是减,是传送前还是
传送后 。例如: LDMIA/IB/DA/DB R13! , {R0-R1 ,R3} ;各指令执行完后,结果如图所示 :
R3
R1
R0
R3
R1
R0
LDMDA:每次传送后地址减 4 ;
66663333
00008888
59595959
15548545
54693645
66663333
LDMIA:每次传送后地址加4 ;
LDMIB:每次传送前地址加4 ;
14543862
15548545
54693645
LDMDB:每次传送前地址减 4 ;
00008888
59595959
26262626
STMIA/IB/DA/DB 地址变化与LDMIA/IB/DA/DB 相同 .
49
批量数据加载 / 存储指令批量数据加载 / 存储指令 FD 、 ED 、 FA 、和 EA 指定是满栈还是空栈,是升序栈还
是降序栈,用于堆栈寻址。一个满栈的栈指针指向上次写的最后一个数据单元,而空栈的栈指针指向第一个空闲单元。一个降序栈是在内存中反向增长而升序栈在内存中正向增长。如下图所示,数据以 16 进制存储。
66663333
54693645
15548545
14543862
36338832
0x123456a0
0x12345690
0x1234568c
0x12345688
0x12345684
0x12345680
0x1234567c
0x12345678
栈指针
FD :满递减堆栈;STM 入栈 ↓ LDM 出栈 ↑
66663333
54693645
15548545
14543862
36338832
0x123456a0
0x12345690
0x1234568c
0x12345688
0x12345684
0x12345680
0x1234567c
0x12345678
ED :空递减堆栈;STM 入栈 ↓ LDM 出栈 ↑
栈指针
FA :满递增堆栈;STM 入栈 ↑ LDM 出栈 ↓栈指针
26262626
59595959
00008888
66663333
54693645
0x123456a0
0x12345690
0x1234568c
0x12345688
0x12345684
0x12345680
0x1234567c
0x12345678
26262626
59595959
00008888
66663333
54693645
0x123456a0
0x12345690
0x1234568c
0x12345688
0x12345684
0x12345680
0x1234567c
0x12345678
栈指针
EA :空递增堆栈;STM 入栈 ↑ LDM 出栈 ↓
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 到目标地址
LDMIA/STMIALDMIA/STMIA
LDMIA/STMIA Rn!, {reglist} Rn is the register containing the base address. Rn mustbe in the
range r0-r7. reglist is a comma-separated list of low registers or low-register
ranges.
Usage Registers are loaded stored and in numerical order, with the
lowest numbered register at the address initially in Rn. The value in Rn is incremented by 4 times the number of
registers in reglist. If Rn is in reglist:
for an LDMIA instruction, the final value of Rn is the value loaded, not the incremented address
for an STMIA instruction, the value stored for Rn is:– the initial value of Rn if Rn is the lowest-numbered register
in reglist– unpredictable otherwise.
Incorrect examplesIncorrect examples
LDMIA r3!,{r0,r9} ; high registers not allowed
STMIA r5!, {} ; must be at least one register in list
STMIA r5!,{r1-r6} ; value stored from r5 is unpredictable
寻址方式对应关系寻址方式对应关系
寻址方式 说明 pop =LDM push =STM
FA 递增满 LDMFA LDMDA STMFA STMIB
FD 递减满 LDMFD LDMIA STMFD STMDB
EA 递增空 LDMEA LDMDB STMEA STMIA
ED 递减空 LDMED LDMIB STMED STMDA
ARM 编译器默认使用方式
LDM/STM 指令格式LDM/STM 指令格式
LDM/STM 指令格式LDM/STM 指令格式
LDMFD R0! {R1, R5, R2}
LDR R1,[R0],#4
LDR R2,[R0],#4
LDR R5,[R0],#4
57
3.3.6 异常中断指令3.3.6 异常中断指令
ARM 处理器支持两条异常中断指令:软件中断指令 SWI和断点中断指令 BKPT 。
1 . SWI软件中断指令: SWI{ 条件 } 24 位的立即数(系统例程类型) ;功能:产生软件中断,并调用操作系统的例程。 指令中 24 位的立即数指定系统例程的类型,其他入口参数通过通用寄存器传递 .
例如: SWI 0X05 ; 该指令用于调用编号为 05 的系统例程
58
SWI 软件中断指令SWI 软件中断指令
指定系统例程类型的 2 种方式:1 、指令中 24 位的立即数(值为 0~16777215 之间的
整数)指定用户程序调用系统例程的类型,其参数通过通用寄存器传递。
MOV R0 , #34 ; 设置子功能号为 34 ,作为入口参数
SWI 12 ; 调用 12 号软中断2 、当 24 位的立即数被忽略时,系统例程类型由寄存器
R0 指定,其参数通过其他通用寄存器传递。 MOV R0 , #12 ; 调用 12 号软中断,类型为
12 。 MOV R1 , #34 ; 设置子功能号为 34
SWI 0 ; 中断立即数为 0 ,类型由 R0 指定。
59
BKPT 断点中断指令BKPT 断点中断指令
2. BKPT 断点中断指令: BKPT 16 位的立即数;
功能:用于产生软件断点中断,以便软件调试时使用。 16 位的立即数:额外的断点信息,可有可无。
60
内容提要 内容提要
思考题
Thumb 指令集
ARM 指令集
ARM 指令格式和寻址方式
ARM 编程模型
61
举例举例 例 1 :写出执行以下计算的指令序列,其
中, X,Y,Z,R,W
均为 32 位无符号数 , 两数乘积不超出 32 位数范围。(1) ZW-(X+6)-(R+9)(2) Z(W*X)/16
例 2: 假定 R0 、 R1 中的内容为带符号数, R2 、 R3 中的内容为无符号数,写出指令实现以下判断:
若 R3 的内容超过 R2 的内容,则转去执行 EXCEED. 若 R1 的内容超过 R0 的内容,则转去执行 EXCEED. 若 R2 的内容等于零,则转去执行 ZERO. 若 R1 的内容和 R2 的内容相等,则转去执行 EQU.