2 커밋 b9d455edbb ... e6219d1882

작성자 SHA1 메시지 날짜
  OpenCode e6219d1882 ingest: ARM汇编基础 + 全库prettier格式化 2 주 전
  OpenCode b9d455edbb ingest: ARM汇编基础 + 全库prettier格式化 2 주 전
1개의 변경된 파일298개의 추가작업 그리고 1개의 파일을 삭제
  1. 298 1
      X-Knowledge-Base/raw/Joplin/Linux+C+C++技术体系梳理/3. 编译调试与驱动预留/9. ARM汇编基础.md

+ 298 - 1
X-Knowledge-Base/raw/Joplin/Linux+C+C++技术体系梳理/3. 编译调试与驱动预留/9. ARM汇编基础.md

@@ -340,7 +340,304 @@ Cortex-A7 有 16 个 32 位通用寄存器(R0-R15)和 2 个特殊状态寄
 
 ## 9.3 代码示例
 
-### 完整的 Cortex-A7 启动汇编框架
+> **在线运行**:以下所有示例均可直接粘贴到 [CPUlator ARM](https://cpulator.01xz.net/?sys=arm) 中运行。
+> 操作:打开网址 → 语言选 ARM → 粘贴代码 → 按 F5 编译加载 → F2 单步执行 → 观察寄存器变化。
+
+### 示例 1:数据传输指令(MOV / MRS / MSR)
+
+```asm
+@ 示例1:数据传输指令
+@ 在 CPUlator 中运行,观察 R0-R3 和 CPSR 的变化
+
+.global _start
+
+_start:
+    @ MOV:寄存器之间拷贝
+    mov r0, #0x10           @ R0 = 0x10
+    mov r1, r0              @ R1 = R0 = 0x10
+    mov r2, #0xff           @ R2 = 0xFF
+
+    @ MOV:加载小立即数
+    mov r3, #0x12           @ R3 = 0x12
+
+    @ MRS:读取 CPSR 到通用寄存器
+    mrs r0, cpsr            @ R0 = CPSR 的值
+
+    @ MSR:修改 CPSR 的中断禁止位
+    orr r0, r0, #0xc0       @ 设置 I=1, F=1(禁止 IRQ 和 FIQ)
+    msr cpsr, r0            @ 写回 CPSR
+
+    @ 死循环,程序停在这里
+hang:
+    b hang
+```
+
+**观察要点**:单步执行后,R0-R3 的值逐步变化,CPSR 在 MSR 前后发生变化。
+
+---
+
+### 示例 2:存储加载指令(LDR / STR)
+
+```asm
+@ 示例2:存储加载指令
+@ 在 CPUlator 中运行,观察寄存器和内存的变化
+
+.global _start
+
+_start:
+    @ 用 LDR 加载地址到寄存器
+    ldr r0, =0x1000         @ R0 = 0x1000(目标内存地址)
+
+    @ 用 STR 写入数据到内存
+    ldr r1, =0x12345678     @ R1 = 0x12345678
+    str r1, [r0]            @ 将 R1 写入地址 0x1000
+
+    @ 用 LDR 从内存读取数据
+    ldr r2, [r0]            @ R2 = 内存[0x1000] = 0x12345678
+
+    @ 按字节操作(LDRB / STRB)
+    ldr r3, =0x2000         @ R3 = 0x2000
+    mov r4, #0xAA           @ R4 = 0xAA
+    strb r4, [r3]           @ 将 0xAA 写入地址 0x2000(只写低 8 位)
+    ldrb r5, [r3]           @ R5 = 0xAA(只读低 8 位)
+
+    @ 按半字操作(LDRH / STRH)
+    ldr r6, =0x3000         @ R6 = 0x3000
+    ldr r7, =0xBBCC         @ R7 = 0xBBCC
+    strh r7, [r6]           @ 将 0xBBCC 写入地址 0x3000(只写低 16 位)
+    ldrh r8, [r6]           @ R8 = 0xBBCC
+
+    @ 死循环
+hang:
+    b hang
+```
+
+**观察要点**:切换到 Memory 窗口查看地址 0x1000、0x2000、0x3000 的内容变化。
+
+---
+
+### 示例 3:算术运算指令(ADD / SUB / MUL)
+
+```asm
+@ 示例3:算术运算指令
+@ 在 CPUlator 中运行,观察标志位(N, Z, C, V)的变化
+
+.global _start
+
+_start:
+    @ 加法
+    mov r0, #100            @ R0 = 100
+    mov r1, #200            @ R1 = 200
+    add r2, r0, r1          @ R2 = 100 + 200 = 300
+
+    @ 立即数加法
+    add r3, r2, #50         @ R3 = 300 + 50 = 350
+
+    @ 减法
+    sub r4, r1, r0          @ R4 = 200 - 100 = 100
+
+    @ 带借位减法(SBC)
+    mov r5, #0
+    subs r6, r5, #1         @ R6 = 0 - 1 = 0xFFFFFFFF,借位 C=0
+    sbc r7, r5, #0          @ R7 = 0 - 0 - !C = 0(因为借位了)
+
+    @ 乘法
+    mov r0, #7
+    mov r1, #6
+    mul r2, r0, r1          @ R2 = 7 * 6 = 42
+
+    @ 无符号除法
+    mov r0, #100
+    mov r1, #7
+    udiv r2, r0, r1         @ R2 = 100 / 7 = 14(商)
+
+    @ 有符号除法
+    mov r0, #-100
+    mov r1, #7
+    sdiv r2, r0, r1         @ R2 = -100 / 7 = -14
+
+    @ 死循环
+hang:
+    b hang
+```
+
+**观察要点**:执行 `subs` 后,CPSR 的 C 位(进位/借位)会变化。
+
+---
+
+### 示例 4:逻辑运算指令(AND / ORR / BIC / EOR)
+
+```asm
+@ 示例4:逻辑运算指令
+@ 在 CPUlator 中运行,常用于寄存器位操作
+
+.global _start
+
+_start:
+    @ AND:按位与(清除高位)
+    ldr r0, =0x1234FFFF     @ R0 = 0x1234FFFF
+    and r1, r0, #0x0000FF00 @ R1 = R0 & 0x0000FF00 = 0x0000FF00(只保留 bit8-15)
+
+    @ ORR:按位或(设置某些位)
+    mov r2, #0              @ R2 = 0
+    orr r2, r2, #0x80       @ R2 = 0x80(设置 bit7)
+    orr r2, r2, #0x01       @ R2 = 0x81(设置 bit0)
+
+    @ BIC:位清除(清除指定位)
+    ldr r3, =0xFFFFFFFF     @ R3 = 0xFFFFFFFF
+    bic r3, r3, #0x01       @ R3 = 0xFFFFFFFE(清除 bit0)
+    bic r3, r3, #0x02       @ R3 = 0xFFFFFFFC(清除 bit1)
+
+    @ EOR:按位异或(翻转某些位)
+    mov r4, #0xFF           @ R4 = 0xFF
+    eor r4, r4, #0x0F       @ R4 = 0xF0(翻转低 4 位)
+
+    @ 实际应用:读取-修改-写入 GPIO 寄存器
+    ldr r5, =0x1000         @ 假设 GPIO 寄存器地址
+    ldr r6, [r5]            @ 读取当前值
+    orr r6, r6, #0x01       @ 设置 bit0(点亮 LED)
+    str r6, [r5]            @ 写回
+
+    @ 死循环
+hang:
+    b hang
+```
+
+**观察要点**:观察每次逻辑运算后寄存器的二进制位变化。
+
+---
+
+### 示例 5:压栈出栈指令(PUSH / POP)
+
+```asm
+@ 示例5:压栈出栈指令
+@ 在 CPUlator 中运行,观察 SP 和栈内存的变化
+
+.global _start
+
+_start:
+    @ 设置栈指针(向下增长的满递减栈)
+    ldr sp, =0x4000         @ SP = 0x4000(栈顶)
+
+    @ 初始化寄存器
+    mov r0, #0x11           @ R0 = 0x11
+    mov r1, #0x22           @ R1 = 0x22
+    mov r2, #0x33           @ R2 = 0x33
+    mov r3, #0x44           @ R3 = 0x44
+
+    @ 压栈:保存 R0-R3
+    push {r0, r1, r2, r3}   @ SP 从 0x4000 变为 0x3FF0
+
+    @ 修改寄存器(模拟函数调用)
+    mov r0, #0xAA           @ R0 被修改
+    mov r1, #0xBB           @ R1 被修改
+
+    @ 出栈:恢复 R0-R3
+    pop {r0, r1, r2, r3}    @ SP 从 0x3FF0 变回 0x4000
+
+    @ R0-R3 应恢复为原始值 0x11, 0x22, 0x33, 0x44
+
+    @ STMFD / LDMFD 写法(等价)
+    stmfd sp!, {r0-r3}      @ 压栈
+    ldmfd sp!, {r0-r3}      @ 出栈
+
+    @ 死循环
+hang:
+    b hang
+```
+
+**观察要点**:
+
+1. 执行 `push` 后 SP 减小(0x4000 → 0x3FF0)
+2. Memory 窗口查看 0x3FF0-0x3FFC 可以看到压入的值
+3. 执行 `pop` 后 SP 恢复,R0-R3 被还原
+
+---
+
+### 示例 6:跳转与比较指令(B / CMP / 条件跳转)
+
+```asm
+@ 示例6:跳转与比较指令
+@ 在 CPUlator 中运行,观察 PC 和条件标志的变化
+
+.global _start
+
+_start:
+    @ 计算 1+2+3+...+10 的累加和
+    mov r0, #0              @ R0 = sum = 0
+    mov r1, #1              @ R1 = i = 1
+
+loop:
+    add r0, r0, r1          @ sum = sum + i
+    add r1, r1, #1          @ i = i + 1
+    cmp r1, #11             @ 比较 i 和 11
+    blt loop                @ 如果 i < 11,跳转到 loop
+
+    @ 结束后 R0 = 55(1+2+3+...+10)
+
+    @ BL 跳转示例:调用子程序
+    mov r0, #10             @ 参数
+    bl  double_value        @ 调用,返回后 R0 = 20
+    @ R0 = 20
+
+    @ 死循环
+hang:
+    b hang
+
+@ 子程序:将 R0 的值翻倍
+double_value:
+    lsl r0, r0, #1          @ R0 = R0 << 1 = R0 * 2
+    bx lr                   @ 返回
+```
+
+**观察要点**:
+
+1. 单步执行循环,观察 R0(累加和)和 R1(计数器)的变化
+2. `cmp` 后 CPSR 的 Z 位会变化
+3. `blt` 条件跳转依赖 CPSR 的 N 位
+
+---
+
+### 示例 7:位移操作(LSL / LSR / ASR)
+
+```asm
+@ 示例7:位移操作
+@ 在 CPUlator 中运行,位移是乘除 2 的高效替代
+
+.global _start
+
+_start:
+    @ 逻辑左移(LSL):相当于乘以 2^n
+    mov r0, #1              @ R0 = 1
+    lsl r1, r0, #3          @ R1 = 1 << 3 = 8
+    lsl r2, r0, #4          @ R2 = 1 << 4 = 16
+
+    @ 逻辑右移(LSR):相当于无符号除以 2^n
+    ldr r3, =0x80           @ R3 = 128
+    lsr r4, r3, #3          @ R4 = 128 >> 3 = 16
+
+    @ 算术右移(ASR):有符号除以 2^n(保留符号位)
+    mov r5, #-128           @ R5 = -128(0xFFFFFF80)
+    asr r6, r5, #3          @ R6 = -128 >> 3 = -16(0xFFFFFFF0)
+
+    @ 循环左移(LSL)实现乘法
+    mov r0, #5
+    lsl r0, r0, #2          @ R0 = 5 * 4 = 20(左移 2 位 = 乘 4)
+
+    @ 循环右移(LSR)实现除法
+    mov r1, #100
+    lsr r1, r1, #2          @ R1 = 100 / 4 = 25(右移 2 位 = 除 4)
+
+    @ 死循环
+hang:
+    b hang
+```
+
+---
+
+### 示例 8:综合实战——Cortex-A7 启动汇编框架
+
+> 以下代码是实际工程中的启动代码片段,需要交叉编译器和链接脚本,无法在 CPUlator 中直接运行。用于理解完整启动流程。
 
 ```asm
 @ Cortex-A7 启动汇编示例(适用于 I.MX6ULL)