跳转汇编指令解读
__asm volatile (
"cpsid i\n" // ① 关闭全局中断(PRIMASK=1)
"ldr r0, =0xE000ED08\n" // ② R0 = VTOR 寄存器的地址(0xE000ED08)
"str %1, [r0]\n" // ③ 将 appBinStartAddr 写入 VTOR(重映射向量表)
"ldr r0, [%1]\n" // ④ 从 appBinStartAddr 处读取第一个字(即初始 MSP 值)
"msr msp, r0\n" // ⑤ 设置主堆栈指针(MSP)为上述值
"dsb\n" // ⑥ 数据同步屏障(确保之前的写操作完成)
"isb\n" // ⑦ 指令同步屏障(刷新流水线,确保新 VTOR 生效)
"bx %0\n" // ⑧ 跳转到 appStartAddr(复位处理函数地址)
:
: "r"(appStartAddr), "r"(appBinStartAddr) // 输入操作数
: "r0", "memory" // 被修改的寄存器和内存
);
appBinStartAddr:编译好的hex文件的起始地址
appStartAddr:appBinStartAddr地址+4,一般是reset_handler函数存放的地址
cpsid i, 关闭全局中断
"ldr r0, =0xE000ED08\n" ,将SCB->VTOR寄存器的地址赋值给R0
"str %1, [r0]\n", 将appBinStartAddr的地址赋值给SCB->VTOR 重新映射中断向量表。
"ldr r0, [%1]\n": 读取栈顶的指针
"msr msp, r0\n":将栈顶指针的数据赋值给msp。
dsb isb:data synchronization barraier,instruction synchronization barraier,一个是用于所有的内存访问完成,阻塞式的。一个是用于取指令的动作访问完成,阻塞式的
"bx %0\n":bx appStartAddr,直接调准到reset_handler地址