【发布时间】:2012-02-15 22:36:48
【问题描述】:
我在处理一些内联汇编代码时遇到了一些问题。我知道应该做什么,但我错过了“如何”!
我有这个“几乎”工作的校验和函数:
static unsigned long cksum_unroll( unsigned short **w, int *mlen)
{
int len;
unsigned short *w0;
unsigned long sum=0;
len = *mlen;
w0 = *w;
while( len >= 8) {
asm volatile (
"ldmia %[w0]!, {v1, v2}\n\t"
"adds %[sum], %[sum], v1\n\t"
"adcs %[sum], %[sum], v2\n\t"
"adcs %[sum], %[sum], #0"
: [sum] "+r" (sum) : [w0] "r" (w0)
);
len -= 8;
}
*mlen = len;
*w = w0;
return (sum);
}
我相信我的问题在于“: [sum] "+r" (sum) : [w0] "r" (w0)" 在第一条装配线上,ldmia 正确处理了 w0(当该线执行时,数据在 r4,r5 中,并且 w0 递增)。但是 w0 的增量值并没有保存在某个地方,当代码循环时,w0 的原始值会再次加载(参见下面的汇编代码)。 我的猜测是我应该将 w0 的值存储在 ": [sum] "+r" (sum) : [w0] "r" (w0)" 行上,但我不知道如何......
这是函数内联汇编部分的反汇编代码:
请注意:
len is stored at r11, #-16
w0 is stored at r11, #-20
sum is stored at r11, #-24
编译,如下代码:
asm volatile (
"ldmia %[w0]!, {v1, v2}\n\t"
"adds %[sum], %[sum], v1\n\t"
"adcs %[sum], %[sum], v2\n\t"
"adcs %[sum], %[sum], #0"
: [sum] "+r" (sum) : [w0] "r" (w0)
);
len -= 8;
生成:
00031910: ldr r3, [r11, #-20]
00031914: ldr r2, [r11, #-24]
00031918: mov r4, r2
0003191c: ldm r3!, {r4, r5}
00031920: adds r4, r4, r4
00031924: adcs r4, r4, r5
00031928: adcs r4, r4, #0
0003192c: str r4, [r11, #-24]
00031930: ldr r3, [r11, #-16]
00031934: sub r3, r3, #8
00031938: str r3, [r11, #-16]
如您所见,我想在第 31928 行和第 3192c 行之间添加类似“str r3, [r11, #-20]”的内容,因为当程序循环到第 31910 行时,r3 会加载初始值r3...
我认为这对于堆栈溢出社区的内联汇编专家来说是一件容易的事!
顺便说一句,我正在研究 ARM7TDMI 处理器(但这可能与这个问题无关......)
提前致谢!
编辑:
为了验证我的想法,我测试了以下内容:
asm volatile (
"ldmia %[w0]!, {v1, v2}\n\t"
"adds %[sum], %[sum], v1\n\t"
"adcs %[sum], %[sum], v2\n\t"
"adcs %[sum], %[sum], #0\n\t"
"str %[w0], [r11, #-20]"
: [sum] "+r" (sum) : [w0] "r" (w0)
);
这很有效。也许这就是解决方案,但是我用什么来替换“r11,#20”,如果我修改函数可能会改变?
【问题讨论】:
-
为了验证我的想法,我测试了以下内容:
asm volatile ( "ldmia %[w0]!, {v1, v2}\n\t" "adds %[sum], %[sum], v1\n\t" "adcs %[sum], %[sum], v2\n\t" "adcs %[sum], %[sum], #0\n\t" "str %[w0], [r11, #-20]" : [sum] "+r" (sum) : [w0] "r" (w0) );这很有效。也许这是解决方案,但是我用什么来替换“r11,#20”,如果我修改函数可能会改变? -
GCC 的内联汇编让我头疼(而且我已经开始了一个,因为附近的改造中正在进行一些地毯胶合),所以我不能给你任何直接的帮助......但是我可以向您指出我读过的关于如何处理 GCC 的内联汇编的最佳文档之一,以防您还没有遇到它:ethernut.de/en/documents/arm-inline-asm.html 作为奖励,该文档专门针对 ARM。跨度>
-
感谢您的链接。当我写这个问题时,这个网页已经打开了!
标签: c gcc arm inline-assembly