You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

STM32F103ZET6 Bootloader跳转异常及Thumb模式指令疑问

STM32F103 Bootloader跳转与Thumb模式指令问题

场景说明

我使用Keil5开发STM32F103ZET6的Bootloader,Bootloader存放于Flash基地址0x08000000,完成操作后需跳转到应用地址0x08004000。

Bootloader跳转代码

#define apdr 0x08004001
void (*app)(void);
app = ((void (*)(void))apdr);
app();

应用反汇编代码

RESET
__Vectors
    0x08004000:    20002400    .$.     DCD    536880128
    0x08004004:    08004145    EA..    DCD    134234437
    0x08004008:    08004151    QA..    DCD    134234449

Reset_Handler
    0x08004144:    f8dfd01c    ....    LDR      sp,[pc,#28] ; [0x8004164] = 0x20002400
    0x08004148:    4807        .H      LDR      r0,[pc,#28] ; [0x8004168] = 0x8004195
    0x0800414a:    4780        .G      BLX      r0
    0x0800414c:    4807        .H      LDR      r0,[pc,#28] ; [0x800416c] = 0x8004131
    0x0800414e:    4700        .G      BX       r0

问题1:任意奇数地址跳转仍能运行的原因

  1. Cortex-M3指令特性:BX/BLX跳转指令会自动忽略目标地址的最低位,仅用高31位作为实际跳转地址,最低位用来指定指令模式——1对应Thumb模式,0对应ARM模式。STM32F103是Cortex-M3内核,仅支持Thumb模式,所以最低位必须为1。
  2. 向量表的自动执行:当跳转到0x08004001这类奇数地址时,BX指令会截断地址为0x08004000(应用向量表起始地址),CPU会自动执行向量表流程:先加载栈顶指针(0x08004000处的值),再跳转到复位向量(0x08004004处的0x08004145,最低位1对应Thumb模式)。
  3. 中间地址的兼容性:对于0x0800414D这类复位handler范围内的奇数地址,BX指令会截断为0x0800414C,该地址是复位handler中的合法指令,CPU执行后会继续后续初始化流程,因此应用仍能正常运行。

问题2:Thumb模式下32位LDR指令的有效性

完全可以正常工作,原因如下:

  • Cortex-M3内核支持Thumb-2指令集,该指令集包含16位和32位混合指令,ldr sp, =__initial_sp属于Thumb-2伪指令,编译器会将其转换为合法的32位Thumb指令(比如你反汇编中看到的f8dfd01c,就是32位的LDR sp,[pc,#28]指令)。
  • 复位handler本身运行在Thumb模式下,Cortex-M3会自动识别并执行32位Thumb-2指令,无需额外配置,因此这条加载栈顶的指令可以正常完成初始化操作。

内容的提问来源于stack exchange,提问作者ugger B

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.16 00:17:08