TA的每日心情 | 无聊 2016-12-20 15:08 |
---|
签到天数: 510 天 连续签到: 1 天 [LV.9]以坛为家II
|
前两周刚搞好一个labview的作品,这几天又开始忙做单片机课设,没想到开学开始这么忙。不过今天在做课设过程中有所收获,所以特地花点时间和大家分享分享。
因为课设要做的涉及到SD卡,所以函数参数中长整型用到比较多。51是8位,不知道处理32位数据上效率怎么样,于是今天特地做了下测试,顺便复习下汇编语言。想要知道一条C代码执行效率怎么样,还是得用反汇编窗口看看汇编后的代码是什么。说了这么多好像大家都不知道我在说些什么。额,好像确实没有逻辑。我还是另起一段,有条理的讲述下问题吧。
我用51实现SPI模式读取SD卡,因为SD卡的函数参数是32位长整型,而SPI以字节为单位传输,于是就涉及到如何获得长整型的各个字节。我目前已知的方法有两种,一种是用移位来获得高位字节,如:SDWriteByte((uint8)(arg >> 24));还有一种是指针的方法,如:SDWriteByte(((unsigned char *)&arg)[0]);以上两句代码实现的是一样的功能(arg是32位无符号长整型,这里其值为0x00000095),但是哪种的效率高呢?我们可以打开keil的反汇编窗口看看汇编后的代码就知道了。
对于第一种方法,汇编代码如:- 253: SDWriteByte((uint8)(arg >> 24));
- C:0x26A8 7818 MOV R0,#0x18
- C:0x26AA 1228A8 LCALL C:28A8
复制代码 这里调用了地址C:28A8的函数,所以我们转到C:28A8看一下代码:- C:0x28A8 900289 MOV DPTR,#0x0289
- C:0x28AB E0 MOVX A,@DPTR
- C:0x28AC FC MOV R4,A
- C:0x28AD A3 INC DPTR
- C:0x28AE E0 MOVX A,@DPTR
- C:0x28AF FD MOV R5,A
- C:0x28B0 A3 INC DPTR
- C:0x28B1 E0 MOVX A,@DPTR
- C:0x28B2 FE MOV R6,A
- C:0x28B3 A3 INC DPTR
- C:0x28B4 E0 MOVX A,@DPTR
- C:0x28B5 FF MOV R7,A
- C:0x28B6 121118 LCALL C?ULSHR(C:1118)
- ......(这里是SDWriteByte函数)
复制代码 这是0x28A8处的代码,以上部分是参数传递部分,后面省略的是SDWriteByte函数。可以看到前面 12句是将arg复制到寄存器中。(可以看到arg在内存中的地址正是0x0289)
那最后一句呢?老实说我汇编很烂,看到C?ULSHR还以为那问号是乱码呢?不过等看完代码后终于知道这里调用的是一个函数:无符号长整型右移函数(ULSHR),在C:1118可以看到函数代码:- C?ULSHR:
- C:0x1118 E8 MOV A,R0
- C:0x1119 600F JZ C:112A
- C:0x111B EC MOV A,R4
- C:0x111C C3 CLR C
- C:0x111D 13 RRC A
- C:0x111E FC MOV R4,A
- C:0x111F ED MOV A,R5
- C:0x1120 13 RRC A
- C:0x1121 FD MOV R5,A
- C:0x1122 EE MOV A,R6
- C:0x1123 13 RRC A
- C:0x1124 FE MOV R6,A
- C:0x1125 EF MOV A,R7
- C:0x1126 13 RRC A
- C:0x1127 FF MOV R7,A
- C:0x1128 D8F1 DJNZ R0,C:111B
- C:0x112A 22 RET
复制代码 17句代码实现了长整型的右移位,老实说,平时没用汇编,看懂了上面的代码后才发现汇编是多么精妙的东西,简单,却强大。
不过,汇编好归好,要是评估起这个移位传参的方法好像效率不是很高哦。一个右移函数的循环部分有14条指令,像这里移位24,算起来要执行300多条指令才能搞定。一句看起来简单的arg>>24竟然要执行这么多指令来完成,那样速率一定有很大影响。
我们再来看第二种方法,汇编代码如下:- 254: SDWriteByte(((unsigned char *)&arg)[0]);
- C:0x26A8 900289 MOV DPTR,#0x0289
- C:0x26AB E0 MOVX A,@DPTR
- C:0x26AC FF MOV R7,A
- C:0x26AD 1228AB LCALL SDWriteByte(C:28AB)
复制代码 可以看到这种方法代码很少,只用了3条指令就完成了参数的传递 ,效率之高就不用说了。
综上,我个人认为在51在进行长移位并不是一个效率很高的方法,用指针的方法应该更好。不知道大家有什么看法,或者有其他更好的方法可以分享下。
|
|