ARM Cortex-M7下如何让GHS编译器生成STRH而非STRH.W指令?
强制GHS汇编器生成STRH指令解决对齐总线异常问题
手写汇编代码直接指定指令
如果是手写汇编代码,直接写不带.w后缀的strh即可:
strh r0, [r2, #0xAAA]
GHS的ARM汇编器默认会根据上下文选择指令宽度,但明确写strh会强制生成16位Thumb-2指令,不会自动转为32位的strh.w。
C代码通过编译选项控制
如果是C代码编译生成的指令,用GHS的编译选项限制指令加宽:
- 添加
-mthumb确保生成Thumb/Thumb-2指令集代码,再搭配-mno-widen-mem-access选项,禁止汇编器自动将内存访问指令加宽为32位版本(比如把strh转成strh.w)。 - 若只需针对特定函数调整,用函数属性做精细控制:
__attribute__((target("no-widen-mem-access"))) void flash_write(uint16_t val, uint32_t addr) { *(volatile uint16_t*)addr = val; }
检查编译器配置差异
两个编译环境的问题大概率出在默认配置上:
- 出问题的环境可能开启了
-mwiden-mem-access(部分版本默认开启),这个选项会让汇编器自动将部分16位内存指令转为32位,这就是生成strh.w的原因。 - 对照正常环境的编译选项,同步配置就能消除差异。
补充:为啥strh.w会触发错误?
虽然0x60000AAA是2字节对齐地址,但部分微控制器的内存接口对32位半字存储指令(strh.w)的要求更严格(比如隐含要求4字节对齐),或者XIP模式下的S26H闪存控制器不支持32位宽度的半字访问,导致即使地址对齐也触发总线异常。换成16位的strh指令即可匹配闪存的访问要求。
内容的提问来源于stack exchange,提问作者Joel D'Souza
相关产品推荐
相关产品推荐

