shamork 发表于 2009-9-17 14:12:12

Hex2BCD再讨论——由自写printf引出的另类Hex2BCD算法

转自大虾网 http://www.daxia.com/list_1683.shtml

有一个矛盾总是在困扰我们---那就是计算机喜欢2进制(16进制)而人类已经习惯了10进制
传统的HEX--BCD通常都按二进制定义按权展开,再付以10进制调整来实现,速度太慢,效率低
我的思路是这样的2的12次方=4096=4100-4=1000H及每一个1000H可以看着"4100"如果有误
差可以从余数中扣除,如双字节数最多扣除16*4=64个,如果有余数,够扣就扣,不够扣从4100
个中次高位减一当100已经够了!如果你问16是怎么来得我告诉65536/4096=16下面是程序
DPTR中是待转换的双字节16进制数,转换的数据保存在34H33H32H31H30H五个连续单元中34H
为高,同样的道理把100=60H+4    4096/96最多商42   4*42=168
16=4096/256 64和128因为都是单字节所以运算非常简单,经过仿真对比其运行速度比传统
方式快12倍!!!!!!!
       HEXBCD:MOV A,DPH   ;16进制高位送A
            ANL A,#0F0H;屏蔽A低四位
            XRL DPH,A    ;屏蔽DPH高四位
            SWAP A       ;A除以16 ( 注意这技巧)
            MOV 32H,A    ;把A个100放百位单元
            RL A
            RL A         ;两次RL A相当于乘以4,这个4表示4A个千,也表示要扣除4A
             ;A*4096=A*(4000+100)-4A=4A*1000+A*100-4A
            XCH A,DPL
            SUBB A,DPL
            XCH A,DPH
            SUBB A,#00H;以上四条指令完成4A的扣除,结果高位在A,低位在DPH
            JNC   "够扣"
            DEC 32H ;不够扣32H减一当百
            MOV A,#101 ;本来是100这里用101是考虑C=1这样就节省一条指令CLR C
            SUBB A,DPL
            ADD A,DPH;A肯定小于64为什么?所以高位不计算了!
            MOV B,#10
            DIV AB
            MOV 31H,A
            MOV 30H,B
这是个简易的printf,一次只能带一个参数,printf代码在下面。
============================================================
这里是main.c
============================================================
#define _X
#include<myprintf.c> //mypr换成printf时,将此项注释掉

//mypr换成printf时,包含下面三项
//#include<regx52.h>        //mypr换成printf时,包外含这三项,将上面一项注释掉
//#include<inituart.c>
//#include<stdio.h>
main()
{
        unsigned int k=0x1234;
        InitUart();
        while(1)               
        {       
                mypr("Hello World!\r\n K is %x",k);//定义_U时%x换成%u,用printf时用%u和%x各一次
        }                          
}
void uart(void) interrupt 4 using 0
{
}
#define _XProgram Size: data=15.0 xdata=0 code=256
#define _UProgram Size: data=27.0 xdata=0 code=716
printf ...一样
%x Program Size: data=32.1 xdata=0 code=1131
%u Program Size: data=32.1 xdata=0 code=1131

============================================================
下面是myprintf.c
============================================================
#include<regx52.h>
#ifndef   BaudRate
   #define BaudRate 57600L
#endif
#ifndef   OSC
   #define OSC      22118400L   //11.0592M
#endif
#include<inituarts.c>


#ifndef _X
   #ifndef _U
           #define _X
           #define _U
   #endif
#endif

unsigned char code hex2ascii[]={0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x41,0x42,0x43,0x44,0x45,0x46};


//putchar
void prc(unsigned char c)
{
   while(!TI)
           ;
   TI=0;
   SBUF=c;          
}

//xu=1 或2 说明包含输出%u功能
#ifdef _U                
   void Hex2BCD(unsigned char *p,unsigned int t)
   {
           unsigned char i=0;   
           unsigned char s;
           if(t<10000) goto ca0;
           if(t>=40000) {i =4;t-=40000;}   //如果t<=9999,则这部分可不用。   
           if(t>=20000) {i+=2;t-=20000;}   
           if(t>=10000) {i++; t-=10000;}   
                *p++=i+48;      //LCDascii               
          
           i=0;   
           ca0:
           if(t>=8000) {i =8;t-=8000;goto ca1;}   
           else
                if(t>=4000) {i=4;t-=4000;}
                else ;
          
           if(t>=2000) {i+=2;t-=2000;}   
           ca1:
           if(t>=1000) {i++; t-=1000;}   
           *p++=i+48;   
           i=0;   
           if(t>=800) {i =8;t-=800;goto cb1;}   
           else
                if(t>=400) {i=4;t-=400;}   
                else ;   
           if(t>=200) {i+=2;t-=200;}
           cb1:   
           s=(unsigned char)t;
           if(s>=100) {i++; s-=100;}   
           *p++=i+48;   
           i=0;   
           if(s>=80) {i=8;s-=80;goto cc1;}
           else
                if(s>=40) {i=4;s-=40;}   
                else ;   
           if(s>=20) {i+=2;s-=20;}
           cc1:
           if(s>=10) {i++; s-=10;}   
           *p++=i+48;   
           *p++=s+48;
           *p='\0';
   }
#endif

//miniprintf
void mypr(unsigned char code *p,unsigned int ap)
{
   unsigned char* apbufp;
#ifdef _U
   unsigned char apbuf;
#endif

   for( ;(*p) != '\0';++p)
   {
           if(*p!='%')                             
           {
                prc(*p);
                continue;
           }
           p++;

#ifdef _X
           if(*p=='x')
           {
                
                prc('0');
                prc('x');
                apbufp=(unsigned char *)(&ap);       //指向ap的高位,简化除法。(只用高位)
                while(ap)
                {
                        if(ap&0xf000)      //说明ap>0x1000
                             prc(hex2ascii[(unsigned char)(*apbufp>>4)]);   //提取高位,然后除8 ,如0x1234提出0x12,0x12>>4=0x01
                        else
                             prc('0');
                        ap<<=4;             //向高位移4位,0x1234变成0x2340变成0x3400变成0x4000变成0x0000
                }
           }
           continue;
#endif

#ifdef _U
           if(*p=='u')
           {
                Hex2BCD(apbuf,ap);              //变成BCD数组
                apbufp=apbuf;
                while(*apbufp)
                {   
                        prc(*apbufp);
                        apbufp++;
                }
           }
#endif          
           continue;
   }                          
}

shamork 发表于 2009-9-17 14:12:23

变参数,myprintf2.c
#define _X
#include<myprintf2.c> //mypr换成printf时,将此项注释掉

//mypr换成printf时,包含下面三项
//#include<regx52.h> //mypr换成printf时,包外含这三项,将上面一项注释掉
//#include<inituart.c>
//#include<stdio.h>   
main()
{
unsigned int k=0x1234;
InitUart();
while(1)
{   
mypr("\r\n K is %x, K is %u",k,k);//定义_U时%x换成%u,用printf时用%u和%x各一次
}   
}
void uart(void) interrupt 4 using 0
{
}
#define _X%x%x Program Size: data=31.0 xdata=0 code=369
#define _U%u%u Program Size: data=45.0 xdata=0 code=835
#define _XU %x%u Program Size: data=48.0 xdata=0 code=922

printf ...一样
%x%x Program Size: data=32.1 xdata=0 code=1146
%u%u Program Size: data=32.1 xdata=0 code=1146
%x%u Program Size: data=32.1 xdata=0 code=1146

看来是在Hex2BCD上花了太多资源。高手来指点。!

==================================================================
下面是myprintf2.c inituarts.c在最本贴最下面。
==================================================================
#include<regx52.h>
#include <stdarg.h>   
#ifndef    BaudRate
    #define BaudRate 57600L
#endif

#ifndef    OSC
    #define OSC      22118400L   //11.0592M
#endif
#include<inituarts.c>

//#define _XU
#ifndef _X
    #ifndef _U
      #define _X
      #define _U
    #endif
#endif

unsigned char code hex2ascii[]={0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x41,0x42,0x43,0x44,0x45,0x46};
//putchar
void prc(unsigned char c)
{
    while(!TI)
      ;
    TI=0;
    SBUF=c;         
}

#ifdef _U               
    void Hex2BCD(unsigned char *fmt,unsigned int t)
    {
      unsigned char i=0;   
      unsigned char s;
      if(t<10000) goto ca0;
      if(t>=40000) {i =4;t-=40000;}   //如果t<=9999,则这部分可不用。   
      if(t>=20000) {i+=2;t-=20000;}   
      if(t>=10000) {i++; t-=10000;}   
            *fmt++=i+48;      //LCDascii               
         
      i=0;   
      ca0:
      if(t>=8000) {i =8;t-=8000;goto ca1;}   
      else
            if(t>=4000) {i=4;t-=4000;}
            else ;
         
      if(t>=2000) {i+=2;t-=2000;}   
      ca1:
      if(t>=1000) {i++; t-=1000;}   
      *fmt++=i+48;   
      i=0;   
      if(t>=800) {i =8;t-=800;goto cb1;}   
      else
            if(t>=400) {i=4;t-=400;}   
            else ;   
      if(t>=200) {i+=2;t-=200;}
      cb1:   
      s=(unsigned char)t;   
      if(s>=100) {i++; s-=100;}   
      *fmt++=i+48;   
      i=0;   
      if(s>=80) {i=8;s-=80;goto cc1;}   
      else
            if(s>=40) {i=4;s-=40;}   
            else ;   
      if(s>=20) {i+=2;s-=20;}   
      cc1:   
      if(s>=10) {i++; s-=10;}   
      *fmt++=i+48;   
      *fmt++=s+48;
      *fmt='\0';   
    }
#endif

//miniprintf
void mypr(unsigned char code *fmt,...)
{
    unsigned char * apbufp;
#ifdef _U
    unsigned char apbuf;
#endif
    va_list pp;
    va_start(pp,fmt); /* 用最后一个具有参数的类型的参数去初始化ap */

   
    for( ;(*fmt) != '\0';++fmt)
    {
      if(*fmt!='%')                     
      {
            prc(*fmt);
            continue;
      }
      fmt++;

      if(*fmt=='%')
      {
            prc('%');
            continue;
      }
      if(*fmt=='\0')         //错误,格式符不完整
      {   
            prc(16);         //输出一个小方框...表示错误
      return ;}
         
      {
            unsigned int ap =va_arg(pp,unsigned int);//作用范围{}内
            if(*fmt=='x')
            {
    #ifdef _X   
                prc('0');
                prc('x');
                apbufp=(unsigned char *)(&ap);      //指向ap的高位,简化除法。(只用高位)
                while(ap)
                {
                  if(ap&0xf000)       //说明ap>0x1000
                        prc(hex2ascii[(unsigned char)(*apbufp>>4)]);//提取高位,然后除8 ,如0x1234提出0x12,0x12>>4=0x01
                  else
                        prc('0');
                  ap<<=4;          //向高位移4位,0x1234变成0x2340变成0x3400变成0x4000变成0x0000
                }         
    #else         
                goto error;         
    #endif            
                continue;
                }
   
         
            if(*fmt=='u')
            {
    #ifdef _U   
                Hex2BCD(apbuf,ap);         //变成BCD数组
                apbufp=apbuf;
                while(*apbufp)
                {   
                  prc(*apbufp);
                  apbufp++;
                }
    #else         
                goto error;      
    #endif            
                continue;
                }
            }
#ifndef _XU
error:
            prc(15);          //定义时未包含此格式,例如定义了_U,却用了%x
            continue;
#endif
    }                  
}

=======================================
下面是inituarts.c
=======================================
//22.1184M Hz 晶振
//#define BaudRate 57600L   //波特率
//#define OSC      22118400L   //晶振频率//22.1184M

#ifndef BaudRate //波特率
#error BaudRate undefined! Now BaudRate is Defaut(115200)!
#define BaudRate 115200L //晶振频率
#endif
#ifndef OSC
#error OSC undefined! Now OSC is Defaut(11059200)!
#define OSC      11059200L   //11.0592M
#endif
#define TimerInitNum            (256 - (OSC/192L)/BaudRate)   // 255 //定时器1初值

//定时器1为波特率发生器

#if (BaudRate==2400)||(BaudRate==4800)||(BaudRate==9600)||(BaudRate==14400)||(BaudRate==19200)||(BaudRate==28800)||(BaudRate==38400)||(BaudRate==57600)||(BaudRate==115200)
void InitUart(void)   
{
SCON=0x50; //串口方式1,允许接收
TMOD=0x20; //定时器1定时方式2
PCON=0x80; //设定SMOD为1
TH1=TimerInitNum; //0xfe 22.1184M-57600bps
TL1=TimerInitNum;
TR1=1; //启动定时器 //设定时器1开始计数
ET1=1;TI=1;
EA=1;
ES=1;
}
#else
#error "BaudRate" defination do not match,must be one of (19200,57600,115200)!
#endif

wolf11_1234 发表于 2009-9-17 14:19:49

你的hex2bcd太臃肿了
用keil自带的库,反汇编回来看看

shamork 发表于 2009-9-17 14:29:46

下面就是printf了
printf("Hello World!\r\n K is %x, K is %u",k,k);
C:0x0450    1187   ACALL    PRINTF(C:0087)

C:0x0087    E4       CLR      A
C:0x0088    C207   CLR      0x20.7
C:0x008A    F519   MOV      0x19,A
C:0x008C    8B0A   MOV      ?_PRINTF517?BYTE(0x0A),R3
C:0x008E    8A0B   MOV      0x0B,R2
C:0x0090    890C   MOV      0x0C,R1
C:0x0092    E4       CLR      A
C:0x0093    F51A   MOV      0x1A,A
C:0x0095    F51C   MOV      0x1C,A
C:0x0097    F51D   MOV      0x1D,A
C:0x0099    E51A   MOV      A,0x1A
C:0x009B    6007   JZ       C:00A4
C:0x009D    7F20   MOV      R7,#0x20
C:0x009F    120060   LCALL    C:0060
C:0x00A2    80F5   SJMP   C:0099
C:0x00A4    751BFF   MOV      0x1B,#0xFF
C:0x00A7    C201   CLR      0x20.1
C:0x00A9    C200   CLR      0x20.0
C:0x00AB    C202   CLR      0x20.2
C:0x00AD    C203   CLR      0x20.3
C:0x00AF    C205   CLR      0x20.5
C:0x00B1    C206   CLR      0x20.6
C:0x00B3    C208   CLR      0x21.0
C:0x00B5    12002E   LCALL    C:002E
C:0x00B8    FF       MOV      R7,A
C:0x00B9    700D   JNZ      C:00C8
C:0x00BB    300705   JNB      0x20.7,C:00C3
C:0x00BE    7F00   MOV      R7,#0x00
C:0x00C0    120071   LCALL    C:0071
C:0x00C3    AF1D   MOV      R7,0x1D
C:0x00C5    AE1C   MOV      R6,0x1C
C:0x00C7    22       RET      
C:0x00C8    B4255F   CJNE   A,#0x25,C:012A
C:0x00CB    C2D5   CLR      F0(0xD0.5)
C:0x00CD    C204   CLR      0x20.4
C:0x00CF    12002E   LCALL    C:002E
C:0x00D2    FF       MOV      R7,A
C:0x00D3    24D0   ADD      A,#PSW(0xD0)
C:0x00D5    B40A00   CJNE   A,#?_PRINTF517?BYTE(0x0A),C:00D8
C:0x00D8    501A   JNC      C:00F4
C:0x00DA    75F00A   MOV      B(0xF0),#?_PRINTF517?BYTE(0x0A)
C:0x00DD    781A   MOV      R0,#0x1A
C:0x00DF    30D505   JNB      F0(0xD0.5),C:00E7
C:0x00E2    08       INC      R0
C:0x00E3    B6FF01   CJNE   @R0,#0xFF,C:00E7
C:0x00E6    06       INC      @R0
C:0x00E7    C6       XCH      A,@R0
C:0x00E8    A4       MUL      AB
C:0x00E9    26       ADD      A,@R0
C:0x00EA    F6       MOV      @R0,A
C:0x00EB    20D504   JB       F0(0xD0.5),C:00F2
C:0x00EE    7002   JNZ      C:00F2
C:0x00F0    D203   SETB   0x20.3
C:0x00F2    80D9   SJMP   C:00CD
C:0x00F4    24CF   ADD      A,#0xCF
C:0x00F6    B41A00   CJNE   A,#0x1A,C:00F9
C:0x00F9    EF       MOV      A,R7
C:0x00FA    5004   JNC      C:0100
C:0x00FC    C2E5   CLR      0xE0.5
C:0x00FE    D204   SETB   0x20.4
C:0x0100    020271   LJMP   C:0271
C:0x0103    D201   SETB   0x20.1
C:0x0105    80C6   SJMP   C:00CD
C:0x0107    D200   SETB   0x20.0
C:0x0109    80C0   SJMP   C:00CB
C:0x010B    D202   SETB   0x20.2
C:0x010D    80BC   SJMP   C:00CB
C:0x010F    D2D5   SETB   F0(0xD0.5)
C:0x0111    80BA   SJMP   C:00CD
C:0x0113    D205   SETB   0x20.5
C:0x0115    80B4   SJMP   C:00CB
C:0x0117    7F20   MOV      R7,#0x20
C:0x0119    120060   LCALL    C:0060
C:0x011C    200207   JB       0x20.2,C:0126
C:0x011F    7401   MOV      A,#0x01
C:0x0121    B51A00   CJNE   A,0x1A,C:0124
C:0x0124    40F1   JC       C:0117
C:0x0126    120025   LCALL    C:0025
C:0x0129    FF       MOV      R7,A
C:0x012A    120060   LCALL    C:0060
C:0x012D    020099   LJMP   C:0099
C:0x0130    D208   SETB   0x21.0
C:0x0132    D206   SETB   0x20.6
C:0x0134    8095   SJMP   C:00CB
C:0x0136    120025   LCALL    C:0025
C:0x0139    FB       MOV      R3,A
C:0x013A    120025   LCALL    C:0025
C:0x013D    FA       MOV      R2,A
C:0x013E    120025   LCALL    C:0025
C:0x0141    F9       MOV      R1,A
C:0x0142    4A       ORL      A,R2
C:0x0143    4B       ORL      A,R3
C:0x0144    7006   JNZ      C:014C
C:0x0146    7942   MOV      R1,#0x42
C:0x0148    7A03   MOV      R2,#0x03
C:0x014A    7BFF   MOV      R3,#0xFF
C:0x014C    20022E   JB       0x20.2,C:017D
C:0x014F    E51A   MOV      A,0x1A
C:0x0151    602A   JZ       C:017D
C:0x0153    7E00   MOV      R6,#0x00
C:0x0155    8E82   MOV      DPL(0x82),R6
C:0x0157    758300   MOV      DPH(0x83),#0x00
C:0x015A    12039A   LCALL    C?CLDOPTR(C:039A)
C:0x015D    6006   JZ       C:0165
C:0x015F    0E       INC      R6
C:0x0160    EE       MOV      A,R6
C:0x0161    651B   XRL      A,0x1B
C:0x0163    70F0   JNZ      C:0155
C:0x0165    C2D5   CLR      F0(0xD0.5)
C:0x0167    EB       MOV      A,R3
C:0x0168    C0E0   PUSH   ACC(0xE0)
C:0x016A    EA       MOV      A,R2
C:0x016B    C0E0   PUSH   ACC(0xE0)
C:0x016D    E9       MOV      A,R1
C:0x016E    C0E0   PUSH   ACC(0xE0)
C:0x0170    EE       MOV      A,R6
C:0x0171    1202B8   LCALL    C:02B8
C:0x0174    D0E0   POP      ACC(0xE0)
C:0x0176    F9       MOV      R1,A
C:0x0177    D0E0   POP      ACC(0xE0)
C:0x0179    FA       MOV      R2,A
C:0x017A    D0E0   POP      ACC(0xE0)
C:0x017C    FB       MOV      R3,A
C:0x017D    120381   LCALL    C?CLDPTR(C:0381)
C:0x0180    FF       MOV      R7,A
C:0x0181    60AA   JZ       C:012D
C:0x0183    EB       MOV      A,R3
C:0x0184    C0E0   PUSH   ACC(0xE0)
C:0x0186    EA       MOV      A,R2
C:0x0187    C0E0   PUSH   ACC(0xE0)
C:0x0189    E9       MOV      A,R1
C:0x018A    C0E0   PUSH   ACC(0xE0)
C:0x018C    120060   LCALL    C:0060
C:0x018F    D0E0   POP      ACC(0xE0)
C:0x0191    2401   ADD      A,#0x01
C:0x0193    F9       MOV      R1,A
C:0x0194    D0E0   POP      ACC(0xE0)
C:0x0196    3400   ADDC   A,#0x00
C:0x0198    FA       MOV      R2,A
C:0x0199    D0E0   POP      ACC(0xE0)
C:0x019B    FB       MOV      R3,A
C:0x019C    E51B   MOV      A,0x1B
C:0x019E    04       INC      A
C:0x019F    60DC   JZ       C:017D
C:0x01A1    D51BD9   DJNZ   0x1B,C:017D
C:0x01A4    8087   SJMP   C:012D
C:0x01A6    7BFF   MOV      R3,#0xFF
C:0x01A8    7A02   MOV      R2,#0x02
C:0x01AA    79B4   MOV      R1,#0xB4
C:0x01AC    D202   SETB   0x20.2
C:0x01AE    809C   SJMP   C:014C
C:0x01B0    7910   MOV      R1,#0x10
C:0x01B2    8002   SJMP   C:01B6
C:0x01B4    7908   MOV      R1,#0x08
C:0x01B6    C206   CLR      0x20.6
C:0x01B8    C208   CLR      0x21.0
C:0x01BA    8008   SJMP   C:01C4
C:0x01BC    D2D5   SETB   F0(0xD0.5)
C:0x01BE    790A   MOV      R1,#?_PRINTF517?BYTE(0x0A)
C:0x01C0    8004   SJMP   C:01C6
C:0x01C2    790A   MOV      R1,#?_PRINTF517?BYTE(0x0A)
C:0x01C4    C2D5   CLR      F0(0xD0.5)
C:0x01C6    E51B   MOV      A,0x1B
C:0x01C8    04       INC      A
C:0x01C9    7002   JNZ      C:01CD
C:0x01CB    F51B   MOV      0x1B,A
C:0x01CD    E4       CLR      A
C:0x01CE    FA       MOV      R2,A
C:0x01CF    FD       MOV      R5,A
C:0x01D0    FE       MOV      R6,A
C:0x01D1    FF       MOV      R7,A
C:0x01D2    120025   LCALL    C:0025
C:0x01D5    FC       MOV      R4,A
C:0x01D6    7B08   MOV      R3,#0x08
C:0x01D8    200113   JB       0x20.1,C:01EE
C:0x01DB    120025   LCALL    C:0025
C:0x01DE    FD       MOV      R5,A
C:0x01DF    7B10   MOV      R3,#0x10
C:0x01E1    30000A   JNB      0x20.0,C:01EE
C:0x01E4    120025   LCALL    C:0025
C:0x01E7    FE       MOV      R6,A
C:0x01E8    120025   LCALL    C:0025
C:0x01EB    FF       MOV      R7,A
C:0x01EC    7B20   MOV      R3,#0x20
C:0x01EE    EC       MOV      A,R4
C:0x01EF    33       RLC      A
C:0x01F0    82D5   ANL      C,F0(0xD0.5)
C:0x01F2    92D5   MOV      F0(0xD0.5),C
C:0x01F4    5013   JNC      C:0209
C:0x01F6    C3       CLR      C
C:0x01F7    E4       CLR      A
C:0x01F8    300006   JNB      0x20.0,C:0201
C:0x01FB    9F       SUBB   A,R7
C:0x01FC    FF       MOV      R7,A
C:0x01FD    E4       CLR      A
C:0x01FE    9E       SUBB   A,R6
C:0x01FF    FE       MOV      R6,A
C:0x0200    E4       CLR      A
C:0x0201    200103   JB       0x20.1,C:0207
C:0x0204    9D       SUBB   A,R5
C:0x0205    FD       MOV      R5,A
C:0x0206    E4       CLR      A
C:0x0207    9C       SUBB   A,R4
C:0x0208    FC       MOV      R4,A
C:0x0209    E4       CLR      A
C:0x020A    CB       XCH      A,R3
C:0x020B    F8       MOV      R0,A
C:0x020C    C201   CLR      0x20.1
C:0x020E    EC       MOV      A,R4
C:0x020F    700C   JNZ      C:021D
C:0x0211    CF       XCH      A,R7
C:0x0212    CE       XCH      A,R6
C:0x0213    CD       XCH      A,R5
C:0x0214    CC       XCH      A,R4
C:0x0215    E8       MOV      A,R0
C:0x0216    24F8   ADD      A,#0xF8
C:0x0218    F8       MOV      R0,A
C:0x0219    70F3   JNZ      C:020E
C:0x021B    8017   SJMP   C:0234
C:0x021D    C3       CLR      C
C:0x021E    EF       MOV      A,R7
C:0x021F    33       RLC      A
C:0x0220    FF       MOV      R7,A
C:0x0221    EE       MOV      A,R6
C:0x0222    33       RLC      A
C:0x0223    FE       MOV      R6,A
C:0x0224    ED       MOV      A,R5
C:0x0225    33       RLC      A
C:0x0226    FD       MOV      R5,A
C:0x0227    EC       MOV      A,R4
C:0x0228    33       RLC      A
C:0x0229    FC       MOV      R4,A
C:0x022A    EB       MOV      A,R3
C:0x022B    33       RLC      A
C:0x022C    FB       MOV      R3,A
C:0x022D    99       SUBB   A,R1
C:0x022E    4002   JC       C:0232
C:0x0230    FB       MOV      R3,A
C:0x0231    0F       INC      R7
C:0x0232    D8E9   DJNZ   R0,C:021D
C:0x0234    EB       MOV      A,R3
C:0x0235    300105   JNB      0x20.1,C:023D
C:0x0238    F8       MOV      R0,A
C:0x0239    D0E0   POP      ACC(0xE0)
C:0x023B    C4       SWAP   A
C:0x023C    48       ORL      A,R0
C:0x023D    B201   CPL      0x20.1
C:0x023F    C0E0   PUSH   ACC(0xE0)
C:0x0241    0A       INC      R2
C:0x0242    EC       MOV      A,R4
C:0x0243    4D       ORL      A,R5
C:0x0244    4E       ORL      A,R6
C:0x0245    4F       ORL      A,R7
C:0x0246    7820   MOV      R0,#0x20
C:0x0248    7B00   MOV      R3,#0x00
C:0x024A    70C2   JNZ      C:020E
C:0x024C    EA       MOV      A,R2
C:0x024D    B51B00   CJNE   A,0x1B,C:0250
C:0x0250    40BC   JC       C:020E
C:0x0252    C0E0   PUSH   ACC(0xE0)
C:0x0254    1202BA   LCALL    C:02BA
C:0x0257    D0F0   POP      B(0xF0)
C:0x0259    D0E0   POP      ACC(0xE0)
C:0x025B    200104   JB       0x20.1,C:0262
C:0x025E    C4       SWAP   A
C:0x025F    C0E0   PUSH   ACC(0xE0)
C:0x0261    C4       SWAP   A
C:0x0262    B201   CPL      0x20.1
C:0x0264    C0F0   PUSH   B(0xF0)
C:0x0266    120049   LCALL    C:0049
C:0x0269    D0F0   POP      B(0xF0)
C:0x026B    D5F0EB   DJNZ   B(0xF0),C:0259
C:0x026E    020099   LJMP   C:0099
C:0x0271    1203E9   LCALL    C?CCASE(C:03E9)
C:0x0274    0136   AJMP   C:0036
C:0x0276    5301B0   ANL      0x01,#P3(0xB0)
C:0x0279    58       ANL      A,R0
C:0x027A    0107   AJMP   C:0007
C:0x027C    4C       ORL      A,R4
C:0x027D    0103   AJMP   C:0003
C:0x027F    4201   ORL      0x01,A
C:0x0281    B44F01   CJNE   A,#0x4F,C:0285
C:0x0284    BC4401   CJNE   R4,#0x44,C:0288
C:0x0287    BC4901   CJNE   R4,#0x49,C:028B
C:0x028A    1C       DEC      R4
C:0x028B    4301C2   ORL      0x01,#0xC2
C:0x028E    5501   ANL      A,0x01
C:0x0290    A646   MOV      @R0,0x46
C:0x0292    01A6   AJMP   C:00A6
C:0x0294    4501   ORL      A,0x01
C:0x0296    A647   MOV      @R0,0x47
C:0x0298    03       RR       A
C:0x0299    6250   XRL      0x50,A
C:0x029B    010B   AJMP   C:000B
C:0x029D    2D       ADD      A,R5
C:0x029E    010F   AJMP   C:000F
C:0x02A0    2E       ADD      A,R6
C:0x02A1    0132   AJMP   C:0032
C:0x02A3    2B       ADD      A,R3
C:0x02A4    0113   AJMP   C:0013
C:0x02A6    23       RL       A
C:0x02A7    0130   AJMP   C:0030
C:0x02A9    20034B   JB       0x20.3,C:02F7
C:0x02AC    2A       ADD      A,R2
C:0x02AD    00       NOP      
C:0x02AE    CB       XCH      A,R3
C:0x02AF    48       ORL      A,R0
C:0x02B0    00       NOP      
C:0x02B1    00       NOP      
C:0x02B2    012A   AJMP   C:002A
C:0x02B4    3F       ADDC   A,R7
C:0x02B5    3F       ADDC   A,R7
C:0x02B6    3F       ADDC   A,R7
C:0x02B7    00       NOP      
C:0x02B8    790A   MOV      R1,#?_PRINTF517?BYTE(0x0A)
C:0x02BA    A2D5   MOV      C,F0(0xD0.5)
C:0x02BC    200314   JB       0x20.3,C:02D3
C:0x02BF    300509   JNB      0x20.5,C:02CB
C:0x02C2    B91002   CJNE   R1,#0x10,C:02C7
C:0x02C5    04       INC      A
C:0x02C6    04       INC      A
C:0x02C7    B90801   CJNE   R1,#0x08,C:02CB
C:0x02CA    04       INC      A
C:0x02CB    A2D5   MOV      C,F0(0xD0.5)
C:0x02CD    200602   JB       0x20.6,C:02D2
C:0x02D0    5001   JNC      C:02D3
C:0x02D2    04       INC      A
C:0x02D3    200268   JB       0x20.2,C:033E
C:0x02D6    9202   MOV      0x20.2,C
C:0x02D8    B51A00   CJNE   A,0x1A,C:02DB
C:0x02DB    5034   JNC      C:0311
C:0x02DD    C0E0   PUSH   ACC(0xE0)
C:0x02DF    7F20   MOV      R7,#0x20
C:0x02E1    300319   JNB      0x20.3,C:02FD
C:0x02E4    7F30   MOV      R7,#0x30
C:0x02E6    A202   MOV      C,0x20.2
C:0x02E8    7206   ORL      C,0x20.6
C:0x02EA    7205   ORL      C,0x20.5
C:0x02EC    500F   JNC      C:02FD
C:0x02EE    120311   LCALL    C:0311
C:0x02F1    C202   CLR      0x20.2
C:0x02F3    C206   CLR      0x20.6
C:0x02F5    C205   CLR      0x20.5
C:0x02F7    C208   CLR      0x21.0
C:0x02F9    7F30   MOV      R7,#0x30
C:0x02FB    800F   SJMP   C:030C
C:0x02FD    300503   JNB      0x20.5,C:0303
C:0x0300    E9       MOV      A,R1
C:0x0301    C0E0   PUSH   ACC(0xE0)
C:0x0303    120060   LCALL    C:0060
C:0x0306    300503   JNB      0x20.5,C:030C
C:0x0309    D0E0   POP      ACC(0xE0)
C:0x030B    F9       MOV      R1,A
C:0x030C    D0E0   POP      ACC(0xE0)
C:0x030E    B51ACC   CJNE   A,0x1A,C:02DD
C:0x0311    300517   JNB      0x20.5,C:032B
C:0x0314    7F30   MOV      R7,#0x30
C:0x0316    B9100C   CJNE   R1,#0x10,C:0325
C:0x0319    120060   LCALL    C:0060
C:0x031C    7F58   MOV      R7,#0x58
C:0x031E    300407   JNB      0x20.4,C:0328
C:0x0321    7F78   MOV      R7,#0x78
C:0x0323    8003   SJMP   C:0328
C:0x0325    B90803   CJNE   R1,#0x08,C:032B
C:0x0328    120060   LCALL    C:0060
C:0x032B    300205   JNB      0x20.2,C:0333
C:0x032E    7F2D   MOV      R7,#0x2D
C:0x0330    020060   LJMP   C:0060
C:0x0333    7F20   MOV      R7,#0x20
C:0x0335    2008F8   JB       0x21.0,C:0330
C:0x0338    7F2B   MOV      R7,#0x2B
C:0x033A    2006F3   JB       0x20.6,C:0330
C:0x033D    22       RET      
C:0x033E    9202   MOV      0x20.2,C
C:0x0340    80CF   SJMP   C:0311
C:0x0342    28       ADD      A,R0
C:0x0343    6E       XRL      A,R6
C:0x0344    756C6C   MOV      0x6C,#0x6C
C:0x0347    29       ADD      A,R1
C:0x0348    00       NOP      
C:0x0349    D201   SETB   0x20.1
C:0x034B    120025   LCALL    C:0025
C:0x034E    3001F8   JNB      0x20.1,C:0349
C:0x0351    C201   CLR      0x20.1
C:0x0353    781A   MOV      R0,#0x1A
C:0x0355    30D501   JNB      F0(0xD0.5),C:0359
C:0x0358    08       INC      R0
C:0x0359    F6       MOV      @R0,A
C:0x035A    0200CB   LJMP   C:00CB
C:0x035D    2D       ADD      A,R5
C:0x035E    5043   JNC      C:03A3
C:0x0360    49       ORL      A,R1
C:0x0361    58       ANL      A,R0
C:0x0362    120025   LCALL    C:0025
C:0x0365    2403   ADD      A,#0x03
C:0x0367    B40500   CJNE   A,#0x05,C:036A
C:0x036A    4001   JC       C:036D
C:0x036C    E4       CLR      A
C:0x036D    90035D   MOV      DPTR,#0x035D
C:0x0370    93       MOVC   A,@A+DPTR
C:0x0371    120051   LCALL    C:0051
C:0x0374    743A   MOV      A,#0x3A
C:0x0376    120051   LCALL    C:0051
C:0x0379    D203   SETB   0x20.3
C:0x037B    751A04   MOV      0x1A,#0x04
C:0x037E    0201B0   LJMP   C:01B0
C:0x0381    BB0106   CJNE   R3,#0x01,C:038A
C:0x0384    8982   MOV      DPL(0x82),R1
C:0x0386    8A83   MOV      DPH(0x83),R2
C:0x0388    E0       MOVX   A,@DPTR
C:0x0389    22       RET      
C:0x038A    5002   JNC      C:038E
C:0x038C    E7       MOV      A,@R1
C:0x038D    22       RET      
C:0x038E    BBFE02   CJNE   R3,#0xFE,C:0393
C:0x0391    E3       MOVX   A,@R1
C:0x0392    22       RET      
C:0x0393    8982   MOV      DPL(0x82),R1
C:0x0395    8A83   MOV      DPH(0x83),R2
C:0x0397    E4       CLR      A
C:0x0398    93       MOVC   A,@A+DPTR
C:0x0399    22       RET      
C:0x039A    BB010C   CJNE   R3,#0x01,C:03A9
C:0x039D    E582   MOV      A,DPL(0x82)
C:0x039F    29       ADD      A,R1
C:0x03A0    F582   MOV      DPL(0x82),A
C:0x03A2    E583   MOV      A,DPH(0x83)
C:0x03A4    3A       ADDC   A,R2
C:0x03A5    F583   MOV      DPH(0x83),A
C:0x03A7    E0       MOVX   A,@DPTR
C:0x03A8    22       RET      
C:0x03A9    5006   JNC      C:03B1
C:0x03AB    E9       MOV      A,R1
C:0x03AC    2582   ADD      A,DPL(0x82)
C:0x03AE    F8       MOV      R0,A
C:0x03AF    E6       MOV      A,@R0
C:0x03B0    22       RET      
C:0x03B1    BBFE06   CJNE   R3,#0xFE,C:03BA
C:0x03B4    E9       MOV      A,R1
C:0x03B5    2582   ADD      A,DPL(0x82)
C:0x03B7    F8       MOV      R0,A
C:0x03B8    E2       MOVX   A,@R0
C:0x03B9    22       RET      
C:0x03BA    E582   MOV      A,DPL(0x82)
C:0x03BC    29       ADD      A,R1
C:0x03BD    F582   MOV      DPL(0x82),A
C:0x03BF    E583   MOV      A,DPH(0x83)
C:0x03C1    3A       ADDC   A,R2
C:0x03C2    F583   MOV      DPH(0x83),A
C:0x03C4    E4       CLR      A
C:0x03C5    93       MOVC   A,@A+DPTR
C:0x03C6    22       RET      
C:0x03C7    BB0106   CJNE   R3,#0x01,C:03D0
C:0x03CA    8982   MOV      DPL(0x82),R1
C:0x03CC    8A83   MOV      DPH(0x83),R2
C:0x03CE    F0       MOVX   @DPTR,A
C:0x03CF    22       RET      
C:0x03D0    5002   JNC      C:03D4
C:0x03D2    F7       MOV      @R1,A
C:0x03D3    22       RET      
C:0x03D4    BBFE01   CJNE   R3,#0xFE,C:03D8
C:0x03D7    F3       MOVX   @R1,A
C:0x03D8    22       RET      
C:0x03D9    FA       MOV      R2,A
C:0x03DA    E6       MOV      A,@R0
C:0x03DB    FB       MOV      R3,A
C:0x03DC    08       INC      R0
C:0x03DD    08       INC      R0
C:0x03DE    E6       MOV      A,@R0
C:0x03DF    F9       MOV      R1,A
C:0x03E0    25F0   ADD      A,B(0xF0)
C:0x03E2    F6       MOV      @R0,A
C:0x03E3    18       DEC      R0
C:0x03E4    E6       MOV      A,@R0
C:0x03E5    CA       XCH      A,R2
C:0x03E6    3A       ADDC   A,R2
C:0x03E7    F6       MOV      @R0,A
C:0x03E8    22       RET      
C:0x03E9    D083   POP      DPH(0x83)
C:0x03EB    D082   POP      DPL(0x82)
C:0x03ED    F8       MOV      R0,A
C:0x03EE    E4       CLR      A
C:0x03EF    93       MOVC   A,@A+DPTR
C:0x03F0    7012   JNZ      C:0404
C:0x03F2    7401   MOV      A,#0x01
C:0x03F4    93       MOVC   A,@A+DPTR
C:0x03F5    700D   JNZ      C:0404
C:0x03F7    A3       INC      DPTR
C:0x03F8    A3       INC      DPTR
C:0x03F9    93       MOVC   A,@A+DPTR
C:0x03FA    F8       MOV      R0,A
C:0x03FB    7401   MOV      A,#0x01
C:0x03FD    93       MOVC   A,@A+DPTR
C:0x03FE    F582   MOV      DPL(0x82),A
C:0x0400    8883   MOV      DPH(0x83),R0
C:0x0402    E4       CLR      A
C:0x0403    73       JMP      @A+DPTR
C:0x0404    7402   MOV      A,#0x02
C:0x0406    93       MOVC   A,@A+DPTR
C:0x0407    68       XRL      A,R0
C:0x0408    60EF   JZ       C:03F9
C:0x040A    A3       INC      DPTR
C:0x040B    A3       INC      DPTR
C:0x040C    A3       INC      DPTR
C:0x040D    80DF   SJMP   C:03EE
C:0x040F    EF       MOV      A,R7
C:0x0410    B40A07   CJNE   A,#?_PRINTF517?BYTE(0x0A),C:041A
C:0x0413    740D   MOV      A,#0x0D
C:0x0415    12041A   LCALL    C:041A
C:0x0418    740A   MOV      A,#?_PRINTF517?BYTE(0x0A)
C:0x041A    309811   JNB      RI(0x98.0),C:042E
C:0x041D    A899   MOV      R0,SBUF(0x99)
C:0x041F    B8130C   CJNE   R0,#0x13,C:042E
C:0x0422    C298   CLR      RI(0x98.0)
C:0x0424    3098FD   JNB      RI(0x98.0),C:0424
C:0x0427    A899   MOV      R0,SBUF(0x99)
C:0x0429    C298   CLR      RI(0x98.0)
C:0x042B    B811F6   CJNE   R0,#0x11,C:0424
C:0x042E    3099FD   JNB      TI(0x98.1),C:042E
C:0x0431    C299   CLR      TI(0x98.1)
C:0x0433    F599   MOV      SBUF(0x99),A
C:0x0435    22       RET

shamork 发表于 2009-9-17 15:16:42

转自大虾网 http://www.daxia.com/list_1683.shtml

有一个矛盾总是在困扰我们---那就是计算机喜欢2进制(16进制)而人类已经习惯了10进制
传统的HEX--BCD通常都按二进制定义按权展开,再付以10进制调整来实现,速度太慢,效率低
我的思路是这样的2的12次方=4096=4100-4=1000H及每一个1000H可以看着"4100"如果有误
差可以从余数中扣除,如双字节数最多扣除16*4=64个,如果有余数,够扣就扣,不够扣从4100
个中次高位减一当100已经够了!如果你问16是怎么来得我告诉65536/4096=16下面是程序
DPTR中是待转换的双字节16进制数,转换的数据保存在34H33H32H31H30H五个连续单元中34H
为高,同样的道理把100=60H+4    4096/96最多商42   4*42=168
16=4096/256 64和128因为都是单字节所以运算非常简单,经过仿真对比其运行速度比传统
方式快12倍!!!!!!!
       HEXBCD:MOV A,DPH   ;16进制高位送A
            ANL A,#0F0H;屏蔽A低四位
            XRL DPH,A    ;屏蔽DPH高四位
            SWAP A       ;A除以16 ( 注意这技巧)
            MOV 32H,A    ;把A个100放百位单元
            RL A
            RL A         ;两次RL A相当于乘以4,这个4表示4A个千,也表示要扣除4A
             ;A*4096=A*(4000+100)-4A=4A*1000+A*100-4A
            XCH A,DPL
            SUBB A,DPL
            XCH A,DPH
            SUBB A,#00H;以上四条指令完成4A的扣除,结果高位在A,低位在DPH
            JNC   "够扣"
            DEC 32H ;不够扣32H减一当百
            MOV A,#101 ;本来是100这里用101是考虑C=1这样就节省一条指令CLR C
            SUBB A,DPL
            ADD A,DPH;A肯定小于64为什么?所以高位不计算了!
            MOV B,#10
            DIV AB
            MOV 31H,A
            MOV 30H,B
            ;以下的程序留给大家自己编写,按时叫作业哦社员们

yuxin51 发表于 2009-9-17 15:42:09

5楼的思路有意思,不过本人现在基本不用纯汇编折腾了,隔几天再回头看自己写的汇编代码都觉得晕……至于printf,我也是能不用就不用。

zzwuyu 发表于 2009-9-17 15:53:12

5楼的兄弟提供了一个不错的思路,谢谢了。

shamork 发表于 2009-9-17 16:02:10

5楼的思路不是问题,关键是如何整理出来,让我们这些习惯了C的人们能够方便的用上。

shamork 发表于 2009-9-17 17:06:37

5楼的思路不是问题,关键是如何整理出来,让我们这些习惯了C的人们能够方便的用上。

cowboy 发表于 2009-9-17 17:37:08

经过仿真对比其运行速度比传统方式快12倍!!!!!!!
===============================================
快12倍表示有多快?能在100us内完成吗?(以标准12T的51运行于12MHz来算)

shamork 发表于 2009-9-21 16:52:24

新思路:人类算法 51适用
万位 千位 百位 十位 个位
            2   5   6
+         2   5   6
------------------------------
             12    30   36
+      10    25    30
4    10    12
------------------------------
4    20    49    60   36
+               3<-36->6
------------------------------
4    20    49    63   6
+            6<-63->3
------------------------------
4    20    55   3   6
+       5<-55->5
------------------------------
4    25   5   3   6
+ 2<-25->5
------------------------------
6   5   5   3   6

----------------------------------------------------------------------------
我不会汇编,所以只能写个类汇编出来了。等高手来改写优化。这个用在12MHz S51上,123周期(仅计算,没测)
WW EQU 30H;万位
QW EQU 31H;千位
BW EQU 32H;百位
SW EQU 33H;十位
GW EQU 34H;个位

MOV DPH,#FFH
MOV DPL,#FFH

;将DPH(ff)变成2.5.6
MOV A ,DPH
MOV B ,#100
DIV AB
MOV R0,A
MOV A,B;余数放A继续/10
MOV B,#10
DIV AB
MOV R1,A
MOV R2,B
;将DPL(ff)变成2.5.6
MOV A,DPL
MOV B,#100
DIV AB
MOV R3,A
MOV A,B
MOV B,#10
DIV AB
MOV R4,A
MOV R5,B

;开乘了256*6--6*6
MOV A,R5
MOV B,R2
MUL AB
MOV GW,A
;5*6
MOV A,R5
MOV B,R1;
MUL AB
MOV SW,A
;2*6
MOV A,R5
MOV B,R0
MUL AB
MOV BW,A
;256*5--6*5
MOV A,R4
MOV B,R2
MUL AB
ADD SW,A
;5*5
MOV A,R4
MOV B,R1
MUL AB
ADD BW,A
;2*5
MOV A,R4
MOV B,R0
MUL AB
MOV QW,A
;256*2---6*2
MOV A,R3
MOV B,R2
MUL AB
ADD BW,A
;5*2
MOV A,R3
MOV B,R1
MUL AB
ADD QW,A
;2*2
MOV A,R3
MOV B,R0
MUL AB
MOV WW,A
;开始合并--36/10=3(+QW) 余6(GW)
MOV A,GW
MOV B,#10
DIV AB
ADD SW,A
MOV GW,B
;sw
MOV A,SW
MOV B,#10
DIV AB
ADD BW,A
MOV SW,B
;bw
MOV A,BW
MOV B,#10
DIV AB
ADD QW,A
MOV BW,B
;qw ww
MOV A,QW
MOV B,#10
DIV AB
ADD WW,A
MOV QW,B

cowboy 发表于 2009-9-21 18:27:14

思路错了。0xabcd != 0xab * 0xcd

shamork 发表于 2009-9-21 18:49:55

0xab=171
0xcd=205
0xabcd=43981
171*205=35055
是错了呢。高手就是高手。
那就只能DPH*256+DPL了

shamork 发表于 2009-9-21 18:53:30

顺便问下cowboy你在另个贴中说的汇编<60us的算法是什么?能不能贴出来改造下方便C调用?

cowboy 发表于 2009-9-21 20:06:43

号称世上最快的16bit二进制数转5位压缩BCD码的程序,最长56周期(标准51)。原理还没弄懂。
原作者:DENGM
;R2R3-->R5R6R7 小端
BIN2BCD:
       MOVA, R3      
       ANLA, #0FCH
       RR   A
       RR   A
       MOVR5,A
       ADDA, R5
       ADDA, R5
       MOVR7,A
       MOVA, R2
       ANLA, #3
       MOVR6,A
       XRLA, R3
       ANLA, #3
       XRLA, R2
       RR   A
       RR   A
       ADDA, R7
       JNCL2
       INCR5
       ADDA, #6
L2:    ADDA, R7
       MOVB, #25
       JNCL3
       INCR5
       ADDA, #6
       DIVAB
       SJMP L4
L3:    DIVAB
       CJNE A, #10, L4
       INCR5
       CLRA
L4:    MOVR7,A
       MOVA, #10
       XCHA, B
       ADDA, #(L5-$-3)
       MOVC A, @A+PC
       ADDA, R6
       DA   A
       XCHA, R5
       DIVAB
       XCHA, R7
       SWAP A
       ORLA, B
       SWAP A
       MOVR6,A
       RET
   
L5:    DB 00H, 04H, 08H, 12H, 16H
       DB 20H, 24H, 28H, 32H, 36H
       DB 40H, 44H, 48H, 52H, 56H
       DB 60H, 64H, 68H, 72H, 76H
       DB 80H, 84H, 88H, 92H, 96H
       END

yaya001 发表于 2009-9-21 23:38:13

mark

shamork 发表于 2009-9-23 19:21:27

能不能改造下方便C调用啊,做成库?

shamork 发表于 2009-9-23 19:39:04

无法验证正确性
http://cache.amobbs.com/bbs_upload782111/files_18/ourdev_484599.jpg
R2=0x12 R3=0x34 测试 (原文件名:QQ截图未命名.jpg)

cowboy 发表于 2009-9-23 20:27:55

0x34 12 = 1 33 30
r3 r2r7 r6 r5

nicksean 发表于 2009-9-23 22:09:22

mark

boy364100 发表于 2009-11-30 08:38:44

强~~~正在验证~~~

jlian168 发表于 2013-7-14 10:26:01

wolf11_1234 发表于 2009-9-17 14:19 static/image/common/back.gif
你的hex2bcd太臃肿了
用keil自带的库,反汇编回来看看

SIR:

WHERE IS THE "keil自带的库"?

THANKS.

leahcim89 发表于 2013-7-20 23:25:16

懂了,下来看看。
页: [1]
查看完整版本: Hex2BCD再讨论——由自写printf引出的另类Hex2BCD算法