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无特殊限制,可随意使用:

  1. R13:栈指针(SP),分主栈(MSP)和进程栈(PSP),仅用于栈操作(PUSH/POP/访存),不可随意赋值;
  2. R14:链接寄存器(LR),专门保存函数调用/分支的返回地址,如BL指令会自动将下一条指令地址存入LR;
  3. R15:程序计数器(PC),指向当前执行的指令,赋值PC直接实现程序跳转,不可作为普通源寄存器。

知识点3:条件码与条件执行(ARM指令集特色,考频80%)

  1. 条件码:通过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 | 总是执行 | 无要求 | 默认,可省略 |
  2. 条件执行规则
    • ARM状态:所有指令可直接加条件码(如ADDEQ R0, R1, R2,Z=1时才执行);
    • Thumb-2状态:仅分支指令(B/CBZ)可直接加条件码,其他指令需配合IT指令实现多指令条件执行(如ITTE EQ,后续3条指令按EQ/EQ/!EQ执行)。

知识点4:移位操作(核心,考频100%)

<Operand2>的寄存器移位形式为Rm, 移位指令 #sh5种移位操作是基础,直接决定运算结果,记熟移位规则(移位位数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补高位)。

基础概念配套习题(入门必做,检验记忆)

一、选择题(每题只有一个正确答案)

  1. Thumb-2指令中,后缀{S}的作用是()
    A. 回写基址寄存器 B. 更新条件标志位 C. 表示立即数 D. 仅用户模式可用
  2. 以下哪个寄存器是链接寄存器LR,用于保存返回地址()
    A. R13 B. R14 C. R15 D. R12
  3. Thumb-2中,逻辑左移指令LSL的核心规则是()
    A. 高位补0,低位舍弃 B. 高位舍弃,低位补0 C. 高位补符号位,低位舍弃 D. 循环补位
  4. 条件码EQ对应的标志位状态是()
    A. Z=1 B. Z=0 C. C=1 D. N=1

二、判断题(对打√,错打×,并改正错误)

  1. Thumb-2状态下,所有指令都可以直接加条件码实现条件执行()
  2. 访存指令中的{!}表示更新条件标志位()
  3. 程序计数器PC(R15)可以作为普通源寄存器参与加法运算()
  4. 算术右移ASR和逻辑右移LSR的区别是高位补位不同,ASR补符号位()

三、简答题

  1. 简述Thumb-2中<Operand2>的两种常见形式,并各举一个例子。
  2. 写出Cortex-M系列中3个专用寄存器的名称、编号和核心作用。

基础概念习题答案+解题思路

一、选择题

  1. B({S}=更新nzcv标志,{!}=回写基址,#imm=立即数,{T}=用户模式);
  2. B(R13=SP,R14=LR,R15=PC,R12=通用寄存器);
  3. B(LSL逻辑左移:高位舍,低位补0);
  4. A(EQ=相等,Z=1表示运算结果为0,两数相等)。

二、判断题

  1. ×;改正:Thumb-2中仅分支指令可直接加条件码,其他指令需配合IT指令。
  2. ×;改正:{!}是回写基址寄存器,{S}是更新条件标志位。
  3. ×;改正:PC(R15)不可作为普通源寄存器,仅可赋值实现跳转。
  4. √(ASR补符号位,用于有符号数;LSR补0,用于无符号数)。

三、简答题

  1. ①立即数形式:#imm,如#10#0x0F;②寄存器移位形式:Rm+移位指令+#sh,如R1, LSL #2R2, ASR #1
  2. ①R13(SP):栈指针,用于栈操作(PUSH/POP/访存);②R14(LR):链接寄存器,保存函数/分支的返回地址;③R15(PC):程序计数器,指向当前执行的指令,赋值实现跳转。

第二部分:核心指令类精讲+配套习题

「数据移动→算术/逻辑运算→移位指令→访存指令→分支控制」 顺序讲解,这是学生入门必学的5类核心指令,占考试/实操考点的90%以上,每类指令讲高频指令+使用规则+实操案例+配套习题

模块1:数据移动指令(最基础,考频100%)

核心指令MOVMVNMOVT(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。

数据移动指令配套习题

一、选择题

  1. Thumb-2中,给寄存器32位全范围赋值的通用方法是()
    A. 直接用MOV指令 B. MOV+MOVT指令 C. 直接用MOVT指令 D. MVN+MOV指令
  2. 以下MOV指令中,Thumb-2下合法的是()
    A. MOV R0, #0x123456 B. MOV R1, #0xABABABAB C. MOV R2, #0x12345678 D. MOV R3, #0x1000
  3. MVN R0, #0的执行结果是()
    A. R0=0 B. R0=0xFF C. R0=0xFFFFFFFF D. R0=0x000000FF
  4. 指令MOVT R1, #0x4567的作用是()
    A. 给R1低16位赋值0x4567,高16位清0 B. 给R1高16位赋值0x4567,低16位不变
    C. 给R132位赋值0x4567 D. 给R1按位取反后赋值0x4567

二、编程题(Thumb-2环境,Cortex-M3)

  1. 写出指令,将寄存器R0赋值为0x9876ABCD(32位合法立即数)。
  2. 写出指令,将寄存器R1的内容按位取反后存入R2,并更新条件标志位。
  3. 写出指令,实现「将R3的值左移4位后赋值给R4」(用MOV指令的移位形式)。

三、分析题(判断指令是否合法,若非法说明原因)

  1. MOV R5, #0x123 2. MOVT R6, #0x123456 3. MVN R7, R8, LSR #3 4. MOV R15, #0x1000

数据移动指令习题答案+解题思路

一、选择题

  1. B(MOV赋低16位,MOVT赋高16位,实现32位全赋值);
  2. B(0xABABABAB是0xXYXYXYXY模式,符合Thumb-2立即数规则;A/C是超过8位的非重复数,D无8位常数/重复模式);
  3. C(#0按位取反是32位全1,即0xFFFFFFFF);
  4. B(MOVT仅修改高16位,低16位不变)。

二、编程题

  1. 分步赋值:
    MOV R0, #0xABCD (赋低16位)
    MOVT R0, #0x9876(赋高16位)
  2. 加{S}更新标志位,MVN实现取反:
    MVNS R2, R1
  3. MOV+寄存器移位形式:
    MOV R4, R3, LSL #4

三、分析题

  1. 非法;原因:#0x123既不是8位常数,也无0xXYXYXYXY等重复模式,违反Thumb-2立即数规则。
  2. 非法;原因:MOVT的imm16是16位立即数,范围0~65535,0x123456是24位,超出范围。
  3. 合法;原因:MVN的支持寄存器移位形式,LSR#3是合法移位。
  4. 非法;原因: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位运算高频考点)

一、选择题

  1. 实现64位加法的核心指令组合是()
    A. ADD+SUB B. ADDS+ADC C. ADD+ADC D. ADDS+SUB
  2. CMP指令的本质是()
    A. 加法指令,仅更新标志位 B. 减法指令,保存结果并更新标志位
    C. 减法指令,仅更新标志位 D. 乘法指令,仅更新标志位
  3. Thumb-2中,宽立即数ADD指令的imm12范围是()
    A. 0~255 B. 0~4095 C. 0~65535 D. 0~1020
  4. 指令SUBS R0, R1, #5执行后,C=0表示()
    A. 减法无借位 B. 减法有借位 C. 结果为0 D. 结果为负

二、编程题(Thumb-2,Cortex-M3,高频考点)

  1. 写出指令,实现32位加法:R0 = R1 + R2×8,且更新条件标志位。
  2. 写出指令,实现64位加法:将64位数(R3:R2)和(R5:R4)相加,结果存入(R7:R6)(R3/R5为高32位,R2/R4为低32位)。
  3. 写出指令,实现逻辑:比较R0和#10,若R0等于10则跳转到标签EQ10,若R0大于10(有符号)则跳转到标签GT10
  4. 写出指令,实现64位减法:将64位数(R1:R0)减去(R3:R2),结果存入(R5:R4)。

三、分析题(写出指令执行结果,假设初始寄存器值)

已知:R0=0xFFFFFFF0,R1=0x00000020,执行以下指令,写出R2/R3的值和C标志位状态:

  1. ADDS R2, R0, R1 2. ADC R3, #0, #0

算术运算指令习题答案+解题思路

一、选择题

  1. B(ADDS算低32位,产生进位C;ADC算高32位+进位,实现64位加法);
  2. C(CMP=SUBS省略Rd,仅执行Rn-Operand2并更新标志,不保存结果);
  3. B(Thumb-2宽立即数ADD的imm12是12位,范围0~4095);
  4. B(减法中C=0表示有借位,C=1表示无借位,与加法相反)。

二、编程题

  1. R2×8=R2 LSL#3,加{S}更新标志:
    ADDS R0, R1, R2, LSL #3
  2. 64位加法:低32位ADDS,高32位ADC:
    ADDS R6, R2, R4
    ADC R7, R3, R5
  3. CMP比较+条件分支指令:
    CMP R0, #10
    BEQ EQ10
    BGT GT10
  4. 64位减法:低32位SUBS,高32位SBC:
    SUBS R4, R0, R2
    SBC R5, R1, R3

三、分析题

  1. ADDS R2, R0, R1:0xFFFFFFF0 + 0x00000020 = 0x100000010(32位寄存器只能存低32位)→ R2=0x00000010;加法结果超过32位,C=1(进位)。
  2. ADC R3, #0, #0:R3 = 0 + 0 + C = 0+0+1=R3=0x00000001,C保持1(无新运算)。
    最终结果:R2=0x00000010,R3=0x00000001,C=1。

(后续将继续讲解逻辑运算、移位、访存、分支控制指令,均附带详细规则+实操案例+高频习题,需要我继续更新这部分内容吗?)

posted @ 2026-03-14 00:15  weixinye  阅读(2)  评论(0)    收藏  举报