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

如何让ARM编译器生成STM指令而非多条STR指令?

如何让Cortex-M0+编译器生成STM指令替代多条STR指令?

我正在为Cortex-M0+编写一个重复读取固定内存地址并写入缓冲区的C函数,目标是让编译器生成STM指令而非多条STR指令。这款CPU没有指令预取单元和缓存,单条STM在取指周期上比多条STR效率更高。我了解-fldm-stm选项,但它仅用于启用该指令的功能支持,并非编译优化提示。

初始代码与编译选项

#include <stdint.h>

#define port (0x12345678U)
extern uint32_t buf[16];

void myfunc(void)
{
    uint32_t *p = buf;

    for (uint8_t i=0; i<16; i++)
    {
        *(p++) = *(volatile uint32_t *)(port);
    }
}

编译选项:-O3 -fldm-stm --target=arm-arm-none-eabi -mcpu=cortex-m0+ -mthumb


更新1:尝试循环展开与大小优化

参考建议修改了代码,添加循环展开编译指示并改用大小优化选项:

#include <stdint.h>

#define port (0x12345678U)
extern uint32_t buf[16];

void myfunc(void)
{
    uint32_t *p = buf;

#pragma unroll (4)

    for (uint8_t i=0; i<16; i++)
    {
        *(p++) = *(volatile uint32_t *)(port);
    }
}

编译选项:-Os -fldm-stm --target=arm-arm-none-eabi -mcpu=cortex-m0+ -mthumb

但编译器仍未生成STM指令。


更新2:接近预期效果,但存在疑问

经过调整后,代码如下:

#include <stdint.h>

#define port (0x12345678U)
extern uint32_t buf[16];

void myfunc(void)
{
    register uint32_t r0, r1, r2, r3;
    uint32_t *p = buf;

    for (uint8_t i=0; i<16; i+=4)
    {
         r0 = (uint32_t) (*(volatile uint32_t *)(port));
         r1 = (uint32_t) (*(volatile uint32_t *)(port));
         r2 = (uint32_t) (*(volatile uint32_t *)(port));
         r3 = (uint32_t) (*(volatile uint32_t *)(port));
        *(p++) = r0;
        *(p++) = r1;
        *(p++) = r2;
        *(p++) = r3;
    }
}

生成的循环体汇编代码如下:

.LBB0_1:
    ldr     r3, [r2]
    ldr     r4, [r2]
    ldr     r5, [r2]
    ldr     r6, [r2]
    stm     r1!, {r3, r4, r5, r6}  ;; Bingo!
    adds    r1, #0                 ;; 这行指令为什么存在?
    adds    r0, r0, #4
    cmp     r0, #12
    blo     .LBB0_1

我不清楚标记的adds r1, #0指令存在的原因,有人能解释吗?


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.26 03:16:04