【问题标题】:arm 32 byte move with ldm/stm as inline asmarm 32 字节移动与 ldm/stm 作为内联 asm
【发布时间】:2021-10-19 02:42:20
【问题描述】:

我正在尝试执行以下操作,但它不起作用。使用 arm 工具链 gcc 8.5 时代码崩溃。

#define _move(src, dst) __asm volatile ( \
                "ldr   r0, [%0] \n\t"    \
                "ldr   r1, [%1] \n\t"    \
                "ldm   r0!, {r4-r11} \n\t" \
                "stm   r1!, {r4-r11} \n\t" \
                :          \
                : "r" (dst), "r" (src)          \
                : "cc"          \
                )


static uint32_t sr[8];
static uint32_t ds[8];

int main() {

    sr[0] = 0xff;
    
    _move(sr, ds);

    printf("data:%d\n", ds[0]);

}

代码有什么问题?

https://godbolt.org/z/edzz9vhPK

【问题讨论】:

  • 您是否检查过您可以在不破坏重要值的情况下使用所有这些寄存器?你至少应该在clobber列表中这样说。
  • ldr r0, [%0],从dst 地址读取值。或r0 = ds[0]ds[0] 很可能为零(或一些随机的废话),我认为 ldm r0!, {r4-r11} 正在使用 NULL 解引用。
  • 除了为寄存器 4 到 11 声明 clobber,您还需要 clobber "memory"
  • 无论如何,你有什么理由不信任编译器而只做memcpy(ds, sr, 32)
  • 感谢提及“记忆”。这样做的原因是时间。我需要最快的方式来传输数据。目前我无法进行正常的 dmac 传输。

标签: c gcc arm gcc8


【解决方案1】:

问题是访问未对齐,因为在实际项目中有一个缓冲区开始对齐 32,但使用 ldm 访问数据有时是未对齐的。

现在我在访问它们之前检查 src 指针,如果它没有对齐,我会屏蔽前两位。在我处理数据时,这已被检查和更正。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-01-15
    • 2016-06-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-12-29
    • 1970-01-01
    相关资源
    最近更新 更多