批量数据加载/存储指令

Download Report

Transcript 批量数据加载/存储指令

微机原理与接口技术
第三章 ARM寻址方式与指令系统
主讲人:鞠 雷
山东大学
计算机科学与技术学院
内容提要
ARM编程模型
ARM指令格式和寻址方式
ARM指令集
Thumb指令集
思考题
2
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.3.1 数据处理指令
1. MOV数据传送指令 (Move)
MOV{<cond>}{S} <Rd>,<op1>;
Rd—目的寄存器
op1-寄存器或立即数,若为寄存器可以先移位。
功能:将操作数op1表示的值传送到目的寄存器Rd中。
如果
R15 是目的寄存器,将修改程序计数器或标志。用于返
例如:
指定相同的寄存器来实现
NOP 指令的效果,还可以专门移
回到调用代码,方法是把连接寄存器的内容传送到
R15:
位一个寄存器:
MOV R0,#5;
R0=5
MOV R0,R1;
R0=R1
MOV
MOV
PC,R0,
R14R0; ; ;退出到调用者 R0 = R0... NOP
MOV R0,R1,LSL#5;
MOVS
MOV
PC,
R0,
R14
R0, LSL
;退出到调用者并回复标志位
#3 ;
R0 = R0 * 8
R0= R1左移5位
4
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
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)
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
?
7
ADD加法指令
3. ADD加法指令(Addition)
ADD{<cond>}{S} <Rd>,<Rn>,<op2>;
Op2为寄存器或立即数,若为
 功能:ADD 将把两个操作数加起来,把结果放置到目的寄
寄存器可以先移位。
存器中。 Rd = Rn + op2

例:
ADD R0, R1, #5 ;
ADD R0, R1, R2 ;
ADD R0, R2, R3, LSL#1 ;
R0 = R1 + 5
R0 = R1 + R2
R0 = R2 + (R3 ) X 2
8
ADC带进位加法指令
4.
ADC带进位加法指令 (Addition with Carry)
ADC{<cond>}{S} <Rd>,<Rn>,<op2>;
功能:将寄存器Rn、操作数op2表示的值以及进位标志位三者相
加,然后把结果存入目的寄存器Rd中。
进位标志值
Rd= Rn + op2 + carry
9
ADC带进位加法指令
 下列例子实现两个 64位数的加法运算。
64 位结果:
寄存器 R0、R1;低位存在R0
第一个 64 位数: 寄存器 R2、R3;低位存在R2
第二个 64 位数: 寄存器 R4、R5。低位存在R4
ADDS R0, R2, R4 ;
ADC R1, R3, R5 ;
加低位的字
加下一个字,不带进位
注意:相加时,应设置 S 后缀来更改进位标志。
10
SUB减法指令
5. SUB减法指令(Subtraction)
SUB{<cond>}{S} <Rd>,<Rn>,<op2>;
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
11
RSB反向减法指令
6. RSB反向减法指令(Reverse Subtraction)
RSB{<cond>}{S} <Rd>,<Rn>,<op2>;
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
12
SBC带借位减法指令
7. SBC带借位减法指令:(Subtraction with Carry)
SBC{<cond>}{S} <Rd>,<Rn>,<op2>;
 功能:用寄存器Rn的值减去操作数op2表示的值,再减去
进位标志取反的值,然后把结果存入目的寄存器Rd中。
Rd= Rn - op2 - !carry
注意: 减法有借位,carry=0 。
13
SBC带借位减法指令
 该指令用于实现超过32位的数的减法。
 例如:
第一个64位操作数存放在寄存器R2,R3中;低位存在R2
第二个64位操作数存放在寄存器R4,R5中;低位存在R4
64位结果存放在R0,R1中。
SUBS R0,R2,R4; 低32位相减,S表示结果影响条件
标志位的值
SBC R1,R3,R5;
高32位相减
14
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)
15
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;
器CPSR的值
R0=R1×R2,结果影响寄存
16
 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 * 5
Example: r0 = r1 + (r1 * 4)
ADD r0, r1, r1, LSL #2
 Example: r2 = r3 * 105
Example: r2 = r3 * 15 * 7
Example: r2 = r3 * (16 - 1) * (8 - 1)
RSB r2, r3, r3, LSL #4
RSB r2, r2, r2, LSL #3
; r2 = r3 * 15
; r2 = r2 * 7
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
18
ARM中除法的实现
嵌入式计算机CPU运算速度慢尽量避免除法
1. offset=(Offset+increment)%buffer_size; (50cycle)
2. offset+=increment;
if(offset>=buffer_size) offset-=buffer_size;(3cycle)
ARM中除法的实现
 V7之前的ARM处理器:函数形式(如C库函数,20-100 cycles)
 ARM v7



Cortex-M系列,硬件除法器 (2-12 cycles)
Cortex-R系列,硬件除法器
Cortex-A系列,协处理器(VFP,NEON)
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的最低位
21
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; 注释有错
22
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;
EORS R0, R5, #0x01;
R0, 并影响标志位z.
R2=R1^R0
R5低位变反,结果保存到
23
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)
24
CMP比较指令
15.CMP比较指令 (Compare)
CMP{<cond>} <Rn>,<op1>;
 功能:将寄存器Rn的值和操作数op1所表示的值进行比较,
根据结果更新CPSR中条件标志位的值,但不储存结果。
status = Rn – op1
操作数op1为寄存器或立即数。
该指令进行一次减法运算,但不存储结果,只更改条件标
志位,后面的指令就可以根据条件标志位来决定是否执行。该
指令不需要显式的指定S后缀来更改状态标志。
CMP R0,#5; 计算R0-5,根据结果设置条件标志位

ADDGT R0,R0,#5;
于,则执行ADDGT指令
如果前次带符号比较结果为大
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;
TST
R0, #0x01;
判断R0的最低位是否为0
TST
R1, #0x0F;
判断R1的低4位是否全为0
BEQ
测试R0中第0位和第2位是否为0
equal;
26
3.3.2 跳转指令
B{<cond>} <addr>;
31
28 27
Cond
25 24 23
0
1 0 1 L
Offset
Link bit
0 = Branch
1 = Branch with link
Condition field

功能:B是最简单的跳转指令。遇到一个B指令,ARM处理器
将立即跳转到给定的地址addr,从那里继续执行。
例如:
 注意:addr的值是相对当前PC(即寄存器R15) 的值的一个偏
移量;而不是一个绝对地址。它是24位有符号数。实际地址的
值由汇编器来计算 B。addr的值有符号扩展为32位后,左移两
exit;
程序跳转到标号
位,然后与PC值相加,即得到跳转的目的地址。跳转的范围为
exit处
-32M~+32M。
……
exit……
27
B跳转指令
 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的值:
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)
偏移量 = 0x 0000 001c – 0x0000 0004 - 8 (由于流水线造成)
= 0x 0000 0010
exit = 0b 0000 0000 0000 0000 0000 0100 = 0x 000004
实际执行时寻找跳转地址过程:
0x000004  0x000000040x00000010+PC(0x0000000b)
BL带返回的跳转指令
2.
BL带返回的跳转指令
PC-4
BL{<cond>} <addr>;
 功能:同B指令,但BL指令执行跳转操作的同时,还将PC
(寄存器R15)的值保存到LR寄存器(寄存器R14)中。该
指令用于实现子程序调用 。程序的返回可通过把LR寄存
器的值复制到PC寄存器中来实现
例如:
BL func;
调用子程序func
……
func
……
MOV R15,R14;
子程序返回
29
分支执行
if (a != 5){
LDR r0 [a]
a = a + 1;
CMP r0 #5
LDR r0 [a]
CMP r0 #5
ADDNE R0 R0 #1
}
BEQ Bypass
MOV r0 #5
Bypass: a = 5;
ADD R0 R0 #1
Bypass: 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


R1>R0, 转去EXCEED


CMP R1, R0; BGT EXCEED;
R2= 0,转去EXCEED


CMP R3 R2; BHI EXCEED;
CMP R2, #0; BEQ ZERO;
R0 = R1, 转去EQU

CMP R0, R1; BEQ EQU;
 总结:


无符号数比较: >= CS, <= CC, > HI, < LS
有符号数比较: >= QE, <= LE , < LT, > GT
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)
 乘法运算?
3.3.3 Load/Store指令
 Load/Store指令用于寄存器和内存间数据的传送,Load用于把内
存中的数据装载到寄存器中,而Store则用于把寄存器中的数据
存入内存。

Load/Store指令分为三类:

单一数据传送指令(LDR和STR等);

多数据传送指令(LDM和STM);

数据交换指令(SWP和SWPB)。
34
LDR字数据加载指令
[Rn +偏移/ Rm]所指数据装入后, Rn不变
1.LDR字数据加载指令:
LDR Rd,[Rn] ;
把内存中地址为Rn的字数据装入
LDR{<cond>}
<Rd>,<addr>;
寄存器Rd中;
 功能:把addr所表示的内存地址中的字数据装载到目标寄
LDR Rd,[Rn,Rm] ;
将内存中地址为Rn+Rm的
存器Rd中,同时还可以把合成的有效地址写回到基址寄存
字数据装入寄存器Rd中;
器。
LDR Rd,[Rn,#index] ; 将内存中地址为
Addr寻址方式:
Rn+index的字数据装入寄存器Rd中;
LDR
Rd,[Rn,Rm,LSL#5] ;将内存中地址为Rn+
Rn表示基址寄存器,Rm表示变址寄存器,index表示偏
Rm×32的字数据装入寄存器Rd;
移量(变址),为12位的无符号数。
1、操作数地址为基址加变址,执行后基址不变。
addr: [Rn,Rm]
((Rn)+(Rm))->(Rd);执行后Rn不变
35
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
36
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。
37
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
38
STR字数据存储指令
3. STR字数据存储指令:
STR{<cond>} <Rd>,<addr>;
地址addr寻址方式同LDR指令。
 功能:把寄存器Rd中的字数据(32位)保存到addr所表示的
例如:
内存地址中,同时还可以把合成的有效地址写回到基址寄存
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]; 将数据输出到外设端口寄存器中;
39
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.
Endianess Example
r0 = 0x11223344
31
24 23
11
22
16 15
87
33
0
44
STR r0, [r1]
31
24 23
11
22
16 15
87
33
0
31
Memory
44
24 23
44
16 15
33
87
22
0
11
r1 = 0x100
r1 = 0x100
Little-endian
Big-endian
LDRB r2, [r1]
31
24 23
00
00
16 15
87
00
r2 = 0x44
0
44
31
24 23
00
16 15
00
87
00
r2 = 0x11
0
11
 应用举例:(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;
LDR
R4, =x
STR
R3, [R4]
a+b-c -> R3
;(R4)=x
; (a+b)- c存入x变量 42
(2) 用ARM指令实现x=a*(b+c)
ADR R4, b; 变量b的地址装入R4中;LDR R4,=b
LDR
R0, [R4] ;(b)->R0
ADR R4, c
LDR
; LDR R4,=c
R1, [R4] ; (c)->R1
ADD R2, R0,R1 ;b+c ->R2
ADR R4, a
LDR
;LDR R4,=a
R0, [R4] ; (a)->R0
MUL R2, R2,R0; (b+c)*a->R2
ADR R4, x
STR R2, [R4]
;LDR R4,=x
; (b+c)*a->x
43
批量数据加载/存储指令
内存操作: IA IB DA DB
5. LDM批量数据加载指令:
堆栈操作: FA FD EA ED
LDM{<cond>}{<type>} <Rn>{!},<regs>{^};
Rn:保存内存单元的起始地址。
 功能:从一片连续的内存单元读取数据到各个寄存器中,内
Regs:寄存器列表,由若干
存单元的起始地址为基址寄存器Rn的值,各个寄存器由寄存
个寄存器组成,寄存器之间
器列表regs表示。该指令一般用于多个寄存器数据的出栈。
以“,”或“-”分隔。
 {!}:若选用了此后缀,则当指令执行完毕后,将最后的地
址写入基址寄存器。
 ‘^’ 不带^表示用户和系统模式寄存器;
带有^表示异常模式寄存器,此时若LDM包含R15,装载 R15
时恢复 SPSR至CPSR 位。
44
批量数据加载/存储指令
6. STM批量数据存储指令:
STM{<cond>}{<type>} <Rn>{!},<regs>{^};
 功能:将各个寄存器的值存入一片连续的内存单元中,
批量数据存储、加载时,低编号寄存器对应低地址存储
内存单元的起始地址为基址寄存器Rn的值,各个寄存器
单元,与寄存器在指令中出现的次序无关。
由寄存器列表regs表示。该指令一般用于多个寄存器数
据的入栈。
45
批量数据加载/存储指令
 指令中,type字段有以下几种:
满栈(Full):栈顶存储单元含有有效数据。
4种类型的堆栈
空栈(Empty):栈顶存储单元不含有有效数据。
递增(
Aaccumulate ):入栈指针加4,出栈指针减
FD:满递减堆栈;Full
decrease
4。
入栈指针先减再入栈,出栈先出指针再加
递减( Decrease ):入栈指针减4,出栈指针加4。
入栈:STMFD
R13!,{R0,R1}
出栈:LDMFD
R13!,{R2,R3}
FA:满递增堆栈;Full accumulate
入栈指针先加再入栈,出栈先出指针再减
入栈:STMFA
出栈:LDMFA
ED:空递减堆栈;Empty decrease
入栈先入栈指针再减,出栈指针先加再出栈
EA:空递增堆栈;Empty accumulte
入栈先入栈指针再加,出栈指针先减再出栈
46
批量数据加载/存储指令
 指令中,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
LDMDB
R13!,{R0,R1}
R13!,{R2,R3}
47
批量数据加载/存储指令
IA、IB、DA、DB指定了地址加还是减,是传送前还是传送
后 。例如:LDMIA/IB/DA/DB
R13!,{R0-R1,R3};各指令
STMIA/IB/DA/DB
地址变化与
执行完后,结果如图所示:
LDMIA/IB/DA/DB 相同.
R13
0x12345684
0x123456a0
36338832
0x12345690
14543862
0x1234568c
15548545
0x12345688
54693645
0x12345684
66663333
0x12345680
00008888
0x1234567c
59595959
0x12345678
26262626
LDMIA:每次传送后地址加4;
LDMDB:每次传送前地址减4;
LDMIB:每次传送前地址加
4;
LDMDA:每次传送后地址减4;
15548545
14543862
R3
54693645
15548545
R1
00008888 R3
66663333
54693645
66663333
R0
59595959 R1
00008888
59595959
26262626
内存中的数据
48
R0
批量数据加载/存储指令
 FD、ED、FA、和EA指定是满栈还是空栈,是升序栈还是降序
栈,用于堆栈寻址。一个满栈的栈指针指向上次写的最后一
个数据单元,而空栈的栈指针指向第一个空闲单元。一个降
序栈是在内存中反向增长而升序栈在内存中正向增长。如下
图所示,数据以16进制存储。
EA:空递增堆栈;
36338832 FA:满递增堆栈;
0x123456a0
0x123456a0
ED:空递减堆栈;
STM入栈
↑ LDM出栈 ↓
FD:满递减堆栈;
0x123456a0
14543862
0x12345690
STM STM入栈
入栈 ↑ ↓LDM出栈
LDM出栈 ↓↑
0x12345690
0x12345690
栈指针
↓LDM出栈 ↑
15548545 STM入栈
0x1234568c
0x1234568c
0x1234568c
0x12345688
0x12345688
0x12345688
0x12345684
0x12345684
0x12345684
0x12345680
0x12345680
0x12345680
0x1234567c
0x1234567c
0x1234567c
0x12345678
0x12345678
0x12345678
54693645
54693645
66663333
66663333
栈指针
栈指针
栈指针
00008888
59595959
26262626
49
批量数据加载/存储指令
 例如:使用LDM/STM进行现场寄存器保护,常在子程序中或异常处理使用:
SENDBYTE
STMFD SP!,{R0-R7, LR};
例如:
......
寄存器入栈
1、STMEA
R13!,
{R0-R12,PC};将寄存器R0~R12以及程序计数器PC的值
BL
DELAY;
调用DELAY子程序
保存到R13指示的堆栈中。
2、使用LDM/STM进行数据复制:
DELAY
......
......
......
LDR R0,=SrcData; 设置源数据地址
LDMFD SP!,{R0-R7, PC}; 恢复寄存器,并返回
LDR R1,=DstData; 设置目标地址
LDMIA R0, {R2-R9}; 加载8字数据到寄存器R2~R9
STMIA R1, {R2-R9}; 存储寄存器R2~R9到目标地址
50
LDMIA/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 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指令格式
LDMFD R0! {R1, R5, R2}
LDR R1,[R0],#4
LDR R2,[R0],#4
LDR R5,[R0],#4
3.3.6 异常中断指令
ARM处理器支持两条异常中断指令:软件中断指令SWI和断
点中断指令 BKPT。
1. SWI软件中断指令:
SWI{条件} 24位的立即数(系统例程类型) ;
功能:产生软件中断,并调用操作系统的例程。
指令中24位的立即数指定系统例程的类型,其他入口
参数通过通用寄存器传递.
例如:SWI
0X05; 该指令用于调用编号为05的系统例程
57
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指定。
58
BKPT断点中断指令
2. BKPT断点中断指令:
BKPT 16位的立即数;
 功能:用于产生软件断点中断,以便软件调试时使用。
16位的立即数:额外的断点信息,可有可无。
59
内容提要
ARM编程模型
ARM指令格式和寻址方式
ARM指令集
Thumb指令集
思考题
60
举例
 例1:写出执行以下计算的指令序列,其中,X,Y,Z,R,W
均为32位无符号数,两数乘积不超出32位数范围。
(1) ZW-(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.
61