硬汉嵌入式论坛

 找回密码
 立即注册
查看: 678|回复: 2
收起左侧

[开发工具] 经测试,AC6下使用atomic_inc32 (uint32_t *mem) 错误,请大神指点一下!

[复制链接]

2

主题

7

回帖

13

积分

新手上路

积分
13
发表于 2023-3-24 21:44:06 | 显示全部楼层 |阅读模式
起因是对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。

请大神们帮忙解答一下,感谢!

回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106685
QQ
发表于 2023-3-25 01:04:52 | 显示全部楼层
正常来说是要存到R0返回。

下载.png

存到R1也可以用,深入的,楼主有精力的话,可以再研究研究

QQ截图20230325010640.png




回复

使用道具 举报

2

主题

7

回帖

13

积分

新手上路

积分
13
 楼主| 发表于 2023-3-25 14:58:58 | 显示全部楼层
eric2013 发表于 2023-3-25 01:04
正常来说是要存到R0返回。

非常感谢,测试的函数返回值类型为uint32_t,我认为函数返回只能存放在R0中;不过也不再纠结这个了,以后用到的时候注意点就好。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|小黑屋|Archiver|手机版|硬汉嵌入式论坛

GMT+8, 2024-4-29 21:09 , Processed in 0.170243 second(s), 28 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2023, Tencent Cloud.

快速回复 返回顶部 返回列表