|
发表于 2010-4-24 22:27:04
|
显示全部楼层
帖一个我做的库:
NAME LONG2BCD
?PR?_long2bcd?LONG2BCD SEGMENT CODE INBLOCK
PUBLIC _long2bcd
; void long2bcd(unsigned long l, unsigned char * p)
RSEG ?PR?_long2bcd?LONG2BCD
_long2bcd:
MOV R3, #0x05
CLR A
?C0001: MOV @R1, A
INC R1
DJNZ R3, ?C0001
MOV A, #0x08
MOV R2, A
?C0002: XCH A, R4
RLC A
XCH A, R4
MOV R3, #0x02
?C0003: DEC R1
XCH A, @R1
RLC A
MOV 0xD5, C ;PSW.5,F0
ADD A, #0x33
JB 0xE3, ?C0004 ;ACC.3
ADD A, #(-3)
?C0004: JB 0xE7, ?C0005 ;ACC.7
ADD A, #(-48)
?C0005: MOV C, 0xD5 ;PSW.5,F0
XCH A, @R1
DJNZ R3, ?C0003
INC R1
INC R1
DJNZ R2, ?C0002
MOV R2, A
?C0006: XCH A, R5
RLC A
XCH A, R5
MOV R3, #0x03
?C0007: DEC R1
XCH A, @R1
RLC A
MOV 0xD5, C
ADD A, #0x33
JB 0xE3, ?C0008
ADD A, #(-3)
?C0008: JB 0xE7, ?C0009
ADD A, #(-48)
?C0009: MOV C, 0xD5
XCH A, @R1
DJNZ R3, ?C0007
INC R1
INC R1
INC R1
DJNZ R2, ?C0006
MOV R2, A
?C000A: XCH A, R6
RLC A
XCH A, R6
MOV R3, #0x04
?C000B: DEC R1
XCH A, @R1
RLC A
MOV 0xD5, C
ADD A, #0x33
JB 0xE3, ?C000C
ADD A, #(-3)
?C000C: JB 0xE7, ?C000D
ADD A, #(-48)
?C000D: MOV C, 0xD5
XCH A, @R1
DJNZ R3, ?C000B
INC R1
INC R1
INC R1
INC R1
DJNZ R2, ?C000A
MOV R2, A
?C000E: XCH A, R7
RLC A
XCH A, R7
MOV R3, #0x05
?C000F: DEC R1
XCH A, @R1
RLC A
MOV 0xD5, C
CJNE R2, #1, ?C0010
SJMP ?C0012
?C0010: ADD A, #0x33
JB 0xE3, ?C0011
ADD A, #(-3)
?C0011: JB 0xE7, ?C0012
ADD A, #(-48)
?C0012: MOV C, 0xD5
XCH A, @R1
DJNZ R3, ?C000F
INC R1
INC R1
INC R1
INC R1
INC R1
DJNZ R2, ?C000E
RET
END
所用算法的流程图 (原文件名:hex2bcd.JPG)
C语言的调用接口已在程序中以注释的方式给出,需要注意的是,程序需要传递一个通用指针进去,但函数内部的代码实际上只能处理该指针为“unsigned char data *”的形式,也就是说,存储BCD码结果的数组只能在DATA区。结果为压缩BCD码,存于传进来的指针所指的5个元素的数组。
附上库文件工程包、测试工程包:
生成.LIB库文件的工程包ourdev_549026.rar(文件大小:5K) (原文件名:long2bcd.rar)
功能测试及、与除法及取模运算方式对比的工程包ourdev_549027.rar(文件大小:7K) (原文件名:temp.rar)
在标准51架构上,该函数使用2174周期、而作为对比的除法/取模方式要用4700周期。
本想使用div/ldiv库来改善除法/取模方式的效率,结果查阅Keil的帮助才发现,Keil C不支持这两个ANSI-C的库,看样子有必要自己写一个。 |
|