1. 核心功能差异
B(Branch,单纯跳转)
- 只修改 PC,跳转到目标标号;
- 不保存返回地址到 LR (R14);
- 跳走后无法回到跳转指令下一条代码;
- 用途:死循环、分支跳转、永不返回的跳转(如中断复位、while (1))。
示例:
B loop ; 跳转到loop,一去不回
loop:
...
BL(Branch with Link,带链接跳转 = 函数调用)
- 跳转前自动执行:
LR = 当前B/BL下一条指令地址; - 再修改 PC 跳转到目标;
- 子程序末尾用
MOV PC, LR即可返回调用处; - 用途:调用子函数 / 子程序(C 语言函数调用底层就是 BL)。
示例完整调用:
BL delay_func ; 保存返回地址到LR,跳去delay_func
; 执行完delay_func后回到这一行继续运行
delay_func:
; 延时逻辑
MOV PC, LR ; 返回BL下一条指令
2. 硬件编码区分(bit24 L 位)
- B:指令 bit24 = 0,无链接;
- BL:指令 bit24 = 1,开启链接、写入 LR。
3. 寻址范围(两者完全一样)
ARM32 相对偏移 24 位有符号数,左移 2 位,跳转范围 ±32MB; 只能跳当前 32MB 内标号,超出要用 LDR PC,=addr 长跳转。
4. 对比表
| 指令 | 是否存返回地址到 LR | 能否返回 | 典型场景 |
|---|---|---|---|
| B | 否 | 不能 | 死循环、if‑else 分支、复位跳转 |
| BL | 是(自动保存) | 能 | 子程序 / 函数调用 |