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

ARM C代码内嵌汇编跳转函数被优化无法执行如何解决

问题根源

  1. 编译器默认不会识别内嵌汇编的副作用:ARMCC在优化开启时,会自动删除没有可见副作用的函数调用。你的jump函数没有返回值、没有修改全局变量或入参,编译器看不到汇编块内的跳转逻辑,就判定这个函数调用没有任何作用,不仅把jump函数本身优化成了直接返回(BX lr),还直接删除了main里的jump()调用,甚至把后面没用的变量赋值逻辑也全部优化掉了。
  2. volatile修饰函数属于无效用法:C标准里volatile只能用于修饰数据对象,修饰函数返回值不会被编译器识别,自然起不到防止优化的作用。

解决方法

  • 给内嵌汇编添加__volatile限定:这是ARM系列编译器针对内嵌汇编的标准语法,显式告诉编译器该汇编块存在不可预测的副作用,不能被优化删除、也不能和其他指令重排。修改后的代码示例:
void jump(void)
{
  __asm __volatile
  {
    B 0x15000
  }
  // 可选:添加__builtin_unreachable()告知编译器汇编后的代码永远不会执行,消除冗余警告
  __builtin_unreachable();
}
  • 给函数添加专用属性:搭配__attribute__((noreturn, noinline))修饰jump函数,noreturn告诉编译器该函数不会返回,不需要处理调用后的返回逻辑;noinline防止编译器把函数内联到调用位置,适配需要单独调用的场景:
__attribute__((noreturn, noinline)) void jump(void)
{
  __asm __volatile
  {
    LDR PC, =0x15000
  }
  __builtin_unreachable();
}

补充说明:推荐用LDR PC, =0x15000代替B 0x15000,B指令的跳转范围有限(ARM模式下最大±32MB,Thumb模式更小),超出范围会编译报错,直接给PC寄存器赋值可以实现全32位地址空间跳转,兼容性更好。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.05 09:30:05