ARM/Thumb-2 指令集精讲
ARM/Thumb-2指令集精讲+配套习题(学生入门版)
本次讲解按基础概念→核心指令类的顺序推进,每个知识点后紧跟基础习题+进阶习题,习题均为学生入门高频考点,同时附带解题思路和答案,帮你边学边练、吃透核心内容。
注:所有讲解和习题以Thumb-2(ARMv7) 为核心(嵌入式开发最常用,考试/实操重点),标注特殊说明的会区分ARM/Thumb差异。
第一部分:基础核心概念精讲(必吃透,否则指令无从谈起)
知识点1:指令格式与通用符号含义
Thumb-2指令的通用格式:指令名{后缀} 目标寄存器, 源寄存器1, 源操作数2
手册中所有符号是指令的「通用语言」,记熟以下高频符号(考频100%):
| 符号/后缀 | 含义 | 核心注意点 |
|---|---|---|
Rd |
目标寄存器 | 运算结果存入该寄存器 |
Rn/Rm/Rs |
源寄存器 | Rn一般为第一操作数,Rm/Rs为第二/移位寄存器 |
{S} |
更新条件标志位 | 加{S}才会修改CPSR的nzcv(负、零、进位、溢出)标志,默认不更新 |
{!} |
回写基址寄存器 | 仅访存指令用,如LDR R0, [R1, #4]!,执行后R1=R1+4 |
<Operand2> |
灵活操作数 | 两种形式:①立即数(#imm);②寄存器移位(Rm, 移位指令 #sh) |
#<imm> |
立即数 | Thumb-2中立即数有取值规则,后续指令会详细讲 |
[Rn, #offset] |
内存地址 | 访存指令专用,表示「基址寄存器Rn + 偏移量offset」对应的内存地址 |
T2 |
Thumb-2专属 | 标注T2的指令仅Thumb-2可用,ARM状态无 |
A |
Thumb不可用 | 标注A的指令仅ARM状态可用,Thumb/Thumb-2无 |
知识点2:核心寄存器(Cortex-M系列,学生入门重点)
Thumb-2(Cortex-M3/M4)的核心寄存器共16个32位通用寄存器R0-R15,其中专用寄存器是考试/实操重点,通用寄存器R0-R12无特殊限制,可随意使用:
- R13:栈指针(SP),分主栈(MSP)和进程栈(PSP),仅用于栈操作(PUSH/POP/访存),不可随意赋值;
- R14:链接寄存器(LR),专门保存函数调用/分支的返回地址,如
BL指令会自动将下一条指令地址存入LR; - R15:程序计数器(PC),指向当前执行的指令,赋值PC直接实现程序跳转,不可作为普通源寄存器。
知识点3:条件码与条件执行(ARM指令集特色,考频80%)
- 条件码:通过CPSR的nzcv标志位判断,手册末尾「Condition Field」的14个条件码中,高频8个记熟即可,其余可查手册:
| 条件码 | 含义 | 对应标志位 | 常用场景 |
|--------|------|------------|----------|
| EQ | 相等 | Z=1 | 比较后判断两数相等 |
| NE | 不相等 | Z=0 | 比较后判断两数不等 |
| CS/HS | 有进位/无符号大于等于 | C=1 | 无符号数运算判断进位/大小 |
| CC/LO | 无进位/无符号小于 | C=0 | 无符号数运算判断无进位/大小 |
| MI | 负数 | N=1 | 有符号数判断为负 |
| PL | 正数/零 | N=0 | 有符号数判断为正/零 |
| GT | 有符号大于 | Z=0且N=V | 有符号数比较大小 |
| LT | 有符号小于 | N≠V | 有符号数比较大小 |
| AL | 总是执行 | 无要求 | 默认,可省略 | - 条件执行规则:
- ARM状态:所有指令可直接加条件码(如
ADDEQ R0, R1, R2,Z=1时才执行); - Thumb-2状态:仅分支指令(B/CBZ)可直接加条件码,其他指令需配合
IT指令实现多指令条件执行(如ITTE EQ,后续3条指令按EQ/EQ/!EQ执行)。
- ARM状态:所有指令可直接加条件码(如
知识点4:移位操作(核心,考频100%)
<Operand2>的寄存器移位形式为Rm, 移位指令 #sh,5种移位操作是基础,直接决定运算结果,记熟移位规则(移位位数sh:Thumb-2中0≤sh≤31):
| 移位指令 | 英文 | 规则 | 适用场景 |
|---|---|---|---|
| LSL | 逻辑左移 | 高位舍弃,低位补0 | 无符号数×2^sh(如LSL#2=×4) |
| LSR | 逻辑右移 | 低位舍弃,高位补0 | 无符号数÷2^sh(如LSR#2=÷4) |
| ASR | 算术右移 | 低位舍弃,高位补符号位(Rm[31]) | 有符号数÷2^sh(保留符号) |
| ROR | 循环右移 | 低位舍弃,补到高位,形成循环 | 位循环、字节交换 |
| RRX | 带进位循环右移 | 结合C标志位循环,仅移1位 | 多字节数循环移位 |
例:Rm=0x80000001(二进制1000...0001),LSL#1=0x00000002,ASR#1=0xC0000000(符号位1补高位)。
基础概念配套习题(入门必做,检验记忆)
一、选择题(每题只有一个正确答案)
- Thumb-2指令中,后缀
{S}的作用是()
A. 回写基址寄存器 B. 更新条件标志位 C. 表示立即数 D. 仅用户模式可用 - 以下哪个寄存器是链接寄存器LR,用于保存返回地址()
A. R13 B. R14 C. R15 D. R12 - Thumb-2中,逻辑左移指令LSL的核心规则是()
A. 高位补0,低位舍弃 B. 高位舍弃,低位补0 C. 高位补符号位,低位舍弃 D. 循环补位 - 条件码EQ对应的标志位状态是()
A. Z=1 B. Z=0 C. C=1 D. N=1
二、判断题(对打√,错打×,并改正错误)
- Thumb-2状态下,所有指令都可以直接加条件码实现条件执行()
- 访存指令中的
{!}表示更新条件标志位() - 程序计数器PC(R15)可以作为普通源寄存器参与加法运算()
- 算术右移ASR和逻辑右移LSR的区别是高位补位不同,ASR补符号位()
三、简答题
- 简述Thumb-2中
<Operand2>的两种常见形式,并各举一个例子。 - 写出Cortex-M系列中3个专用寄存器的名称、编号和核心作用。
基础概念习题答案+解题思路
一、选择题
- B(
{S}=更新nzcv标志,{!}=回写基址,#imm=立即数,{T}=用户模式); - B(R13=SP,R14=LR,R15=PC,R12=通用寄存器);
- B(LSL逻辑左移:高位舍,低位补0);
- A(EQ=相等,Z=1表示运算结果为0,两数相等)。
二、判断题
- ×;改正:Thumb-2中仅分支指令可直接加条件码,其他指令需配合IT指令。
- ×;改正:
{!}是回写基址寄存器,{S}是更新条件标志位。 - ×;改正:PC(R15)不可作为普通源寄存器,仅可赋值实现跳转。
- √(ASR补符号位,用于有符号数;LSR补0,用于无符号数)。
三、简答题
- ①立即数形式:#imm,如
#10、#0x0F;②寄存器移位形式:Rm+移位指令+#sh,如R1, LSL #2、R2, ASR #1。 - ①R13(SP):栈指针,用于栈操作(PUSH/POP/访存);②R14(LR):链接寄存器,保存函数/分支的返回地址;③R15(PC):程序计数器,指向当前执行的指令,赋值实现跳转。
第二部分:核心指令类精讲+配套习题
按「数据移动→算术/逻辑运算→移位指令→访存指令→分支控制」 顺序讲解,这是学生入门必学的5类核心指令,占考试/实操考点的90%以上,每类指令讲高频指令+使用规则+实操案例+配套习题。
模块1:数据移动指令(最基础,考频100%)
核心指令:MOV、MVN、MOVT(Thumb-2专属T2),是所有编程的基础,用于寄存器赋值、数据传递。
1. MOV指令:数据移动/赋值
- 格式:
MOV{S} Rd, <Operand2> - 功能:将
的值赋值给Rd - 关键规则:
① Thumb-2中立即数取值规则:32位立即数由「8位常数左移任意位数」或「0xXYXYXYXY/0x00XY00XY/0xXY00XY00」位模式构成(简单说:能被8位常数表示或重复的立即数才合法);
② 可直接实现「寄存器→寄存器」赋值(如MOV R0, R1);
③ 加{S}会更新标志位(如MOVS R0, #0,执行后Z=1)。 - 实操案例:
✅ 合法:MOV R0, #0x0F(8位常数)、MOV R1, R2, LSL #2(寄存器移位)、MOV R3, #0x12121212(0xXYXYXYXY模式);
❌ 非法:MOV R0, #0x123(非8位常数,也无重复模式)。
2. MVN指令:按位取反后移动
- 格式:
MVN{S} Rd, <Operand2> - 功能:将
按位取反(0→1,1→0)后赋值给Rd(等价于 Rd = ~<Operand2>) - 关键规则:与MOV的立即数/寄存器规则完全一致,常用于生成全1掩码。
- 实操案例:
MVN R0, #0→ #0按位取反为0xFFFFFFFF,R0=0xFFFFFFFF;
MVN R1, R2→ R1 = ~R2。
3. MOVT指令(Thumb-2专属T2):高16位赋值
- 格式:
MOVT Rd, #<imm16> - 功能:将16位立即数
imm16赋值给Rd的高16位(31:16),低16位(15:0)保持不变 - 关键规则:
①imm16范围0~65535(16位全范围),无8位限制;
② 32位全范围赋值必用「MOV+MOVT」:MOV赋低16位,MOVT赋高16位(Thumb-2中MOV直接赋32位常數有局限,这是唯一通用方法)。 - 实操案例:
给R0赋值0x12345678(32位):
MOV R0, #0x5678→ R0低16位=0x5678,高16位=0x0000,R0=0x00005678;
MOVT R0, #0x1234→ R0高16位=0x1234,低16位不变,最终R0=0x12345678。
数据移动指令配套习题
一、选择题
- Thumb-2中,给寄存器32位全范围赋值的通用方法是()
A. 直接用MOV指令 B. MOV+MOVT指令 C. 直接用MOVT指令 D. MVN+MOV指令 - 以下MOV指令中,Thumb-2下合法的是()
A. MOV R0, #0x123456 B. MOV R1, #0xABABABAB C. MOV R2, #0x12345678 D. MOV R3, #0x1000 - MVN R0, #0的执行结果是()
A. R0=0 B. R0=0xFF C. R0=0xFFFFFFFF D. R0=0x000000FF - 指令
MOVT R1, #0x4567的作用是()
A. 给R1低16位赋值0x4567,高16位清0 B. 给R1高16位赋值0x4567,低16位不变
C. 给R132位赋值0x4567 D. 给R1按位取反后赋值0x4567
二、编程题(Thumb-2环境,Cortex-M3)
- 写出指令,将寄存器R0赋值为0x9876ABCD(32位合法立即数)。
- 写出指令,将寄存器R1的内容按位取反后存入R2,并更新条件标志位。
- 写出指令,实现「将R3的值左移4位后赋值给R4」(用MOV指令的
移位形式)。
三、分析题(判断指令是否合法,若非法说明原因)
- MOV R5, #0x123 2. MOVT R6, #0x123456 3. MVN R7, R8, LSR #3 4. MOV R15, #0x1000
数据移动指令习题答案+解题思路
一、选择题
- B(MOV赋低16位,MOVT赋高16位,实现32位全赋值);
- B(0xABABABAB是0xXYXYXYXY模式,符合Thumb-2立即数规则;A/C是超过8位的非重复数,D无8位常数/重复模式);
- C(#0按位取反是32位全1,即0xFFFFFFFF);
- B(MOVT仅修改高16位,低16位不变)。
二、编程题
- 分步赋值:
MOV R0, #0xABCD(赋低16位)
MOVT R0, #0x9876(赋高16位) - 加{S}更新标志位,MVN实现取反:
MVNS R2, R1 - MOV+寄存器移位形式:
MOV R4, R3, LSL #4
三、分析题
- 非法;原因:#0x123既不是8位常数,也无0xXYXYXYXY等重复模式,违反Thumb-2立即数规则。
- 非法;原因:MOVT的imm16是16位立即数,范围0~65535,0x123456是24位,超出范围。
- 合法;原因:MVN的
支持寄存器移位形式,LSR#3是合法移位。 - 非法;原因:R15是PC(程序计数器),不可直接用立即数赋值(Thumb-2中PC赋值需通过访存/分支指令)。
模块2:算术运算指令(编程核心,考频100%)
核心指令:ADD/ADC(加法)、SUB/SBC(减法)、CMP(比较),是数值运算的基础,带进位的ADC/SBC是64位运算的关键(高频考点)。
1. ADD指令:普通加法
- 格式:
ADD{S} Rd, Rn, <Operand2> - 功能:
Rd = Rn + <Operand2> - 关键规则:
①支持立即数/寄存器移位(与MOV规则一致);
② 加{S}更新nzcv标志(如进位C=1表示加法结果超过32位);
③ Thumb-2有宽立即数ADD(T2):ADD Rd, Rn, #<imm12>,imm12范围0~4095(直接支持大立即数加法,无需移位)。 - 实操案例:
ADD R0, R1, R2→ R0=R1+R2;
ADDS R3, R4, #10→ R3=R4+10,更新标志位;
ADD R5, R6, R7, LSL #2→ R5=R6 + (R7×4)。
2. ADC指令:带进位加法
- 格式:
ADC{S} Rd, Rn, <Operand2> - 功能:
Rd = Rn + <Operand2> + C(C是上一次运算的进位标志位) - 关键规则:
① 必须与ADDS配合使用,先算低32位ADDS(产生进位C),再算高32位ADC;
② 唯一用途:实现64位/多字节加法(学生入门核心考点)。 - 实操案例:64位加法(R1:R0 = 高32位:低32位,R3:R2 = 高32位:低32位,结果存入R5:R4):
ADDS R4, R0, R2→ 低32位相加,产生进位C;
ADC R5, R1, R3→ 高32位+进位C,最终R5:R4=64位和。
3. SUB指令:普通减法
- 格式:
SUB{S} Rd, Rn, <Operand2> - 功能:
Rd = Rn - <Operand2> - 关键规则:与ADD一致,加
{S}更新nzcv标志(C=0表示减法有借位,C=1表示无借位);Thumb-2有宽立即数SUB(T2):SUB Rd, Rn, #<imm12>(0~4095)。 - 实操案例:
SUB R0, R1, #5→ R0=R1-5;
SUBS R2, R3, R4, ASR #1→ R2=R3 - (R4÷2),更新标志位。
4. SBC指令:带借位减法
- 格式:
SBC{S} Rd, Rn, <Operand2> - 功能:
Rd = Rn - <Operand2> - NOT(C)(NOT(C):C=0则为1,C=1则为0,对应借位) - 关键规则:与ADC一致,必须与SUBS配合实现64位/多字节减法。
- 实操案例:64位减法(R1:R0 - R3:R2,结果存入R5:R4):
SUBS R4, R0, R2→ 低32位相减,产生借位标志C;
SBC R5, R1, R3→ 高32位-借位,最终R5:R4=64位差。
5. CMP指令:比较(隐式减法,仅更标志)
- 格式:
CMP Rn, <Operand2> - 功能:执行
Rn - <Operand2>,不保存结果,仅更新nzcv标志位(核心:通过标志位判断两数大小/相等) - 关键规则:
① 本质是SUBS指令省略目标寄存器,仅更标志;
② 后续必跟分支指令+条件码(如CMP R0, #0+BEQ label,R0=0时跳转到label);
③ 无符号数比较用CS/CC,有符号数比较用GT/LT/GE/LE。 - 实操案例:
CMP R0, R1→ 比较R0和R1,更新标志位;
BEQ label→ 若R0=R1(Z=1),跳转到label;
BGT label2→ 若R0>R1(有符号),跳转到label2。
算术运算指令配套习题(含64位运算高频考点)
一、选择题
- 实现64位加法的核心指令组合是()
A. ADD+SUB B. ADDS+ADC C. ADD+ADC D. ADDS+SUB - CMP指令的本质是()
A. 加法指令,仅更新标志位 B. 减法指令,保存结果并更新标志位
C. 减法指令,仅更新标志位 D. 乘法指令,仅更新标志位 - Thumb-2中,宽立即数ADD指令的imm12范围是()
A. 0~255 B. 0~4095 C. 0~65535 D. 0~1020 - 指令
SUBS R0, R1, #5执行后,C=0表示()
A. 减法无借位 B. 减法有借位 C. 结果为0 D. 结果为负
二、编程题(Thumb-2,Cortex-M3,高频考点)
- 写出指令,实现32位加法:R0 = R1 + R2×8,且更新条件标志位。
- 写出指令,实现64位加法:将64位数(R3:R2)和(R5:R4)相加,结果存入(R7:R6)(R3/R5为高32位,R2/R4为低32位)。
- 写出指令,实现逻辑:比较R0和#10,若R0等于10则跳转到标签
EQ10,若R0大于10(有符号)则跳转到标签GT10。 - 写出指令,实现64位减法:将64位数(R1:R0)减去(R3:R2),结果存入(R5:R4)。
三、分析题(写出指令执行结果,假设初始寄存器值)
已知:R0=0xFFFFFFF0,R1=0x00000020,执行以下指令,写出R2/R3的值和C标志位状态:
- ADDS R2, R0, R1 2. ADC R3, #0, #0
算术运算指令习题答案+解题思路
一、选择题
- B(ADDS算低32位,产生进位C;ADC算高32位+进位,实现64位加法);
- C(CMP=SUBS省略Rd,仅执行Rn-Operand2并更新标志,不保存结果);
- B(Thumb-2宽立即数ADD的imm12是12位,范围0~4095);
- B(减法中C=0表示有借位,C=1表示无借位,与加法相反)。
二、编程题
- R2×8=R2 LSL#3,加{S}更新标志:
ADDS R0, R1, R2, LSL #3 - 64位加法:低32位ADDS,高32位ADC:
ADDS R6, R2, R4
ADC R7, R3, R5 - CMP比较+条件分支指令:
CMP R0, #10
BEQ EQ10
BGT GT10 - 64位减法:低32位SUBS,高32位SBC:
SUBS R4, R0, R2
SBC R5, R1, R3
三、分析题
- ADDS R2, R0, R1:0xFFFFFFF0 + 0x00000020 = 0x100000010(32位寄存器只能存低32位)→ R2=0x00000010;加法结果超过32位,C=1(进位)。
- ADC R3, #0, #0:R3 = 0 + 0 + C = 0+0+1=R3=0x00000001,C保持1(无新运算)。
最终结果:R2=0x00000010,R3=0x00000001,C=1。
(后续将继续讲解逻辑运算、移位、访存、分支控制指令,均附带详细规则+实操案例+高频习题,需要我继续更新这部分内容吗?)

浙公网安备 33010602011771号