|
起因是对AC6的汇编一直不是很清楚,我试着写了以下代码,发现有问题:
__STATIC_INLINE uint32_t u32BasepriSet(uint32_t u32Basepri)
{
uint32_t ret;
__ASM volatile (
"mrs %[ret], basepri \n\t"
"msr basepri, %[in] \n\t"
: [ret] "=r" (ret) /**< outputs */
: [in] "r" (u32Basepri) /**< inputs */
: "cc","memory"
);
return ret;
}
修改为以下代码,就正常了:
{
uint32_t ret, tmp;
__ASM volatile (
"mrs %[tmp], basepri \n\t"
"msr basepri, %[in] \n\t"
"mov %[ret], %[tmp]"
: [ret] "=r" (ret), [tmp] "=r" (tmp) /**< outputs */
: [in] "r" (u32Basepri) /**< inputs */
: "cc","memory"
);
return ret;
}
想到以前硬汉提过的原子操也有类似的代码,在文件在 rtx_core_cm.h 文件中找到以下函数:
__STATIC_INLINE uint32_t atomic_inc32 (uint32_t *mem) {
#ifdef __ICCARM__
#pragma diag_suppress=Pe550
#endif
register uint32_t val, res;
#ifdef __ICCARM__
#pragma diag_default=Pe550
#endif
register uint32_t ret;
__ASM volatile (
#ifndef __ICCARM__
".syntax unified\n\t"
#endif
"1:\n\t"
"ldrex %[ret],[%[mem]]\n\t"
"adds %[val],%[ret],#1\n\t"
"strex %[res],%[val],[%[mem]]\n\t"
"cbz %[res],2f\n\t"
"b 1b\n"
"2:"
: [ret] "=&l" (ret),
[val] "=&l" (val),
[res] "=&l" (res)
: [mem] "l" (mem)
: "cc", "memory"
);
return ret;
}
测试代码:
uint32_t test = 0;
atomic_inc32(&test);
反汇编代码:
0x080076F2 F6484008 MOVW r0,#0x8C08
0x080076F6 F2C20000 MOVT r0,#0x2000
0x080076FA E8501F00 LDREX r1,[r0,#0]
0x080076FE 1C4A ADDS r2,r1,#1
0x08007700 E8402300 STREX r3,r2,[r0,#0]
0x08007704 B103 CBZ r3,0x08007708
0x08007706 E7F8 B 0x080076FA
分析反汇编代码发现,返回值存储于寄存器R1中,而C语言的约定是返回值存储于 R0。
请大神们帮忙解答一下,感谢!
|
|