找回密码
 立即注册
查看: 258|回复: 7

栗说C251与汇编语言混合编程

[复制链接]
  • 打卡等级:以坛为家II
  • 打卡总天数:521
  • 最近打卡:2025-05-09 05:40:06

24

主题

519

回帖

1026

积分

荣誉版主

积分
1026
发表于 2024-12-11 20:29:27 | 显示全部楼层 |阅读模式
AI公司提供的AI32G12K128的USB例程的util.c文件里有一个函数:

WORD reverse2(WORD w)
{
    WORD ret;
   
    ((BYTE *)&ret)[0] = ((BYTE *)&w)[1];
    ((BYTE *)&ret)[1] = ((BYTE *)&w)[0];

    return ret;
}

编译后的汇编代码为:
    29: WORD reverse2(WORD w)
0xFF1316   7A370021    MOV      w(0x0021),WR6
    30: {
    31:     WORD ret;
    32:      
    33:     ((BYTE *)&ret)[0] = ((BYTE *)&w)[1];
0xFF131A   7E340022    MOV      WR6,#0x0022
0xFF131E   7E240000    MOV      WR4,#0x0000
0xFF1322   7E1B30      MOV      R3,@DR4
0xFF1325   7E340023    MOV      WR6,#0x0023
0xFF1329   7E240000    MOV      WR4,#0x0000
0xFF132D   7A1B30      MOV      @DR4,R3
    34:     ((BYTE *)&ret)[1] = ((BYTE *)&w)[0];
    35:  
0xFF1330   7E340021    MOV      WR6,#w(0x0021)
0xFF1334   7E240000    MOV      WR4,#0x0000
0xFF1338   7E1B30      MOV      R3,@DR4
0xFF133B   7E340024    MOV      WR6,#0x0024
0xFF133F   7E240000    MOV      WR4,#0x0000
0xFF1343   7A1B30      MOV      @DR4,R3
    36:     return ret;
0xFF1346   7E370023    MOV      WR6,0x0023
    37: }
0xFF134A   22          RET      

用汇编代码为:
        RSEG       ?PR?REVERSE2?UTIL
        reverse2 PROC   
; line 29: WORD reverse2(WORD w)
        MOV      WR4,WR6
        MOV      R6,R5
        MOV      R7,R4
        RET      
        ENDP

然后将c文件替换为汇编代码文件,重新编译后,进入debug汇编界面,
在usb.c文件里找到调用reverse2(WORD w)函数处:

   244:             Setup.wLength = reverse2(Setup.wLength);
0xFF0D8C   7E37000E    MOV      WR6,0x000E
0xFF0D90   12153A      LCALL    reverse2(C:0x153A)
0xFF0D93   7A37000E    MOV      0x000E,WR6

再找到reverse2(C:0x153A)处:
    75:         MOV      WR4,WR6
0xFF153A   7D23        MOV      WR4,WR6
    76:         MOV      R6,R5
0xFF153C   7C65        MOV      R6,R5
    77:         MOV      R7,R4
0xFF153E   7C74        MOV      R7,R4
    78:         RET      
0xFF1540   22          RET      

验证OK!




回复

使用道具 举报 送花

  • 打卡等级:初来乍到
  • 打卡总天数:7
  • 最近打卡:2025-04-01 23:18:33

15

主题

139

回帖

987

积分

高级会员

积分
987
发表于 2024-12-11 22:21:35 | 显示全部楼层
大小端转换?
uint16_t reverse2(uint16_t w)
{
    return (w >> 8) | (w << 8);
}

这种非常简单的操作,用函数调用效率太低了,函数调用3个时钟,返回又3个时钟,调用前后的参数传递和返回值也需要消耗时钟周期,而真正的操作只有两三条指令而已。

如果要转换数据放在寄存器A和B,(WR10),只需一条指令,
XCH A,B

回复 支持 反对

使用道具 举报 送花

  • 打卡等级:以坛为家II
  • 打卡总天数:521
  • 最近打卡:2025-05-09 05:40:06

24

主题

519

回帖

1026

积分

荣誉版主

积分
1026
发表于 2024-12-12 07:58:29 | 显示全部楼层
确实,用 return (w >> 8) | (w << 8); 可以编译出高效的代码:

    30: WORD reverse2(WORD w)
    31: {
    32:     return (w >> 8) | (w << 8);
0xFF153A   6C67        XRL      R6,R7
0xFF153C   6C76        XRL      R7,R6
0xFF153E   6C67        XRL      R6,R7
    33: }
0xFF1540   22          RET  
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:偶尔看看III
  • 打卡总天数:42
  • 最近打卡:2025-05-09 08:19:05
已绑定手机

17

主题

446

回帖

1189

积分

金牌会员

积分
1189
发表于 2024-12-12 08:34:10 | 显示全部楼层
转换成通用指针确实慢
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:以坛为家II
  • 打卡总天数:521
  • 最近打卡:2025-05-09 05:40:06

24

主题

519

回帖

1026

积分

荣誉版主

积分
1026
发表于 2024-12-12 08:35:23 | 显示全部楼层
同样道理,对于函数:
DWORD reverse4(DWORD d)
{   
    DWORD ret;
   
    ((BYTE *)&ret)[0] = ((BYTE *)&d)[3];
    ((BYTE *)&ret)[1] = ((BYTE *)&d)[2];
    ((BYTE *)&ret)[2] = ((BYTE *)&d)[1];
    ((BYTE *)&ret)[3] = ((BYTE *)&d)[0];

    return ret;
}

改为:
return (d << 24) | (d << 16) & 0xff0000 | ((d >> 16) & 0xff00) | (d >> 24) ;
也可以编译出高效的代码:
    17: DWORD reverse4(DWORD d)
    18: {   
0xFF186B   7F21        MOV      DR8,DR4
    19:     return (d << 24) | (d << 16) & 0xff0000 | ((d >> 16) & 0xff00) | (d >> 24) ;
0xFF186D   7D03        MOV      WR0,WR6
0xFF186F   6C00        XRL      R0,R0
0xFF1871   7C41        MOV      R4,R1
0xFF1873   6C55        XRL      R5,R5
0xFF1875   4D20        ORL      WR4,WR0
0xFF1877   7D14        MOV      WR2,WR8
0xFF1879   6C33        XRL      R3,R3
0xFF187B   7D02        MOV      WR0,WR4
0xFF187D   0A38        MOVZ     WR6,R8
0xFF187F   4D31        ORL      WR6,WR2
    20: }
0xFF1881   22          RET      

用汇编最高效:
        MOV      DR8,DR4
        MOV      R4,R11
        MOV      R5,R10
        MOV      R6,R9
        MOV      R7,R8
        RET      
        ENDP
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:偶尔看看III
  • 打卡总天数:42
  • 最近打卡:2025-05-09 08:19:05
已绑定手机

17

主题

446

回帖

1189

积分

金牌会员

积分
1189
发表于 2024-12-12 09:08:36 | 显示全部楼层
还是ARM NB一条指令搞定 __rev
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:偶尔看看III
  • 打卡总天数:42
  • 最近打卡:2025-05-09 08:19:05
已绑定手机

17

主题

446

回帖

1189

积分

金牌会员

积分
1189
发表于 2024-12-12 09:11:01 | 显示全部楼层
;DWORD reverse4(DWORD d)
        PUSH         R7
        PUSH        R6
        PUSH        R5
        PUSH        R4
        POP                DR4
        RET
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:偶尔看看III
  • 打卡总天数:42
  • 最近打卡:2025-05-09 08:19:05
已绑定手机

17

主题

446

回帖

1189

积分

金牌会员

积分
1189
发表于 2024-12-12 09:18:30 | 显示全部楼层
;DWORD reverse4(DWORD d)
        PUSH        DR4
        POP                R4
        POP                R5
        POP                R6
        POP                R7
        RET
回复 支持 反对

使用道具 举报 送花

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

本版积分规则

QQ|手机版|小黑屋|深圳国芯人工智能有限公司 ( 粤ICP备2022108929号-2 )

GMT+8, 2025-5-9 22:22 , Processed in 0.122698 second(s), 93 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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