第三章 ARM7指令系统【嵌入式系统】

第三章 ARM7指令系统【嵌入式系统】本文详细介绍了 ARM7TDMI 指令集 包括指令分类 格式 条件域 操作数形式以及寻址方式

大家好,欢迎来到IT知识分享网。

前言

2023-7-3 17:05:04

以下内容源自《【嵌入式系统】》
仅供学习交流使用

推荐

第二章 ARM 技术及体系结构【嵌入式系统】

第三章 ARM7指令系统

3.1. ARM7TDMI 指令集概述

3.1.1 ARM 指令分类

3.1.2 指令格式

1.指令的机器编码格式
在 ARM 指令集中,每条指令占有 4 个字节,即指令长度为 32 位,其指令的二进制编
码格式如图 3.1 所示
在这里插入图片描述
其中:
Cond 为指令执行的条件。
Opcode 为数据处理指令/程序状态寄存器(PSR)处理指令的操作编码。在访问指令中
表示是否为有符号数访问。
Rn 为第一操作数,Operand2 为第二操作数,Rd 为目的操作数。
Rs、Rm 分别为乘法指令中的乘数和被乘数。
RdHi、RdLo 分别为长乘法指令乘积的高 32 位寄存器和低 32 位寄存器。
在乘法指令中 A 表示乘加指令,U 表示带符号数的乘法。
S 在数据处理指令中设置是否影响程序状态寄存器中的条件标志位。
I 是 Operand2 的类型制定,I 为 0 时,偏移量为 12 位立即数,为 1 时,偏移量为带移
位的寄存器。
在加载/存储指令中,B 表示字节访问。P 表示前/后变址。W 表示写回。U 表示变址为
加/减。L 用于区别加载(L 为 1)或存储(L 为 0)。
Cp opc 为协处理器的操作编码。
















2.指令的汇编格式
在汇编程序设计中,ARM 指令采用三地址的指令格式,即一个目的操作数和两个源操
作数,汇编指令的基本组成如下:
<指令助记符>{<执行条件>}{S} <目标寄存器>, <第 1 操作数的寄存器> {,<第 2 操作数>}
< opcode> {< cond>} {S} < Rd> , < Rn> {,< operand2>}
其中,< >号内的项是必需的,{}号内的项是可选的。如是指令助记符,是必
须含有的,而{}为指令执行条件,是依据实际需要可选项。若不书写,则使用默认条
件 AL(无条件执行)。
opcode 指令助记符,如 LDR、STR 等。用于指定指令的操作功能。
cond 执行条件,如 EQ、NE 等,参考表 3-2。用于指定指令的执行条件。
S 指定指令执行是否影响 CPSR 寄存器中的条件标志位,选择时影响 CPSR。
Rd 目标寄存器。用于存放运算的结果。
Rn 第 1 个操作数寄存器。用于存放参与运算的操作数 1。
operand2 第 2 个操作数。用于指定参与运算的操作数 2。












【例 3-1】
MOV R0,R1 ;将 R1 中的值送入 R0
SUBS R0, R1, R2 ;将 R1 中值减去 R2 的值,结果保存到 R0,并影响 CPSR。
LDR R0, [R1, #0x0C] ;将 R1+0x0C 所指向的存储器单元内容加载到 R0 中。


在这里插入图片描述
在这里插入图片描述
ARM 处理器支持 16 种条件码,分别对应了 CPSR 寄存器标志位(N、Z、C、V)的 16
个组合状态值,处理器根据 CPSR 中标志位 N、Z、C 和 V 的值来确定指令是执行还是跳过。
表 3-2 给出了这些条件码助记符及其对应的状态标志值。ARM 指令使用条件码助记符来指
定本指令的执行条件。其中条件(AL) 是缺省条件,可以省略。如果指令不含有条件码助记
符时,就默认是该条件。
ARM 指令具有条件执行的特点,提高了程序中条件语言的效率,如【例 3-2】






在这里插入图片描述

3.1.3 指令的条件域

3.1.4 第 2 个操作数(operand2)的三种形式

  • #immed_8r——常数表达式;
  • Rm——寄存器方式;
  • Rm,shift——寄存器移位方式。
    1.常数表达方式
    #immed_8r 是常数表达式,该常数必修对应 8 位位图,即常数是由一个 8 位的常数循环
    左移偶数位得到。例如 0x3FC00(0xFF<<10)、0x168(0x5A<<2)、0x(0x35<<16)、
    0xE0000007(0x7E<<28)是合法常数;而 0x3F2、286、0x10010、0x 是非法常数。
    【例 3-2】




MOV R2,#100 ;R2←100 AND R1,R2,#0x3F00 ;R2 与 0x3F00,结果保存到 R1 中 LDR R0,[R1],# -8 ;将 R1 指向的存储器单元内容加载到 R0 中,随后 R1←R1-8 

2.寄存器方式
Rm 指寄存器方式,在寄存器方式下操作数即为寄存器中的数值。
【例 3-3】

SUB R0,R1,R2 ;R0=R1-R2 MOV PC,R0 ;PC=R0,ARM 处理器将跳转到 R0 指定地址处执行 LDR R0,[R1],-R2 ;将 R1 指向的存储器单元内容加载到 R0,修改 R1=R1-R2 

3.寄存器移位方式
Rm,shift 表示使用寄存器的移位结果作为操作数,但 Rm 值保持不变。移位方法如图
3.2 所示:

在这里插入图片描述

LSL # n ;逻辑左移 n 位(1≤n≤31) LSR # n ;逻辑右移 n 位(1≤n≤31) ASR # n ;算术右移 n 位(1≤n≤31) ROR # n ;循环右移 n 位(1≤n≤31) RRX ;带扩展的循环右移,操作数右移一位,高位有 C 标志填充。 Type Rs ; type 为 ASR、LSL、LSR 和 ROR 中的一种;Rs 偏移量寄存器, ;低 8 位有效。通常使用通用寄存器用作 Rs 

【例 3-4】

ADD R0,R1,R1,LSL #3 ;R0=R1+(R1<<3)。 SUB R0,R1,R2,LSR R3 ;R0 = R1-(R2 >>(R3))。 MOV R0,R1,RRX ;将 R1 带扩展的循环右移 1 位,存入 R0 中 

3.2. ARM 指令的寻址方式

寻址方式是处理器根据指令中给出的地址信息来寻找物理地址的方法,ARM 处理器有
8 种基本寻址方式。

(1) 立即寻址
立即寻址也叫立即数寻址,立即寻址指令中的地址码部分就是操作数本身,即操作数包
含在指令之中,取出指令也就取出了可以立即使用的操作数。
【例 3-5】
MOV R0,#75 ;将立即数 75 送入 R0。
SUB R1,R0,#0x5600 ;R0 的值减立即数 0x5600,然后将结果送回 R1。
前缀“#”号表示立即数,“0x”表示 16 进制数值。





(2)寄存器寻址
寄存器寻址就是将寄存器中的数值作为操作数,指令中的地址码指出的是寄存器编号,
指令执行时直接取出寄存器值进行操作。
【例 3-6】


MOV R0,R1 ; R0←R1 SUB R0,R1,R2 ;R0←R1-R0 

(3)寄存器移位寻址
寄存器移位寻址是ARM指令集特有的寻址方式,当第二个操作数是寄存器偏移方式时,
可以选择进行移位操作。
【例 3-7】


MOV R0,R1,LSL #3 ;R1 的值逻辑左移 3 位,结果放入 R0 ;即是 R0=R1×8 MOV R0,R1,ROR R2 ;R1 的值循环右移 R2 位,然后放入 R0 AND R0,R1,R2,LSL R3 ;R2 的值逻辑左移 R3 位,再和 R1 的值相“与”, ;结果放入 R0 

(4)寄存器间接寻址
寄存器间接寻址就是以寄存器中的值作为操作数的地址,而操作数本身存放在存储器
中,即寄存器用作操作数的地址指针。

【例 3-8】 LDR R0,[R1] ;将 R1 指向的存储单元中的数据,读取后保存到 R0 中 STR R0,[R1] ;将 R0 中的数据保存到 R1 指向的存储单元中 

(5)基址变址寻址
基址变址寻址就是将寄存器(一般称为基址寄存器)中的内容与指令中给出的地址偏移
量相加,形成操作数的有效地址
。基址变址寻址用于访问基址附近的存储单元,常用于查表、
数组操作、功能部件寄存器访问等。寄存器间接寻址是偏移量为0的基址变址寻址。
基址变址寻址分为前变址法和后变址法
① 前变址法(也叫前索引偏移):基地址寄存器中的值和地址偏移量先作加减运算,生
成的操作数作为内存访问的地址。
② 后变址法(也叫后索引偏移):将基地址寄存器中的值直接作为内存访问的地址进行
操作,内存访问完毕后基地址寄存器中的值和地址偏移量作加减运算,并更新基地址寄
存器内容。
【例3-9】








LDR R0,[R1,#6] ;R0←[R1+6]。 
LDR R0,[R1,#6]! ;R0←[R1+6],R1←R1+6。 
LDR R0,[R1],#6 ;R0←[R1],R1←R1+6。 
LDR R0,[R1,R2] ;R0←[R1+R2]。 

(6)相对寻址
相对寻址是基址寻址的一种变通。由程序计数器 PC 作为基地址寄存器,指令中的地址
码字段作为偏移量,两者相加后得到的地址即为操作数的有效地址。
【例 3-10】


Start MOV R0, #0 MOV R1, #3 MOV R2, #2 BL arithfunc ;转移到arithfunc,是相对寻址 ... ... arithfunc CMP R0, #num MOVHS PC, LR ;返回 ... .. 

相对寻址中偏移量及有效地址的计算如下图3.3所示。

在这里插入图片描述
(7)多寄存器寻址
多寄存器寻址是指一次可以传送多个寄存器的值,允许一条指令传送 16 个寄存器的任
何子集或所有 16 个寄存器。
【例 3-11】



LDMIA R1!,{R2-R5,R12} ;R2←[R1],R1←R1+4 ;R3←[R1],R1←R1+4 ;R4←[R1],R1←R1+4 ;R5←[R1],R1←R1+4 ;R12←[R1],R1←R1+4 STMIA R0,{R2-R5, R12} ;[R0]←R2 ;[R0+4]←R3 ;[R0+8]←R4 ;[R0+12]←R5 ;[R0+16]←R12 

补充:表5-7

在这里插入图片描述

(8)堆栈寻址
堆栈是一个按特定顺序进行存取的存储区,操作顺序为“先进后出” ,堆栈寻址是隐含
的,它使用一个专门的寄存器(堆栈指针)指向一块存储区域(堆栈),指针所指向的存储单元
是堆栈的栈顶。堆栈按照生长方向可分为两种如图3.4所示:
向上生长:向高地址方向生长,称为递增堆栈
向下生长:向低地址方向生长,称为递减堆栈




在这里插入图片描述
从堆栈指针指向的栈顶位置不同,又分为满堆栈和空堆栈,如图3.5所示。
满堆栈:堆栈指针SP指向最后压入的堆栈的有效数据项,
空堆栈:堆栈指针SP指向下一个待压入数据的空位置,


在这里插入图片描述
根据上述堆栈生长方式和堆栈指针位置的不同,可以组合出四种类型的堆栈方式:
① 满递增堆栈:堆栈向上增长,堆栈指针SP指向含有效数据项的最高地址。指令如
LDMFA、STMFA等;
② 空递增堆栈:堆栈向上增长,堆栈指针SP指向堆栈上的第一个空位置。指令如
LDMEA、STMEA等;
③ 满递减堆栈:堆栈向下增长,堆栈指针SP指向含有效数据项的最低地址。指令如
LDMFD、STMFD等;
④ 空递减堆栈:堆栈向下增长,堆栈指针SP指向堆栈下的第一个空位置。指令如
LDMED、STMED等。








解释采自:https://www.jianshu.com/p/aa4695b6bc26 LD : load 加载,出栈操作 ST : store 存储,入栈操作 M : multi 多次 F:full 满栈,SP指向最后一个数据 E:empty 空栈,SP指向与最后一个数据相邻的下一个可写入存储单元 D:descending 递减,代表栈的增长方向 A:ascending 递增,代表栈的增长方向 

【例 3-12】

STMFD SP!,{R1-R7,LR} ;将 R1~R7,LR 入栈,满递减堆栈 LDMFD SP!,{R1-R7,LR} ;数据出栈,放入 R1~R7,LR 寄存器, ;满递减堆栈 

补充:表5-8

在这里插入图片描述

3.3. ARM 指令集介绍

3.3.1 数据处理指令

在这里插入图片描述

3.3.2 乘法指令

在这里插入图片描述

3.3.3 分支指令

  • 分支指令 B;
  • 带连接的分支指令 BL;
  • 带状态切换的分支指令 BX。

在这里插入图片描述

3.3.4 程序状态寄存器访问指令

① MRS 读状态寄存器指令
MRS 指令格式: MRS{cond} Rd, CPSR
MRS{cond} Rd, SPSR
其中: Rd 为目标寄存器,Rd 不允许为 R15。
MRS 指令将 CPSR 或 SPSR 中的内容装入到一个通用寄存器中。在 ARM 处理器中,只
有 MRS 指令可以对状态寄存器 CPSR 和 SPSR 进行读操作。通过读 CPSR 可以了解当前处
理器的工作状态。读 SPSR 寄存器可以了解到进入异常前的处理器状态。
【例 3-38】






MRS R0, CPSR ; 将 CPSR 状态寄存器值读取到 R0 中 MRS R2, SPSR ; 将 SPSR 状态寄存器值读取到 R2 中 

② MSR 写状态寄存器指令
指令格式:MSR{cond} PSR_fields, #immed_8r
MSR{cond} PSR_fields, Rm
其中: immed_8r:要传送到状态寄存器指定域的 8bit 立即数,。
Rm :要传送到状态寄存器指定域的源寄存器数。
PSR :指 CPSR 或 SPSR 寄存器。
Fields:指定传送的区域,分别对应 PSR 的 4 个字节片段。fields 可以是以下
的一种或多种(字母必须为小写):






  • c 控制域字节(psr[7…0]);
  • x 扩展域字节(psr[15…8]);
  • s 状态域字节(psr[23…16]);
  • f 标志域字节(psr[31…24])。

各个域在 CPRS 寄存器中的位置如错误!未找到引用源。所示。

在这里插入图片描述
MSR 指令将一个立即常数装载到 CPSR 或 SPSR 指定的位域中,或者将一个通用寄存
器中的内容装载到 CPSR 或者 SPSR 中。在 ARM 处理器中,只有 MSR 指令可以对状态寄
存器 CPSR 和 SPSR 进行写操作。


【例 3-39】

MSR CPSR_c, #0xD3 ; CPSR[7…0]=0xD3,即切换到管理模式 MSR CPSR_cxsf, R3 ; CPSR=R3 
ENABLE_IRQ MRS R0, CPSR BIC R0, R0, #0x80 ; 清除 CPSR 的 I 位,允许处理器 IRQ 中断 MSR CPSR_c, R0 MOV PC, LR 

【例 3-41】禁止 IRQ 中断

DISABLE_IRQ MRS R0, CPSR ORR R0, R0, #0x80 ; 将 CPSR 的 I 位置‘1’,屏蔽处理器的 IRQ 中断 MSR CPSR_c, R0 MOV PC, LR 

【例 3-42】地址指针初始化

INITSTACK ; 设置管理模式堆栈指针 MRS R0 , CPSR ;读 CPSR 到 R0 BIC R0 , R0,#0x1F ;R0 的低 5 位清零 ORR R0 , R0,#0x13 ;0x13 是管理模式编码 MSR CPSR_c, R0 ; 切换处理器工作模式到“管理模式” LDR SP, StackSvc ; 开辟‘管理模式’下的堆栈区 ; 设置 IRQ 中断模式堆栈指针 MRS R0 , CPSR ;读 CPSR 到 R0 BIC R0 , R0,#0x1F ;R0 的低 5 位清零 ORR R0 , R0,#0x12 ;0x12 是 IRQ 模式码 MSR CPSR_c, R0 ; 切换处理器工作模式到‘irq 模式’ LDR SP, StackIrq ; 开辟‘irq 模式’下的堆栈区 … 

小tip:
如何记忆MRS和MSR

记住: M:Move output<-input 移动 R:regs 一般寄存器 S:status regs 状态寄存器 

3.3.5 ARM 软中断指令

MOV R0,#34 ;设置子功能号为 34 SWI 0x ;调用 0x 号软中断 
MOV R0,# 0x ;调用 12 号软中断 MOV R1,#34 ;设置子功能号为 34 SWI 0 

【例 3-45】

SWI_Handler STMFD SP!,{R0-R3,R12,LR} ;现场保护 MRS R0,SPSR ;读取 SPSR STMFD SP!,{R0} ;保存 SPSR TST R0,#0x20 ;测试 T 标志位 LDRNEH R0, [LR,#-2] ;若是 Thumb 指令,读取指令码(16 位) BICNE R0,R0,#0xFF00 ;取得 Thumb 指令的 8 位立即数(低 8 位) LDREQ R0,[LR,#-4] ;若是 ARM 指令,读取指令码(32 位) BICEQ R0,R0,#0xFF000000 ;取得 ARM 指令的 24 位立即数(低 24 位) ... … LDMFD SP!,{R0-R3, R12,PC}^ ;SWI 异常中断返回,添加“^”符号表示 ;同时将 SPSR 内容拷贝到 CPSR 中。 

3.3.6 ARM 存储器访问指令

在这里插入图片描述
1. 单寄存器加载/存储指令

从寻址方式中地址计算方法来划分,加载/存储指令有 4 种格式
① 零偏移。当偏移量为 0 时,即为零偏移。
② 前索引偏移。在数据传送之前,先通过基地址和偏移量的值计算有效地址,将有效
地址作为传送数据的存储地址。若使用后缀“!”,则将有效地址写回到基址寄存器 Rn 中,
且 Rn 不允许为 R15;否则,不修改基址寄存器的值。
③程序相对偏移。将基址寄存器默认为 PC。并且在语句中省略,只保留偏移量(通常
直接使用语句标号指定)。不能使用后缀“!”。
④ 后索引偏移。基址寄存器的值直接用作传送数据的存储地址。在数据传送后,将基
址寄存器 Rn 与偏移量求和,并将结果写回到 Rn 中,Rn 不允许是 R15。
注意:必须保证字数据操作的地址是字对齐存储。
【例 3-49】









LDRT R0,[R1] ;零偏移,以用户模式。 LDR Rd,[Rn,Rm]! ;前索引偏移,要求将 Rn 与 Rm 之和写回到 Rn 中。 STR Rd,[Rn,#-0x04] ;前索引偏移,要求(Rn-0x04)不写回 Rn。 STR Rd,[Rn],#0x04 ; 后索引偏移,要求 Rn= Rn+0x04。 LDR Rd,[Rn],Rm ;后索引偏移,要求 Rn= Rn+Rn。 LDR Rd,label ;将标号 label 地址中存放的数据加载到 Rd 中。 

2. 多寄存器加载/存储指令

I:increase v.增加 D:decrease v.减少 A:after prep.之后 B:before prep.之前 

在这里插入图片描述
区别:只有!,使得指令完成数据传送后更新基址寄存器R0的值。

在这里插入图片描述

说明 //地址±1就是R0±4 IA:传送后增加//后缀地址++;M=[R0++]  IB:传送前增加//前缀地址++;M=[++R0]  DA:传送后减少//后缀地址--;M=[R0--]  IB:传送前减少//前缀地址--;M=[--R0]  

3. 堆栈操作指令
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
4. SWP 寄存器和存储器交换指令
在这里插入图片描述




3.3.7 ARM 协处理器操作指令

3.3.8 ARM 伪指令

1. LDR 大范围的地址或立即数的读取

在这里插入图片描述

【例3-56】

在这里插入图片描述

在这里插入图片描述

2. ADRL 中等范围的地址读取伪指令

3. ADR 小范围的地址读取伪指令

4. NOP 空操作伪指令
NOP 伪指令在汇编时将会被代替成 ARM 中的空操作,比如可能为“MOV R0, R0”指
令等。NOP 可用于延时操作。
指令格式:NOP


Delay NOP ;空操作 NOP NOP SUBS R0,R0,#1 ;循环次数减一 BNE Delay ;如果循环未结束,跳转 Delay 继续 MOV PC,LR ;子程序返回 

3.4. Thumb 指令集

最后

2023-7-3 18:04:30

免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://haidsoft.com/124199.html

(0)
上一篇 2025-10-08 20:10
下一篇 2025-10-08 20:15

相关推荐

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注微信