使用 ldm/stm 作为内联 asm 进行 32 字节移动

arm 32 byte move with ldm/stm as inline asm

我正在尝试执行以下操作,但它不起作用。使用 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

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

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