打印

擂台赛---N字节BCD加法之最小代码最小速度!

[复制链接]
2304|19
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
雁舞白沙|  楼主 | 2007-3-15 09:32 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
沙发
xwj| | 2007-3-15 11:40 | 只看该作者

最快的当然是汇编,我看谁还能更快!

; .BCD_ASM.A51 generated from: BCD_ASM.c
;Edit By xwj
;Program Size: DATA=8.0 XDATA=0 CODE=14
;Program Size: DATA=8.0 XDATA=0 CODE=18

$NOMOD51
NAME    BCD_ASM

Big_ENDian EQU   1     ;1为大端模式

?PR?_DATAAdd?BCD_ASM SEGMENT CODE 
    PUBLIC  _DATAAdd

;//xwj修改的程序:
;//入口:
;//*DATAOneDptr==>被加数数组的指针
;//*DATATwoDptr==>加数的数组指针
;// DATALEND   ==>数据字节数
;//出口:
;//*DATAOneDptr==>结果保存在*DATAOneDptr地址,会覆盖原*DATAOneDptr处数据
;void DATAAdd(unsigned char IDATA *DATAOneDptr,unsigned char IDATA *DATATwoDptr,unsigned char DATALEND)
    RSEG  ?PR?_DATAAdd?BCD_ASM
_DATAAdd:
    USING   0
IF Big_ENDian <> 1     ;非1为小端模式

    MOV     A,R7
    MOV     R0,A
    MOV     A,R5
    MOV     R1,A
    CLR     C           ;//清除低位向高位的进位
BCD_loop:
    MOV     A,@R0       ;//ACC=*DATAOneDptr+*DATATwoDptr+CY;
    ADDC    A,@R1         ;//二进制求和(没有上次低位向高位的进位)
    DA      A           ;//BCD码MCS51硬件调整;//C暂存低位向高位的进位
    MOV     @R0,A       ;//回写结果到*DATAOneDptr
    INC     R0          ;//DATAOneDptr++;
    INC     R1          ;//DATATowDptr++;
    DJNZ    R3,BCD_loop ;//{...}while(--DATALEND)
    RET     

ELSE     ;1为大端模式,有地址调整

    MOV     A,R7
    ADD     A,R3
    DEC     A
    MOV     R0,A
    MOV     A,R5
    ADD     A,R3
    DEC     A
    MOV     R1,A
    CLR     C           ;//清除低位向高位的进位
BCD_loop:
    MOV     A,@R0       ;//ACC=*DATAOneDptr+*DATATwoDptr+CY;
    ADDC    A,@R1         ;//二进制求和(没有上次低位向高位的进位)
    DA      A           ;//BCD码MCS51硬件调整;//C暂存低位向高位的进位
    MOV     @R0,A       ;//回写结果到*DATAOneDptr
    DEC     R0          ;//DATAOneDptr++;
    DEC     R1          ;//DATATowDptr++;
    DJNZ    R3,BCD_loop ;//{...}while(--DATALEND)
    RET     

ENDIF
    END
    

;本程序由xwj设计的UltraEdit脚本加亮显示,如需要脚本请联系xuwenjun@21cn.com

使用特权

评论回复
板凳
雁舞白沙|  楼主 | 2007-3-15 11:42 | 只看该作者

汇编也来了?没有想到!

偶回家练习练习!

使用特权

评论回复
地板
yewuyi| | 2007-3-15 11:50 | 只看该作者

哈哈,最快就是计算器……

使用特权

评论回复
5
xwj| | 2007-3-15 11:52 | 只看该作者

LS,你的观点早就过时了!

使用特权

评论回复
6
hotpower| | 2007-3-15 13:00 | 只看该作者

倒塌了~~~BCD还用打擂???

没时间倒塌了~~~白沙就好好玩吧.

一个原则:能用就好~~~

使用特权

评论回复
7
computer00| | 2007-3-15 13:27 | 只看该作者

呵呵,支持菜农~~~~不知道用在哪里的?

在这个东西上花太多时间值不值呀? 好比用在一个键盘输入然后处理的计算中,本身键盘扫描都要延迟ms,那么这个计算速度再快也没啥玩头.

使用特权

评论回复
8
xwj| | 2007-3-15 13:33 | 只看该作者

呵呵,还不是以为昨天hotpower 太无聊搞出N个版本,今天却...

使用特权

评论回复
9
hotpower| | 2007-3-15 19:50 | 只看该作者

倒塌了~~~我当时感觉白沙的算法太倒塌才参战的~~~

实际我反对BCD码~~~最多做做+-,*/必倒塌!!!

它的应用不过是给人看的,故一般用在LED数码显示.

其他真不多少用~~~

使用特权

评论回复
10
yixiupu0| | 2007-3-15 21:11 | 只看该作者

^_^

    在低端的地方用得很多,(如计算器,仪表等)它本身晶振才32.768K,在一个16ms的时间段中才能跑完3,4百句程序,你说最小代码最少时间有没有意义呢?像那种单片机很多都做了硬件防抖,扫描键盘时根本就不会去做几十ms的延时,顶多就是几个NOP,或者是扫描两次键值相同就认为是一次有效的按键。

使用特权

评论回复
11
dengm| | 2007-3-17 09:13 | 只看该作者

如果不破坏输入数据, asm 就要“同时” 用3个index--R0/R1/SP

     MOV R7, #16 ; N bytes packed bcd 
     MOV R6, #40H ; 1 st packed BCD
     MOV R5, #50H ; 2 nd packed BCD
     MOV R4, #60H ; RESULT 
     ACALL SUB_BCD_ADD   
    ;....
    ;....
     JMP $


         
SUB_BCD_ADD:
    MOV A, R7
    MOV R3, A
    MOV A, R6
    MOV R0, A
    MOV A, R5
    MOV R1, A
    MOV A, R4
    DEC A
    PUSH IE ;***
    CLR EA  ;***
    XCH A, SP
    MOV R2, A ; SP BAKUP 

    CLR C
BCD_ADD_LP:
      MOV A, @R0
      ADDC A, @R1
      DA A
      PUSH ACC
      INC R0
      INC R1
   DJNZ R3, BCD_ADD_LP
   MOV SP, R2
   POP IE ; ***
   RET

 

使用特权

评论回复
12
xwj| | 2007-3-17 10:58 | 只看该作者

dengm不愧是汇编老手,编的程序考虑得很周到

;直接操作堆栈指针SP太危险了,必须先关闭中断:

    PUSH IE ;***
    CLR EA  ;***
    XCH A, SP
    MOV R2, A ; SP BAKUP 

。。。
。。。

   MOV SP, R2
   POP IE ; ***

使用特权

评论回复
13
dengm| | 2007-3-17 14:26 | 只看该作者

这样写才能确保100%正确!!!

     MOV R7, #16 ; N bytes packed bcd 
     MOV R6, #40H ; 1 st packed BCD
     MOV R5, #50H ; 2 nd packed BCD
     MOV R4, #60H ; RESULT 
     ACALL SUB_BCD_ADD   
    ;....
    ;....
     JMP $


         
SUB_BCD_ADD:
    MOV A, R7
    MOV R3, A
    MOV A, R6
    MOV R0, A
    MOV A, R5
    MOV R1, A
    MOV A, R4
    DEC A
 
    JBC EA, BCD_ADD_EA

BCD_ADD_NOT_EA:
    XCH A, SP
    MOV R2, A ; SP BAKUP 

    CLR C
BCD_ADD_LP:
      MOV A, @R0
      ADDC A, @R1
      DA A
      PUSH ACC
      INC R0
      INC R1
   DJNZ R3, BCD_ADD_LP
   MOV SP, R2
   RET

BCD_ADD_EA:
   ACALL BCD_ADD_NOT_EA
   SETB EA
   RET

使用特权

评论回复
14
程序匠人| | 2007-3-18 00:05 | 只看该作者

BCD码的运算匠人用得很少

因为在计算机中,二进制的计算更方便,所以匠人一般都是用二进制数作运算。只有在送显时才做个转化,将BIN转成BCD。
相关链接:http://blog.21ic.com/user1/349/archives/2006/7314.html

使用特权

评论回复
15
hotpower| | 2007-3-18 00:20 | 只看该作者

dengm真能乱搞~~~把中断都搞来了~~~

PF~~~PF~~~

使用特权

评论回复
16
dengm| | 2007-3-18 09:23 | 只看该作者

乱搞一下中断, 就是怕中断搞乱.

使用特权

评论回复
17
dengm| | 2007-3-19 08:00 | 只看该作者

我的asm 的 loop 体只用 9 个周期, 应为最快的了。

使用特权

评论回复
18
dengm| | 2007-4-24 09:18 | 只看该作者

要高速就要3位3位(1k 1k) 来。不用2进制、10进制,要用1000进

 X *1000 = X*1024 - X * 24
         = X*1024 - (X * 3) * 8
 

使用特权

评论回复
19
xwj| | 2007-4-24 09:38 | 只看该作者

LS,注意是BCD加法,不是BIN To BCD哦

看来邓猫真的是走火入魔了...

使用特权

评论回复
20
dengm| | 2007-4-24 09:50 | 只看该作者

有空写一个 18byte packed bcd to bin 的,快速“非典”

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

213

主题

789

帖子

243

粉丝