STM32H753中C调用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指令。
原因分析
汇编函数未明确标记Thumb属性
你的汇编代码仅通过.global asm_func声明了全局函数,但未添加.thumb_func或.code 16指令明确标记该函数属于Thumb指令集。gcc默认会将未明确指令集属性的汇编函数视为ARM指令集函数。Cortex-M内核的指令集限制
STM32H753搭载的Cortex-M7是Thumb-only内核,仅支持Thumb/Thumb-2指令集,无法执行ARM指令。当gcc判定目标函数为ARM指令集时,会生成BLX指令(用于在ARM与Thumb状态间切换),但该指令尝试切换到ARM状态时,直接触发硬故障。跨存储区域调用的叠加影响
由于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

