diff --git a/嵌入式系统/复习文档/ARM处理器架构.md b/嵌入式系统/复习文档/ARM处理器架构.md
new file mode 100644
index 0000000..2209e2a
--- /dev/null
+++ b/嵌入式系统/复习文档/ARM处理器架构.md
@@ -0,0 +1,201 @@
+---
+tags: [嵌入式系统, 复习, ARM架构]
+create time: 2026-06-10 11:11
+---
+
+# ARM处理器架构
+
+## 概述
+本文档深入讲解ARM处理器的架构设计,包括命名规则、存储体系结构、流水线、寄存器组织、CPSR位域、工作模式以及FIQ/IRQ中断机制。ARM架构是嵌入式系统考试的重点内容。
+
+## 正文
+
+### 1. ARM概述
+
+ARM(Advanced RISC Machines)是一系列**处理器核心**的名称,不是一家公司的名字。ARM公司采用**IP授权**模式——设计处理器核心,将设计方案授权给芯片厂商(如高通、三星、ST)进行制造。
+
+ARM的核心特点:
+- **RISC架构**(精简指令集计算机):指令数量少,指令长度固定,执行效率高
+- **低功耗**:适合移动设备和嵌入式场景
+- **IP授权模式**:ARM自己不生产芯片
+
+### 2. ARM7TDMI命名规则
+
+以经典的ARM7TDMI为例,其后缀含义如下:
+
+| 后缀 | 全称 | 含义 |
+|------|------|------|
+| T | Thumb | 支持Thumb指令集(16位) |
+| D | Debug | 支持JTAG调试 |
+| M | Multiplier | 增强型乘法器 |
+| I | ICE | 支持嵌入式ICE(In-Circuit Emulator) |
+
+### 3. 冯·诺依曼 vs 哈佛架构
+
+这是嵌入式系统的经典考点:
+
+**冯·诺依曼架构**(ARM7采用):
+- 指令和数据**共享**同一条总线和同一存储空间
+- 不能同时取指令和读写数据
+- 结构简单,成本低
+
+**哈佛架构**(ARM9及以上采用):
+- 指令和数据使用**独立的**总线和存储空间
+- 可以同时取指令和读写数据
+- 性能更高,但结构更复杂
+
+> [!question] ARM7为什么选择冯·诺依曼架构?
+> ARM7面向低成本嵌入式应用,冯·诺依曼架构只需一组总线,可以减少芯片面积和引脚数量,降低功耗和成本。对于ARM7的应用场景,性能已经足够。
+
+### 4. ARM7三级流水线
+
+ARM7处理器使用三级流水线:
+
+| 阶段 | 名称 | 操作 |
+|------|------|------|
+| 1 | Fetch(取指) | 从存储器取出指令 |
+| 2 | Decode(译码) | 解析指令含义,读取寄存器 |
+| 3 | Execute(执行) | 执行运算,写回结果 |
+
+在理想情况下,三级流水线使得每个时钟周期都能完成一条指令(吞吐率为1 CPI)。但当发生分支跳转时,流水线需要清空并重新填充,导致性能损失。
+
+> [!tip] 流水线级数与PC值的关系
+> 在ARM7三级流水线中,当前执行的指令地址是PC-8(因为PC已经预取了两条指令之后的内容)。这个细节在调试时很重要。
+
+### 5. 寄存器组织
+
+ARM7共有**37个**32位寄存器,但在任意时刻只能访问其中一部分:
+
+- **User/SYS模式**:可访问**17个**(R0-R15 + CPSR)
+- **其他特权模式**:可访问各自的SPSR,以及部分私有寄存器
+
+#### 特殊功能寄存器
+
+| 寄存器 | 名称 | 功能 |
+|--------|------|------|
+| R13 | SP(Stack Pointer) | 栈指针,指向当前栈顶 |
+| R14 | LR(Link Register) | 链接寄存器,保存子程序返回地址 |
+| R15 | PC(Program Counter) | 程序计数器,指向下一条要取的指令 |
+| R12 | IP(Intra-Procedure-call) | 过程调用中间暂存寄存器 |
+
+> [!question] 为什么每个异常模式都有自己独立的R13(SP)?
+> 因为每个模式有自己的运行栈。如果所有模式共享一个SP,当中断发生时可能破坏正在使用的栈数据,导致系统崩溃。
+
+### 6. CPSR位域详解
+
+**CPSR**(Current Program Status Register,当前程序状态寄存器)是ARM中最关键的寄存器之一:
+
+```mermaid
+graph LR
+ subgraph CPSR["CPSR Bit Fields"]
+ direction LR
+ N["N[31]"] --> Z["Z[30]"] --> C["C[29]"] --> V["V[28]"]
+ V --> D["D[27]"] --> I["I[7]"] --> F["F[6]"] --> T["T[5]"]
+ T --> M["M[4:0]"]
+ end
+
+ style N fill:#ef9a9a
+ style Z fill:#ffcc80
+ style C fill:#fff176
+ style V fill:#a5d6a7
+ style I fill:#90caf9
+ style F fill:#90caf9
+ style T fill:#ce93d8
+ style M fill:#f48fb1
+```
+
+**条件标志位(N, Z, C, V)**:
+
+| 标志位 | 位号 | 含义 |
+|--------|------|------|
+| N | [31] | **负数**标志:运算结果最高位为1时置位 |
+| Z | [30] | **零**标志:运算结果为0时置位 |
+| C | [29] | **进位**标志:加法产生进位或减法无借位时置位 |
+| V | [28] | **溢出**标志:有符号运算溢出时置位 |
+
+**控制位**:
+
+| 标志位 | 位号 | 含义 |
+|--------|------|------|
+| I | [7] | IRQ禁止:置1时禁止IRQ中断 |
+| F | [6] | FIQ禁止:置1时禁止FIQ中断 |
+| T | [5] | Thumb状态:置1表示Thumb状态,置0表示ARM状态 |
+| M[4:0] | [4:0] | 处理器模式选择位 |
+
+> [!question] 如果CPSR的N=1、Z=0,这意味着什么?
+> N=1表示上一次运算结果为负数,Z=0表示结果不为零。如果此时用BMI(Branch Minus)指令,分支将被执行,因为BMI条件是N=1。
+
+### 7. SPSR
+
+**SPSR**(Saved Program Status Register)保存的是进入异常模式**之前**的CPSR值。
+
+当异常发生时,硬件自动将当前CPSR保存到对应异常模式的SPSR中。异常返回时,通过 `MOVS PC, LR` 指令将SPSR恢复回CPSR,从而恢复之前的状态。
+
+> [!warning] User模式没有SPSR
+> User模式不是异常模式,所以没有SPSR。如果需要保存User模式的状态,必须通过软件方式实现。
+
+### 8. 七种工作模式
+
+ARM处理器有7种工作模式:
+
+```mermaid
+graph TD
+ subgraph nonPriv["Non-Privileged"]
+ USR["USR - User Mode"]
+ end
+
+ subgraph priv["Privileged Modes"]
+ SYS["SYS - System Mode"]
+ SVC["SVC - Supervisor Mode"]
+ ABT["ABT - Abort Mode"]
+ UND["UND - Undefined Mode"]
+ IRQ["IRQ - IRQ Mode"]
+ FIQ["FIQ - FIQ Mode"]
+ end
+
+ SYS -.-> |"Same registers as USR"| USR
+ SVC --> |"Reset enters here"| SVC
+
+ style USR fill:#bbdefb
+ style SYS fill:#c8e6c9
+ style SVC fill:#ffcc80
+ style ABT fill:#ffab91
+ style UND fill:#ef9a9a
+ style IRQ fill:#ce93d8
+ style FIQ fill:#f48fb1
+```
+
+| 模式 | 编码 | 说明 | 进入方式 |
+|------|------|------|----------|
+| USR | 10000 | 用户模式,非特权 | 正常程序执行 |
+| SYS | 11111 | 系统模式,特权 | 与USR共享寄存器 |
+| SVC | 10011 | 管理模式 | **复位**、SWI |
+| ABT | 10111 | 中止模式 | 存储器访问异常 |
+| UND | 11011 | 未定义模式 | 未定义指令异常 |
+| IRQ | 10010 | 中断模式 | IRQ中断 |
+| FIQ | 10001 | 快速中断模式 | FIQ中断 |
+
+几个关键点:
+- **复位后进入SVC模式**,这是系统上电后的初始状态
+- **USR不是异常模式**,因此没有SPSR
+- **SYS模式**与USR共享寄存器,但具有特权权限
+
+### 9. FIQ vs IRQ
+
+| 比较维度 | FIQ | IRQ |
+|----------|-----|-----|
+| 优先级 | **更高** | 较低 |
+| 私有寄存器 | R8-R14(7个) | R13-R14(2个) |
+| 向量表位置 | 0x0000001C(末尾) | 0x00000018 |
+| 响应速度 | 更快(寄存器保留多,切换少) | 较慢 |
+| 嵌套 | 支持 | 支持 |
+
+FIQ更快的原因:
+1. 有更多的**私有寄存器**(R8-R14),中断处理时不需要保存/恢复通用寄存器
+2. 向量表位于地址空间末尾,可以直接放置ISR代码,**无需跳转**
+
+> [!question] 为什么FIQ的向量表放在0x0000001C(最后),而不是和其他异常一样在前面?
+> 把FIQ的处理程序直接放在向量表位置0x0000001C开始的地方,可以省去一次跳转指令。因为从0x0000001C到中断向量表结束还有空间,足够放几条关键指令。
+
+## 关联笔记
+- [[嵌入式系统/试题册/index|试题册索引]]
diff --git a/嵌入式系统/复习文档/ARM异常与中断机制.md b/嵌入式系统/复习文档/ARM异常与中断机制.md
new file mode 100644
index 0000000..cc8c206
--- /dev/null
+++ b/嵌入式系统/复习文档/ARM异常与中断机制.md
@@ -0,0 +1,235 @@
+---
+tags: [嵌入式系统, 复习, ARM异常]
+create time: 2026-06-10 11:11
+---
+
+# ARM异常与中断机制
+
+## 概述
+本文档详细讲解ARM处理器的异常与中断机制,包括7种异常类型、异常向量表、异常响应流程、FIQ/IRQ中断处理以及中断嵌套。这是理解嵌入式系统实时响应能力的关键。
+
+## 正文
+
+### 1. 什么是异常
+
+**异常(Exception)** 是指处理器在执行正常程序过程中,遇到的需要特殊处理的事件。异常是同步事件,由当前执行的指令触发。
+
+**中断(Interrupt)** 是一种特殊的异常,属于异步事件——由外部硬件信号触发,与当前执行的指令无关。
+
+> [!tip] 异常与中断的关系
+> 中断是异常的子集。所有中断都是异常,但不是所有异常都是中断。IRQ和FIQ是中断,而Reset、SWI、Data Abort等是其他类型的异常。
+
+### 2. 七种异常类型
+
+ARM7定义了7种异常类型,每种异常对应一种处理器模式:
+
+| 异常类型 | 触发原因 | 进入模式 | 优先级 |
+|----------|----------|----------|--------|
+| Reset | 复位信号 | SVC | 最高(1) |
+| Undefined Instruction | 无法识别的指令 | UND | 最高(2) |
+| SWI(软件中断) | SWI指令执行 | SVC | 最高(3) |
+| Prefetch Abort | 指令预取失败 | ABT | 最高(4) |
+| Data Abort | 数据访问失败 | ABT | 最高(5) |
+| IRQ | 外部IRQ中断请求 | IRQ | 较低(6) |
+| FIQ | 外部FIQ中断请求 | FIQ | 最低(7) |
+
+> [!question] 为什么Reset的优先级最高?
+> Reset是最高优先级异常,因为它代表系统需要从头开始。无论处理器当前在做什么,复位信号都必须立即响应,将系统拉回到初始状态。
+
+### 3. 异常向量表
+
+异常向量表是位于地址 **0x00000000** 的一张跳转表,每种异常对应一个固定的偏移地址:
+
+```mermaid
+graph TD
+ subgraph vectorTable["Exception Vector Table"]
+ V0["0x00000000: Reset"] --> V4["0x00000004: Undefined Instruction"]
+ V4 --> V8["0x00000008: SWI"]
+ V8 --> VC["0x0000000C: Prefetch Abort"]
+ VC --> V10["0x00000010: Data Abort"]
+ V10 --> V14["0x00000014: Reserved"]
+ V14 --> V18["0x00000018: IRQ"]
+ V18 --> V1C["0x0000001C: FIQ"]
+ end
+
+ style V0 fill:#ef9a9a
+ style V4 fill:#ffcc80
+ style V8 fill:#fff176
+ style VC fill:#a5d6a7
+ style V10 fill:#90caf9
+ style V14 fill:#e0e0e0
+ style V18 fill:#ce93d8
+ style V1C fill:#f48fb1
+```
+
+每个向量表项只占**4个字节**(一条ARM指令的大小),通常放置一条跳转指令(B或LDR PC)跳转到对应的异常处理程序。
+
+> [!warning] 0x00000014是保留位置
+> 0x00000014是Reserved,没有定义任何异常。这是因为每种异常间隔4个字节,而从Data Abort到IRQ之间需要一个间隔。
+
+> [!question] 为什么FIQ的向量地址是0x0000001C,排在最后?
+> 把FIQ放在向量表末尾有一个巧妙的好处:FIQ的处理程序可以直接从0x0000001C开始写,而不需要一条跳转指令。因为从0x0000001C往后到向量表结束还有空间,足以放置几条关键指令,从而节省了一个跳转周期。
+
+### 4. 异常响应流程
+
+当异常发生时,ARM处理器自动执行以下步骤:
+
+```mermaid
+flowchart TD
+ A["Exception Occurs"] --> B["Step1: Save CPSR to SPSR of target mode"]
+ B --> C["Step2: Set CPSR mode bits to target mode"]
+ C --> D["Step3: Set CPSR T bit to 0 ARM state"]
+ D --> E["Step4: Set CPSR I/F bits disable interrupts"]
+ E --> F["Step5: Save return address to LR of target mode"]
+ F --> G["Step6: Set PC to vector address"]
+ G --> H["Execute exception handler"]
+
+ style A fill:#ef9a9a
+ style H fill:#a5d6a7
+```
+
+具体来说:
+
+**Step 1:保存CPSR**
+- 将当前CPSR的值复制到**目标异常模式的SPSR**
+- 例如:IRQ发生时,CPSR → SPSR_irq
+
+**Step 2:切换处理器模式**
+- 修改CPSR的M[4:0]位,切换到异常对应的模式
+
+**Step 3:切换到ARM状态**
+- 清除CPSR的T位(T=0),确保在ARM状态下执行异常处理程序
+- 这意味着即使当前在Thumb状态,异常处理也使用ARM指令
+
+**Step 4:禁止中断**
+- 根据异常类型,设置I位或F位来禁止中断
+- IRQ异常设置I位(禁止IRQ),FIQ异常设置I和F位(禁止所有中断)
+
+**Step 5:保存返回地址**
+- 将程序计数器的值保存到**目标模式的LR**
+- 不同异常的返回地址偏移不同(见下表)
+
+**Step 6:跳转到向量表**
+- 将PC设置为对应异常的向量地址
+
+### 5. 返回地址的偏移
+
+每种异常保存到LR中的返回地址有特定的偏移:
+
+| 异常类型 | LR保存的值 | 说明 |
+|----------|------------|------|
+| Reset | 未定义 | 无需返回 |
+| Undefined | PC + 4 | 指向未定义指令的下一条 |
+| SWI | PC + 4 | 指向SWI指令的下一条 |
+| Prefetch Abort | PC + 4 | 指向预取失败指令的下一条 |
+| Data Abort | PC + 8 | 指向数据访问失败指令的下一条 |
+| IRQ | PC + 4 | 指向被中断指令的下一条 |
+| FIQ | PC + 4 | 指向被中断指令的下一条 |
+
+> [!question] 为什么Data Abort的偏移是+8而其他是+4?
+> 因为ARM7三级流水线中,当Data Abort被检测到时,流水线已经多预取了指令。Data Abort在执行阶段才被发现,此时PC已经前进了8个字节(两条指令之后)。
+
+### 6. 异常返回
+
+异常处理完成后,需要返回到被中断的程序。返回方式取决于异常类型:
+
+**从IRQ/FIQ返回**:
+```arm
+SUBS PC, LR, #4 ; LR_irq/fiq - 4 = 被中断指令的下一条地址
+```
+
+**从SWI/Undefined返回**:
+```arm
+MOVS PC, LR ; LR_svc/und 直接就是返回地址
+```
+
+**从Data Abort返回**:
+```arm
+SUBS PC, LR, #8 ; LR_abt - 8 = 需要重新执行那条失败的指令
+```
+
+> [!warning] 关键点:MOVS和SUBS中的"S"后缀
+> 返回指令必须使用带S后缀的版本(MOVS/SUBS),因为这会自动将SPSR的值恢复到CPSR。如果用MOV而不是MOVS,SPSR不会被恢复,处理器状态将不正确。
+
+### 7. 中断嵌套
+
+ARM7的中断**支持嵌套**。所谓嵌套,是指在一个中断处理过程中,更高优先级的中断可以打断当前处理。
+
+```mermaid
+sequenceDiagram
+ participant Main as Main Program
+ participant IRQ as IRQ Handler
+ participant FIQ as FIQ Handler
+
+ Main->>IRQ: IRQ interrupt occurs
+ Note over IRQ: CPSR saved, IRQ enabled
+ IRQ->>FIQ: FIQ interrupt occurs
+ Note over FIQ: CPSR saved, all IRQ disabled
+ FIQ-->>IRQ: Return from FIQ
+ IRQ-->>Main: Return from IRQ
+```
+
+实现中断嵌套的关键:
+1. 进入中断处理程序后,需要**手动重新使能IRQ**(清除CPSR的I位)
+2. 保存必要的寄存器到栈上
+3. 使用STMFD/LDMFD来管理栈帧
+
+```arm
+; IRQ中断处理程序模板
+IRQ_Handler:
+ SUB LR, LR, #4 ; 修正返回地址
+ STMFD SP!, {LR} ; 保存返回地址
+ MRS R14, SPSR ; 保存SPSR
+ STMFD SP!, {R14} ; 将SPSR压栈
+ STMFD SP!, {R0-R3, R12} ; 保存可能被破坏的寄存器
+ MSR CPSR_c, #0x13 ; 切换到SVC模式,使能IRQ
+ STMFD SP!, {LR} ; 保存SVC模式的LR
+
+ ; ... 在SVC模式下处理中断 ...
+
+ LDMFD SP!, {LR} ; 恢复SVC的LR
+ MSR CPSR_c, #0x92 ; 切回IRQ模式,禁止IRQ
+ LDMFD SP!, {R0-R3, R12} ; 恢复寄存器
+ LDMFD SP!, {R14} ; 恢复SPSR到R14
+ MSR SPSR_cxsf, R14 ; 写回SPSR
+ LDMFD SP!, {PC}^ ; 恢复PC,同时恢复CPSR
+```
+
+### 8. FIQ vs IRQ 对比总结
+
+```mermaid
+graph TD
+ subgraph comparison["FIQ vs IRQ Comparison"]
+ direction LR
+ subgraph fiqProps["FIQ Properties"]
+ FP1["Higher priority"]
+ FP2["Private R8-R14"]
+ FP3["Vector at 0x1C"]
+ FP4["Fastest response"]
+ end
+ subgraph irqProps["IRQ Properties"]
+ IP1["Lower priority"]
+ IP2["Private R13-R14 only"]
+ IP3["Vector at 0x18"]
+ IP4["Needs register save"]
+ end
+ end
+
+ style FP1 fill:#f48fb1
+ style IP1 fill:#ce93d8
+```
+
+| 特性 | FIQ | IRQ |
+|------|-----|-----|
+| 优先级 | 高 | 低 |
+| 私有寄存器 | R8-R14(7个) | R13-R14(2个) |
+| 向量地址 | 0x0000001C | 0x00000018 |
+| 响应速度 | 快(无需保存R8-R12) | 慢(需要保存R0-R12) |
+| 嵌套 | 支持 | 支持 |
+| 典型用途 | 高速数据传输(DMA) | 一般外部设备中断 |
+
+> [!question] 如果系统中只有一个中断源,应该选择FIQ还是IRQ?
+> 如果只有一个中断源且对响应速度有要求,建议使用FIQ。因为FIQ有更多私有寄存器,中断处理程序不需要保存/恢复R8-R12,减少了压栈/出栈的时间开销。
+
+## 关联笔记
+- [[嵌入式系统/试题册/index|试题册索引]]
diff --git a/嵌入式系统/复习文档/ARM指令集与汇编.md b/嵌入式系统/复习文档/ARM指令集与汇编.md
new file mode 100644
index 0000000..5bf9e3c
--- /dev/null
+++ b/嵌入式系统/复习文档/ARM指令集与汇编.md
@@ -0,0 +1,310 @@
+---
+tags: [嵌入式系统, 复习, ARM指令集]
+create time: 2026-06-10 11:11
+---
+
+# ARM指令集与汇编
+
+## 概述
+本文档详细讲解ARM指令集体系,包括ARM/Thumb指令集对比、指令格式、核心指令详解、条件码、寻址方式以及汇编程序设计。这是嵌入式系统课程中需要动手实践的重点部分。
+
+## 正文
+
+### 1. ARM指令集 vs Thumb指令集
+
+| 比较维度 | ARM指令集 | Thumb指令集 |
+|----------|-----------|-------------|
+| 指令宽度 | **32位** | **16位** |
+| 功能 | 完整功能 | ARM的子集 |
+| 代码密度 | 低(占用空间大) | 高(占用空间小) |
+| 性能 | 高 | 略低 |
+| 状态标志 | CPSR.T = 0 | CPSR.T = 1 |
+
+> [!warning] Thumb状态不能执行ARM指令
+> 在Thumb状态下,处理器只能执行16位的Thumb指令。如果需要执行32位ARM指令,必须先切换到ARM状态(通过BX指令)。两种状态不能在同一时刻混合执行。
+
+### 2. 指令格式
+
+ARM指令的基本格式为:
+
+```
+opcode{condition}{S} Rd, operand1, operand2
+```
+
+| 字段 | 说明 |
+|------|------|
+| opcode | 操作码,如MOV, ADD, LDR |
+| {condition} | 条件码,如EQ, NE, GT(可选) |
+| {S} | 是否影响CPSR标志位(可选) |
+| Rd | 目标寄存器 |
+| operand1 | 第一操作数(通常是寄存器) |
+| operand2 | 第二操作数(灵活,可带移位) |
+
+```mermaid
+graph LR
+ subgraph format["Instruction Format"]
+ direction LR
+ OP["opcode"] --> CON["condition"] --> S["S flag"] --> RD["Rd"] --> OP1["operand1"] --> OP2["operand2"]
+ end
+
+ style OP fill:#4fc3f7
+ style CON fill:#81d4fa
+ style S fill:#b3e5fc
+ style RD fill:#ffcc80
+ style OP1 fill:#ffab91
+ style OP2 fill:#a5d6a7
+```
+
+### 3. 桶形移位器(Barrel Shifter)
+
+ARM指令的一个强大特性:**第二操作数可以在送入ALU之前先进行移位操作**。这意味着一条指令就能完成"移位+运算",无需额外的移位指令。
+
+移位类型:
+
+| 移位操作 | 全称 | 说明 |
+|----------|------|------|
+| LSL | Logical Shift Left | 逻辑左移,低位补0 |
+| LSR | Logical Shift Right | 逻辑右移,高位补0 |
+| ASR | Arithmetic Shift Right | 算术右移,高位补符号位 |
+| ROR | Rotate Right | 循环右移 |
+
+```arm
+; 示例:利用桶形移位器
+ADD R0, R1, R1, LSL #2 ; R0 = R1 + R1 * 4 = R1 * 5
+SUB R2, R3, R3, LSR #1 ; R2 = R3 - R3/2 = R3/2
+MOV R4, R5, ROR #8 ; R4 = R5循环右移8位
+```
+
+> [!tip] 桶形移位器的价值
+> 在没有桶形移位器的架构中,`R1 * 5` 需要两条指令:先LSL #2再ADD。ARM用一条指令就完成了,这体现了RISC架构中"简单指令的巧妙组合"的设计哲学。
+
+### 4. 核心指令详解
+
+#### 4.1 数据传送指令 MOV
+
+```arm
+MOV R0, #10 ; R0 = 10(立即数传送)
+MOV R1, R0 ; R1 = R0(寄存器传送)
+MOV R2, R0, LSL #3 ; R2 = R0 << 3(带移位传送)
+```
+
+**MOV只能在寄存器之间传送数据,不能访问内存!** 这是与LDR的关键区别。
+
+#### 4.2 加载/存储指令 LDR/STR
+
+```arm
+LDR R0, [R1] ; 从R1指向的内存地址加载数据到R0
+STR R0, [R1] ; 将R0的值存储到R1指向的内存地址
+LDR R0, [R1, #4] ; 从R1+4地址加载(基址+偏移)
+STR R0, [R1], #4 ; 先存储,再更新R1 = R1 + 4(后索引)
+LDR R0, [R1, #4]! ; 先更新R1 = R1 + 4,再加载(前索引)
+```
+
+> [!question] MOV R0, #0xFF 和 LDR R0, =0x12345678 有什么区别?
+> `MOV R0, #0xFF` 是真正ARM指令,0xFF是合法的8位立即数(通过循环右移编码)。
+> `LDR R0, =0x12345678` 是**伪指令**,汇编器会将0x12345678放入文字池(literal pool),然后用一条LDR从该地址加载。因为0x12345678无法编码为8位立即数。
+
+#### 4.3 算术运算指令
+
+```arm
+ADD R0, R1, R2 ; R0 = R1 + R2
+ADD R0, R1, #5 ; R0 = R1 + 5
+ADDS R0, R1, R2 ; R0 = R1 + R2,并更新CPSR标志位
+SUB R0, R1, R2 ; R0 = R1 - R2
+SUBS R0, R1, #1 ; R0 = R1 - 1,更新标志位
+MUL R0, R1, R2 ; R0 = R1 * R2
+```
+
+注意带`S`后缀的指令会更新CPSR的N、Z、C、V标志位。
+
+#### 4.4 比较指令 CMP
+
+```arm
+CMP R0, R1 ; 比较R0和R1(计算R0-R1,但不保存结果)
+BEQ label ; 如果相等(Z=1),跳转到label
+BNE label ; 如果不相等(Z=0),跳转到label
+```
+
+CMP本质上是一条**不保存结果的减法指令**,只设置标志位。
+
+#### 4.5 分支指令 B / BL
+
+```arm
+B label ; 无条件跳转到label
+BL function ; 跳转到function,同时将返回地址保存到LR
+```
+
+- **B**:简单跳转,用于循环、条件分支
+- **BL**:带链接的跳转,用于**函数调用**(LR自动保存返回地址)
+
+#### 4.6 软中断指令 SWI
+
+```arm
+SWI #0x123456 ; 触发软中断,进入SVC模式
+```
+
+SWI用于**从用户模式请求操作系统服务**(系统调用)。执行SWI后:
+1. 进入SVC模式
+2. CPSR保存到SPSR_svc
+3. 返回地址保存到LR_svc
+4. PC跳转到向量地址0x00000008
+
+#### 4.7 批量加载/存储 STMFD / LDMFD
+
+```arm
+STMFD SP!, {R0-R3, LR} ; 将R0-R3和LR入栈(满递减栈)
+LDMFD SP!, {R0-R3, PC} ; 从栈中恢复R0-R3,并将PC出栈实现返回
+```
+
+这两个指令常用于**函数入口保存现场**和**函数出口恢复现场**。FD表示Full Descending(满递减栈),是ARM的默认栈类型。
+
+#### 4.8 状态寄存器读写 MRS / MSR
+
+```arm
+MRS R0, CPSR ; 将CPSR读入R0
+MSR CPSR_c, R0 ; 将R0写入CPSR的控制位域
+MSR CPSR_f, R0 ; 将R0写入CPSR的标志位域
+```
+
+MRS/MSR用于在**特权模式下修改CPSR**,例如开关中断:
+
+```arm
+; 关中断
+MRS R0, CPSR
+ORR R0, R0, #0x80 ; I位(bit7)置1
+MSR CPSR_c, R0
+
+; 开中断
+MRS R0, R1
+BIC R0, R0, #0x80 ; I位(bit7)清0
+MSR CPSR_c, R0
+```
+
+#### 4.9 测试等价指令 TEQ
+
+```arm
+TEQ R0, R1 ; 按位异或(EOR),只设置标志位,不保存结果
+```
+
+TEQ用于测试两个值是否相等(或测试某些位),与CMP类似但使用异或运算。
+
+### 5. 条件码
+
+ARM支持15种条件码,基于CPSR的标志位进行判断:
+
+| 条件码 | 含义 | 标志位条件 |
+|--------|------|------------|
+| EQ | 相等 | Z=1 |
+| NE | 不相等 | Z=0 |
+| GT | 大于(有符号) | Z=0且N=V |
+| LT | 小于(有符号) | N!=V |
+| GE | 大于等于(有符号) | N=V |
+| LE | 小于等于(有符号) | Z=1或N!=V |
+| HI | 无符号大于 | C=1且Z=0 |
+| LS | 无符号小于等于 | C=0或Z=1 |
+| CS/HS | 无符号大于等于 | C=1 |
+| CC/LO | 无符号小于 | C=0 |
+| PL | 正数或零 | N=0 |
+| MI | 负数 | N=1 |
+| VS | 溢出 | V=1 |
+| VC | 无溢出 | V=0 |
+| AL | 无条件(默认) | 任意 |
+
+> [!question] CMP R0, #0 后接 BMI label,什么时候会跳转?
+> BMI是"负数"条件跳转。CMP R0, #0 实际上是R0 - 0,结果就是R0本身。如果R0 < 0(最高位为1),N标志位被置位,BMI条件成立,跳转到label。
+
+### 6. 寻址方式
+
+| 寻址方式 | 示例 | 说明 |
+|----------|------|------|
+| 立即数寻址 | `MOV R0, #10` | 操作数就在指令中 |
+| 寄存器寻址 | `ADD R0, R1, R2` | 操作数在寄存器中 |
+| 寄存器间接寻址 | `LDR R0, [R1]` | R1中存放的是内存地址 |
+| 基址+偏移寻址 | `LDR R0, [R1, #4]` | R1为基地址,4为偏移量 |
+| 基址+索引寻址 | `LDR R0, [R1, R2]` | R2的值作为索引偏移 |
+
+### 7. 立即数编码
+
+ARM指令是32位固定的,立即数编码只占用**12位**(4位旋转量 + 8位立即数值)。规则:
+
+```
+实际值 = 8位立即数 循环右移 (旋转量 * 2) 位
+```
+
+这意味着只有**特定的值**才能作为立即数。例如:
+- `#0xFF`:合法,8位全1,旋转0位
+- `#0x100`:合法,`#1`循环右移24位
+- `#0x12345678`:**不合法**,无法用8位循环右移表示
+
+> [!tip] 立即数合法性判断
+> 判断一个数是否是合法的ARM立即数:将它写成二进制,看是否能通过循环右移偶数位变成8位以内的数。
+
+### 8. 字对齐与大小端
+
+**数据宽度**:
+
+| 类型 | 位数 | 字节数 |
+|------|------|--------|
+| Word(字) | 32位 | 4字节 |
+| Halfword(半字) | 16位 | 2字节 |
+| Byte(字节) | 8位 | 1字节 |
+
+**对齐要求**:Word访问的地址必须是4的倍数(地址 mod 4 = 0),Halfword访问地址必须是2的倍数。
+
+**大小端**:
+- **Little-Endian(小端)**:低字节存低地址(ARM常用)
+- **Big-Endian(大端)**:高字节存低地址
+
+```arm
+; 假设内存地址0x1000存放值 0x12345678
+; 小端模式:
+; 0x1000: 0x78 (最低字节)
+; 0x1001: 0x56
+; 0x1002: 0x34
+; 0x1003: 0x12 (最高字节)
+
+; 大端模式:
+; 0x1000: 0x12 (最高字节)
+; 0x1001: 0x34
+; 0x1002: 0x56
+; 0x1003: 0x78 (最低字节)
+```
+
+### 9. 完整示例:C if-else 对应的ARM汇编
+
+以下是C语言if-else语句及其对应的ARM汇编实现:
+
+```c
+// C代码
+int max(int a, int b) {
+ if (a > b)
+ return a;
+ else
+ return b;
+}
+```
+
+```arm
+; ARM汇编实现
+max:
+ CMP R0, R1 ; 比较a和b(R0-R1,设置标志位)
+ MOVGT R0, R0 ; 如果a > b(GT条件成立),R0保持不变
+ MOVLE R0, R1 ; 如果a <= b(LE条件成立),R0 = b
+ BX LR ; 返回,LR中保存了调用者的返回地址
+```
+
+更高效的写法:
+
+```arm
+; 优化版本:只用两条核心指令
+max:
+ CMP R0, R1 ; 比较a和b
+ MOVLT R0, R1 ; 如果a < b,则R0 = b
+ BX LR ; 返回
+```
+
+> [!question] 为什么优化版本只判断了LT一种情况?
+> 因为如果a >= b,R0的值本来就是a,不需要任何操作。只有当a < b时才需要将b写入R0。这体现了"条件执行"的强大——ARM的每条指令都可以条件执行,避免了不必要的跳转。
+
+## 关联笔记
+- [[嵌入式系统/试题册/index|试题册索引]]
diff --git a/嵌入式系统/复习文档/Android应用开发基础.md b/嵌入式系统/复习文档/Android应用开发基础.md
new file mode 100644
index 0000000..8853c94
--- /dev/null
+++ b/嵌入式系统/复习文档/Android应用开发基础.md
@@ -0,0 +1,336 @@
+---
+tags: [嵌入式系统, 复习, Android开发]
+create time: 2026-06-10 11:11
+---
+
+# Android应用开发基础
+
+## 概述
+本文档覆盖Android应用开发的核心知识,包括分层架构、四大组件、Activity生命周期、数据存储、UI布局、权限管理和常用设计模式。这是嵌入式系统课程中移动终端开发部分的复习重点。
+
+## 正文
+
+### 1. Android分层架构
+
+Android系统采用分层架构设计,从底层到顶层分为四层:
+
+```mermaid
+graph TD
+ A["Applications"] --> B["Application Framework"]
+ B --> C["Libraries / Android Runtime"]
+ C --> D["Linux Kernel"]
+
+ style A fill:#4fc3f7
+ style B fill:#81d4fa
+ style C fill:#b3e5fc
+ style D fill:#ffcc80
+```
+
+| 层级 | 组成 | 说明 |
+|------|------|------|
+| **Applications** | 短信、电话、浏览器、第三方App | 用户直接使用的应用 |
+| **Application Framework** | Activity Manager, Content Provider, Resource Manager, Notification Manager | 提供构建应用的基础API |
+| **Libraries / Runtime** | SQLite, OpenGL, WebKit, Media Framework, Dalvik/ART | 系统库和运行时环境 |
+| **Linux Kernel** | 驱动、内存管理、进程管理、网络栈 | 底层硬件抽象和系统服务 |
+
+> [!tip] Dalvik vs ART
+> - **Dalvik**:Android 4.4之前使用,基于JIT(Just-In-Time)编译
+> - **ART**:Android 5.0开始替代Dalvik,使用AOT(Ahead-Of-Time)编译,运行更快但安装更慢
+
+### 2. 四大组件
+
+Android应用由四大核心组件构成:
+
+#### 2.1 Activity(活动)
+
+Activity代表一个**用户界面屏幕**,是用户与应用交互的主要入口。
+
+```java
+public class MainActivity extends AppCompatActivity {
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_main);
+ }
+}
+```
+
+#### 2.2 Service(服务)
+
+Service在**后台**运行,没有用户界面。适合执行长时间运行的操作(如音乐播放、文件下载)。
+
+两种启动方式:
+- **Started Service**:通过startService()启动,独立运行
+- **Bound Service**:通过bindService()绑定,提供客户端-服务器接口
+
+#### 2.3 ContentProvider(内容提供者)
+
+ContentProvider用于**跨应用数据共享**。它封装了数据访问接口,其他应用通过ContentResolver来查询和修改数据。
+
+```java
+// 在AndroidManifest.xml中注册
+
+```
+
+> [!question] 为什么需要ContentProvider而不是直接共享数据库?
+> ContentProvider提供了统一的数据访问接口和权限控制机制。直接共享数据库会暴露数据结构细节,且难以控制访问权限。
+
+#### 2.4 BroadcastReceiver(广播接收器)
+
+BroadcastReceiver用于接收和响应**系统或应用广播**,实现组件间的松耦合通信。
+
+配置方式有两种:
+
+**XML静态注册**:
+```xml
+
+
+
+
+
+```
+
+**代码动态注册**:
+```java
+IntentFilter filter = new IntentFilter("com.example.MY_ACTION");
+registerReceiver(new MyReceiver(), filter);
+```
+
+### 3. Activity生命周期
+
+Activity的生命周期是Android开发的基础知识点:
+
+```mermaid
+stateDiagram-v2
+ [*] --> Created
+ Created --> Started: onCreate -> onStart
+ Started --> Running: onResume
+ Running --> Paused: onPause
+ Paused --> Running: onResume
+ Paused --> Stopped: onStop
+ Stopped --> Started: onRestart -> onStart
+ Stopped --> Created: onDestroy
+ Running --> Stopped: onStop
+ Paused --> Created: onDestroy
+ Created --> [*]: onDestroy
+
+ note right of Created: Activity created
+ note right of Started: Visible but not focused
+ note right of Running: Foreground, interactive
+ note right of Paused: Partially obscured
+ note right of Stopped: Fully hidden
+```
+
+| 生命周期方法 | 调用时机 | 说明 |
+|-------------|----------|------|
+| onCreate() | Activity首次创建 | 初始化界面、绑定数据 |
+| onStart() | Activity变为可见 | 准备显示 |
+| onResume() | Activity获得焦点 | 可与用户交互 |
+| onPause() | Activity失去焦点 | 保存临时数据(秒级) |
+| onStop() | Activity完全不可见 | 释放资源 |
+| onDestroy() | Activity被销毁 | 最终清理 |
+| onRestart() | 从Stopped重新启动 | 不会直接到onCreate |
+
+> [!warning] onPause()中不要做耗时操作
+> onPause()执行完毕后,新的Activity才会启动。如果在onPause()中做网络请求或大量数据处理,会导致界面切换卡顿。耗时操作应该放到onStop()或异步任务中。
+
+### 4. Intent数据传递
+
+Intent是Android中组件间通信的核心机制,用于启动Activity、Service和发送广播。
+
+**传递数据的两种方式**:
+
+**Serializable**(Java标准序列化):
+```java
+// 发送端
+Intent intent = new Intent(this, TargetActivity.class);
+intent.putExtra("user", (Serializable) userObj);
+startActivity(intent);
+
+// 接收端
+User user = (User) getIntent().getSerializableExtra("user");
+```
+
+**Parcelable**(Android特有序列化,性能更好):
+```java
+// 发送端
+intent.putExtra("user", (Parcelable) userObj);
+
+// 接收端
+User user = getIntent().getParcelableExtra("user");
+```
+
+| 比较 | Serializable | Parcelable |
+|------|-------------|------------|
+| 性能 | 慢(使用反射) | 快(手动实现) |
+| 实现 | 简单(实现接口即可) | 复杂(需实现writeToParcel) |
+| 用途 | 临时存储、简单对象 | Activity间频繁传递 |
+| 开销 | 产生大量临时对象 | 内存开销小 |
+
+### 5. startActivityForResult
+
+当一个Activity需要从另一个Activity**获取返回数据**时,使用startActivityForResult:
+
+```java
+// 启动方
+Intent intent = new Intent(this, SecondActivity.class);
+startActivityForResult(intent, REQUEST_CODE);
+
+// 接收返回数据
+@Override
+protected void onActivityResult(int requestCode, int resultCode, Intent data) {
+ if (requestCode == REQUEST_CODE && resultCode == RESULT_OK) {
+ String result = data.getStringExtra("result");
+ // 处理返回数据
+ }
+}
+
+// 被启动方设置返回数据
+Intent resultIntent = new Intent();
+resultIntent.putExtra("result", "hello from second");
+setResult(RESULT_OK, resultIntent);
+finish();
+```
+
+### 6. SQLite数据类型
+
+Android内置SQLite数据库,支持以下5种数据类型:
+
+| 数据类型 | 说明 |
+|----------|------|
+| NULL | 空值 |
+| INTEGER | 整数 |
+| REAL | 浮点数 |
+| TEXT | 文本字符串 |
+| BLOB | 二进制大对象 |
+
+> [!warning] SQLite没有VARCHAR类型
+> SQLite使用动态类型系统,TEXT类型可以存储任意长度的字符串,不需要指定VARCHAR(n)。但创建表时写VARCHAR也是合法的(会被忽略长度约束)。
+
+### 7. UI布局
+
+Android支持多种布局方式:
+
+| 布局类型 | 特点 | 适用场景 |
+|----------|------|----------|
+| **LinearLayout** | 线性排列(水平/垂直) | 简单的行列排列 |
+| **RelativeLayout** | 相对定位 | 复杂的相对位置关系 |
+| **FrameLayout** | 层叠排列,后面的元素覆盖前面 | 重叠界面、帧动画 |
+
+**SimpleAdapter**用于为ListView等列表控件提供数据:
+
+```java
+// 数据源:List