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

STM32H753中C调用RAM汇编函数时gcc生成错误BLX指令致硬故障

为何调用RAM中的汇编函数时gcc生成了异常的BLX指令?

问题背景

使用arm-none-eabi-gcc编译STM32H753裸机软件,复位处理函数以C语言实现并存储在Flash中:

void reset_handler_c(void)
{
   asm_func();
}

汇编函数在.s文件中实现并存储在RAM中:

.global asm_func

asm_func:
  ldr sp,=xxx
  bl entry_point
  bx lr

编译选项为-mcpu=cortex-m7 -std=c99 -mfpu=fpv5-d16 -mfloat-abi=hard -mthumb -O1 ...,各选项含义:

  • -mcpu=cortex-m7:指定目标CPU为Cortex-M7
  • -std=c99:遵循C99编程语言标准
  • -mfpu=fpv5-d16:启用FPv5-D16双精度浮点单元
  • -mfloat-abi=hard:采用硬件浮点调用约定
  • -mthumb:生成Thumb指令集代码
  • -O1:开启一级编译优化

实际生成的汇编代码中使用了BLX指令,而Cortex-M7执行该指令时触发硬故障;但调用Flash中的C函数时,gcc会生成正确的BL指令。

原因分析

  1. 汇编函数未明确标记Thumb属性
    你的汇编代码仅通过.global asm_func声明了全局函数,但未添加.thumb_func或.code 16指令明确标记该函数属于Thumb指令集。gcc默认会将未明确指令集属性的汇编函数视为ARM指令集函数。

  2. Cortex-M内核的指令集限制
    STM32H753搭载的Cortex-M7是Thumb-only内核,仅支持Thumb/Thumb-2指令集,无法执行ARM指令。当gcc判定目标函数为ARM指令集时,会生成BLX指令(用于在ARM与Thumb状态间切换),但该指令尝试切换到ARM状态时,直接触发硬故障。

  3. 跨存储区域调用的叠加影响
    由于C函数位于Flash、汇编函数位于RAM,属于不同地址空间,gcc结合指令集属性的不确定性,进一步选择生成BLX而非BL指令。而调用同存储区域的C函数时,gcc能确认目标函数的Thumb属性,因此生成正确的BL指令。

解决方法

在汇编函数的全局声明后添加.thumb_func指令,明确标记其为Thumb指令集函数:

.global asm_func
.thumb_func

asm_func:
  ldr sp,=xxx
  bl entry_point
  bx lr

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.26 09:20:20