谁还记得MCS-96单片机?放一个汇编库 MCS-96(196) 五字节浮点库及其使用说明
90年代的16位单片机,现在也进入历史的长河中了。放个汇编库在这里,不再丢失。MCS-96(196) 五字节浮点库及其使用说明
MCS-96传统的浮点库(包括IEEE标准)全部是四字节,而MCS-96单片机的指令系统有它的特殊性,采用五字节的浮点库,更能提高程序的运行速度和效率。
此浮点库包含7个子程序(数值转换、四则运算、浮点数处理等),不含函数库。
占RAM (1Ah ~2FH);大小:1。5K,可任意浮动。
为便于读者使用本程序库,先将有关约定说明如下:
浮点数的格式(5字节):
数符(1)阶码(7) 。尾数高字节(H)尾数中字节(M1,M2)尾数低字节(L)
1.四字节定点操作数:用或来表示存放在由CX或DX指示的连续单元中的数据,地址小的单元存放高字节。如果=12345678H,若(CX)=30H,则(30H)=12H,(31H)=34H,(32)=56h,(33H)=78H。
2.二进制浮点操作数:用五个字节表示,第一个字节的最高位为数符,其余七位为阶码(补码形式),第二字节为尾数的高字节(H),第三字节为尾数的中字节(M1),第三字节为尾数的中字节(M2),第四字节为尾数的低字节(L)。尾数用四字节纯小数(原码)来表示(32位二进制)。当尾数的最高位为1时,便称为规格化浮点数,简称操作数。在程序说明中,也用或来表示CX或DX指示的浮点操作数。
例如:
A、0。8则:=00 80 00 00 00,则二进制浮点数表示为00 CC CC CC CDH。若(CX)=30H,则(30H)=00H,(31H)=0CCH,(32H)=0CCH, (33H)=0CCH (34H)=0CDH。
B、-0。8则:=80 80 00 00,则二进制浮点数表示为80 CC CC CC CDH。若(CX)=30H,则(30H)=80H,(31H)=0CCH,(32H)=0CCH, (33H)=0CCH ,(34H)=0CDH。
3.十进制浮点操作数:用五个字节表示,第一个字节的最高位为数符,其余七位为阶码(二进制补码形式),第二字节为尾数的高字节(H),第三字节为尾数的中字节(M1),第四字节为尾数的中字节(M2),第五字节为尾数的低字节(L)。尾数用双字节BCD码纯小数(原码)来表示。当十进制数的绝对值大于1时,阶码就等于整数部分的位数,如 123.4 的阶码是03H,-123.4 的阶码是 83H;当十进制数的绝对值小于1时,阶码就等于 80H 减去小数点后面零的个数,例如 0.00123 的阶码是 7EH,-0.00123的阶码是 0FEH。在程序说明中,用或来表示CX或DX指示的十进制浮点操作数。例如有一个十进制浮点操作数存放在30H、31H、32H、33H、34H中,数值是 -0.012345678,即-0.12345678乘以10的-1次方,则(30H)=0FFH,31H=12H,(32H)=34H,(33H)=56H,(34H)=78H。若用来指向它,则应使(CX)=30H。
4.运算精度:单次定点运算精度为结果最低位的当量值;单次二进制浮点算术运算的精度优于1/2^32;BCD码浮点数的精度亿万分之一(8位有效数),不作为运算的操作数,仅用于输入或输出时的数制转换。不管那种数据格式,随着连续运算的次数增加,精度都会下降。
5.工作区:数据工作区固定在1AH~2FH。堆栈占用最大2个字。
用户请不要在工作区中存放信息!
6.数值转换子程的执行时间(12MHz;与数据大小无关):1。2mS
四则运算的执行时间:0。6~1。2mS
7.子程序调用范例:由于本程序库特别注意了各子程序接口的相容性,很容易采用
积木方式完成一个公式的计算。以浮点运算为例:
计算 y = ab/c+d
已知:a=-123.45678;b=0.75771234;c=56.341234;d=1.2762356; 它们分别存放在30H开始的连续单元中。用BCD码浮点数表示时,分别为a=8312345678H;b=0075771234H;c=0256341234H;d=0112762356H。
求解过程:通过调用BTOF子程序,将各变量转换成二进制浮点操作数,再进行各种运算,最后调用FTOB子程序,还原成十进制形式,供输出使用。程序如下:
TEST:
LD CX,#3FH ;指向BCD码浮点操作数d
CALL BTOF ;将其转换成二进制浮点操作数
LD CX,#3AH ;指向BCD码浮点操作数c
CALL BTOF ;将其转换成二进制浮点操作数
LD CX,#35H ;指向BCD码浮点操作数b
CALL BTOF ;将其转换成二进制浮点操作数
LD CX,#30H ;指向BCD码浮点操作数a
CALL BTOF ;将其转换成二进制浮点操作数
LD DX,#34H ;指向二进制浮点操作数b
CALL FMUL ;进行浮点乘法运算
LD DX,#3AH ;指向二进制浮点操作数c
CALL FDIV ;进行浮点除法运算
LD DX,#3FH ;指向二进制浮点操作数d
CALL FADD ;进行浮点加法运算
CALL FTOB ;将结果转换成BCD码浮点数
STOP: LJMP STOP
END
运行结果,=8038408880H,即y=-0.38408880,比较精确的结果应该是-0.384088802。
程序清单:
(1) 标号: FDIV 功能:浮点数除法
入口条件:被除数在中,除数在中。
出口信息:商仍在中
fdiv:
push cx
ld 2eh,cx
ld 2ch,dx
call mvCX
call mvDX ;read data for dx,cx,
xorb 26h,27h
;*** jb zer
ld 28h,ax
or 28h,bx
jne fdiv0
call movzer
jmp mov0
fdiv0:
ld 28h,dx
or 28h,cx
jne fdiv1
ld 1ah,#3fh
jmp mov0
fdiv1:
call div3
jmp mov0
(2) 标号: FMUL 功能:浮点数乘法
入口条件:被乘数在中,乘数在中。
出口信息:积仍在中
fmul:
push cx
ld 2eh,cx
ld 2ch,dx
call mvCX
call mvDX ;read data for dx,cx,
xorb 26h,27h
call mul1
jmp mov0
(3) 标号: FADD 功能:浮点数加法
入口条件:被加数在中,加数在中。
出口信息:和仍在中
fadd:
clrb 28h;flag for fadd
jmp as
(4) 标号: FSUB 功能:浮点数减法
入口条件:被减数在中,减数在中。
出口信息:差仍在中
fsub:
ldb 28h,#80h
as:
push cx;a1
ld 2ch,dx
ld 2eh,cx
;*******************
call mvDX ;read data for dx,cx,
call mvCX
asn:
xorb 27h,28h ;a2
ldb 28h,27h
xorb 28h,26h ;a1
call as1
mov0:
pop cx
;***********
stb 2fh,1
stb 2eh,2
stb 2dh,3
stb 2ch,4
andb 1ah,#7fh
orb 1ah,26h
stb 1ah,
;******
andb al,1ah,#7fh
clrc
cmpb al,#3fh
jne mv01
setc
mv01:
ret
;********************
movzer:
ld 1ah,#41h
clrb 26h
clr 2ch
clr 2eh
ret
as1:
ld 24h,dx
or 24h,cx
je as2
;*** not =
ld 24h,ax
or 24h,bx
jne eq1
; yes =
ld ax,cx
ld bx,dx
ldb 26h,27h
ldb 1ah,1bh
as2:
ret
eq1:
cmpb 1ah,1bh
je as4
jgt eq2;;1ah>1bh
;*** 1ah<1bh
shrl ax,#01
incb 1ah
ld 24h,ax
or 24h,bx
jne eq1
ldb 1ah,1bh
sjmp as4
eq2:
shrl cx,#1
incb 1bh
ld 24h,cx
or 24h,dx
jne eq1
ldb 1bh,1ah
as4:
add 28h,#0
jne as5
add ax,cx
addc bx,dx
jc as21
sjmp as22
as21:
shrl ax,#01
orb bh,#80h
incb 1ah
as22:
ld 2eh,bx
ld 2ch,ax
ret
as5:
ld 2eh,bx
sub 2ch,ax,cx
subc 2eh,dx ;bxax-dxcx=>2eh2ch
jnc as6 ;<
jmp rln
as6:
notb 26h
and 26h,#80h
ld 2eh,dx
sub 2ch,cx,ax
subc 2eh,bx;dxcx-bxax
jmp rln
mvDX:
ldb 1bh,
ldb dh,1
ldb dl,2
ldb ch,3
ldb cl,4
jmp pa27h ;1bh=neg;27=fu hao
mvCX:
ldb 1ah,
ldb bh,1
ldb bl,2
ldb ah,3
ldb al,4
jmp pa26h ;1bh=neg;27=fu hao
(5) 标号: FTOB 功能:格式化浮点数转换成浮点BCD码
入口条件:格式化浮点操作数在中。
出口信息:转换成的浮点BCD码仍在中。
ftob:
push cx
ld 2eh,cx
call mvCX;bx,ax=data
ld dx,ax
or dx,bx
jne ft1
call movzer
sjmp ftobend
ft1:
ld 28h,#bfl0;***28h=adr
ldb 25h,#0
jbc 1ah,7,ftb1
;**** - "87"
ld 28h,#btfl
ldb 25h,#0edh
addb cl,1ah,#16
jnc ftb1
ld 28h,#bfln
ldb 25h,#0fah
ftb1:
ldb 1bh,+
ldb dh,+
ldb dl,+
ldb ch,+
ldb cl,+
;****************
call pa27h
cmpb 1bh,1ah
jlt fbt2
jne ftb3
;*** "="
;-
cmp dx,bx
jne ftb21
;***
cmp cx,ax
jne ftb21
;***
addb 1bh,25h,#01
ld 2eh,#1000h ;input 0.10000
clr 2ch
ftb6:
ldb 1ah,1bh
ftobend:
jmp mov0
ftb21:
jh ftb3;dx>bx
fbt2:
incb 25h
sjmp ftb1
ftb11:
jle fbt2;;;jgt ftb3
ftb3:
push 24h
call div3
;*** 1ah=jie_ma tatiol
fbt301:
addb 1ah,#0
je fbt4
clrc
call rDX
sjmp fbt301
fbt4:
call hb2
fbt7:
pop 24h;25h=10^n
orb 25h,26h
ldb 1ah,25h
sjmp ftobend
;2eh2ch*10
hb2:
push 1ah
push 26h
;******
ld 1ah,#ch
ldb cl,#08
hb21:
mulu 28h,2ch,#10
mulu ax,2eh,#10
ld 2ch,28h
add 2eh,2ah,ax
addc bl,#0
stb bl,+
djnz cl,hb21
ldb ax,1ah
;28h,27h,26h,25h,24h,23h,22h,ch;=bcd8
;99999999.0
shlb 2fh,#01
addcb cl,#0
ldb al,#08
bh24:
decb 1ah
ldb ah,
addb ah,cl
cmpb ah,#9
jnh hb23
;** add +6
addb ah,#06
andb ah,#0fh
stb ah,
ldb cl,#1
djnz al,bh24
hb23:
stb ah,
;* zip_bcd
ld 1ah,#ch
ld ax,#2fh
ldb bl,#04h
hb25:
ldb ch,+
ldb cl,+
shlb ch,#4
orb ch,cl
stb ch,
dec ax
djnz bl, hb25
pop 26h
pop 1ah
ret
(6) 标号: BTOF 功能:浮点BCD码转换成格式化浮点数
入口条件:浮点BCD码操作数在中。
出口信息:转换成的格式化浮点数仍在中。
btof:
push cx
ld 2eh,cx
call mvCX
ld dx,ax
or dx,bx
jne btf1
;ax=bx=0
call movzer
sjmp btofend
btf1:
cmpb 1ah,#19
jle btf3
;*** 1ah>19
;3fh,0ffh0ffh
orb 26h,#3fh
ldb 1ah,26h
ld ax,#0ffffh
ld bx,#0ffffh
;***********
sjmp btofend
btf3:
cmpb 1ah,#0edh
jge btf4
;**** 1ah<-19
call movzer
sjmp btofend
btf4:
push 26h
call dottobin;dxcx=bin 24h=jie_ma
;***** read 10^n
btf5:
addb al,1ah,#19
ldb ah,#05
mulub ax,ah,al
add 28h,ax,#btfl ;28h=adr
ldb 1bh,+
;***********
andb 1bh,#7fh;ah=jie_ma2
jbc 1bh,6,mlk1
orb 1bh,#80h
;*************
mlk1:
ldb bh,+
ldb bl,+
ldb ah,+
ldb al,+
ldb 1ah,24h
call mul1 ;1ah=jie_ma;2ch_2fh=wei_shu
;******************
pop 26h
btofend:
jmp mov0
pa26h:
andb 26h,1ah,#80h;26h.7=jie_ma1
andb 1ah,#7fh;ji_ma to cl
jbc 1ah,6,btf2
orb 1ah,#80h
btf2:
ret
pa27h:
andb 27h,1bh,#80h;26h.7=jie_ma1
andb 1bh,#7fh;ji_ma to cl
jbc 1bh,6,btf112
orb 1bh,#80h
btf112:
ret
;***************
;use ax-dx,24h-29h
;out=dx,cx=fu(2)
;in=bx,ax
dottobin:
ld 24h,#32
clr dx
clr cx
dot1:
shll ax,#1
addc cx,cx
addc dx,dx
ld 26h,#ax
call intbcd
ldb cl,2dh
decb 24h
jbc dh,7,dot1
;*** 0.5 add
jbc bh,7,dot2
add cx,#01
addc dx,#0
jnc dot2
ld dx,#8000h
inc 24h
dot2:
ret
;**************************
intbcd:
ldb 25h,#04
ldb 2ch,;use 2ch,2dh
int0:
ldb 2dh,1
add 2ch,#66h
jbs 2ch,4,int1
subb 2ch,#06
int1:
jbs 2dh,0,int2
subb 2ch,#60h
int2:
stb 2ch,+
stb 2dh,2ch
djnz 25h,int0
ret
;*********************
; 2fh,2eh,2dh,2ch,2bh,2ah,29h,28h
; 27h,26h,25h,24h,dx,cx,bx,ax,1bh,1ah
;=a1;=a2
;2fh~28h=a1*a2 a1/a2
;bxax*dxcx
mul1:
ld 28h,ax
or 28h,bx
je mul61
ld 28h,dx
or 28h,cx
je mul61
mulu 28h,ax,cx
mulu 2ch,bx,cx
add 2ah,2ch
addc 2eh,#0
clr 28h;;2002.6.30
push 2eh
mulu 2ch,ax,dx
add 2ah,2ch
addc 2eh,+
addcb 28h,#0
push 2eh
mulu 2ch,bx,dx
add 2ch,+
addc 2eh,28h
;*********** 2fh~28h
jbs 2fh,7,mul2
shll 28h,#1
call rl1
sjmp mul3
mul2:
jbc 2bh,7,mul3
add 2ch,#01
addc 2eh,#0
mul3:
addb 1ah,1bh
md:
jbs 1ah,7,mul4
jbc 1ah,6,mul6
;*** over
;1ah=3fh
ldb 1ah,#3fh
setc
ret
mul4:
jbs 1ah,6,mul6
mul61:
call movzer
mul6:
clrc
ret
;************* ab/cd
;ab<cd=;2fh~2ch=temp
;24h=cy
;*****************
div3:
cmp dx,bx
jh div4
je div31
sjmp div32
div31:
cmp cx,ax
jh div4
div32:
clrc
;****
ld 2ch,ax
ld 2eh,bx
call rDX
ld ax,2ch
ld bx,2eh
sjmp div3
div4:
clr 2ah
clr 28h
clr 24h
clr 2ch
clr 2eh
ldb 25h,#32
div43:
clrc
shll 2ch,#1
shll ax,#1
ldb 24h,#0
addcb 24h,#0
sub 28h,ax,cx;ax-cx=>2ch
ld 2ah,bx ;** mov
subc 2ah,dx;bx-dx=>2eh
jbc 24h,0,div41
div42:
ld ax,28h
ld bx,2ah
incb 2ch
sjmp div44
div41:
jc div42
;*** not to sub
div44:
djnz 25h,div43
;****
shr dx,#1
sub bx,dx;dx/2-bx> not +1
;*** inc 28h
addc 28h,#0
addc 2ah,#0
subb 1ah,1bh
call md
jmp rln
;***************
;2fh,2eh,2dh,2ch
;***************
rl1:
addc 2ch,2ch
addc 2eh,2eh
;***
decb 1ah
cmpb 1ah,#0c0h
jgt rl2
orb 26h,#0c1h
ldb 1ah,26h
clr 2ch
clr 2eh
rl2:
ret
;*********************
rDX:
shrl 2ch,#01 ;2ch--->1
incb 1ah
cmpb 1ah,#040h
jlt rr2
orb 26h,#3fh
ldb 1ah,26h
rr2:
ret
;***************
rln:
ld ax,2ch
or ax,2eh
jne rln1
;*** =0
orb 26h,#0c1h
ldb 1ah,26h
ret
rln1:
jbs 2fh,7,rln2
call rl1
sjmp rln
rln2:
ret
BTFL:
DB 41H,0ECH,01EH,04ah,00dh;10e-19
DB 45H,093H,092H,0eeh,08eh;10e-18
DB 48H,0B8H,077H,0aah,032h;10e-17
DB 4BH,0E6H,095H,094h,0beh;10e-16
DB 4FH,090H,01DH,07ch,0f7h;10e-15
DB 52H,0B4H,024H,0dch,035h;10e-14
DB 55H,0E1H,02EH,013h,042h;10e-13
DB 59H,08CH,0BcH,0cch,009h;10e-12
DB 5CH,0AFH,0EbH,0ffh,00bh;10e-11
DB 5FH,0DBH,0E6H,0feh,0ceh;10e-10
DB 63H,089H,070H,05fh,041h;10e-9
DB 66H,0ABH,0CCH,077h,011h;10e-8
DB 69H,0D6H,0bfH,094h,0d6h;10e-7
BFLN:
DB 6DH,086H,037H,0bdh,005h;10e-6
DB 70H,0A7H,0C5H,0ach,047h;10e-5
DB 73H,0D1H,0B7H,017h,059h;10e-4
DB 77H,083H,012H,06eh,097h;10e-3
DB 7AH,0A3H,0D7H,00ah,003d;10e-2
DB 7DH,0CCH,0CcH,0CCH,0cdh;10e-1
BFL0:
DB 01h,080H,000H,000h,000h;10e0
DB 04h,0A0H,000H,000h,000h;10e1
DB 07h,0C8H,000H,000h,000h;10e2
DB 0AH,0FAH,000H,000h,000h;10e3
DB 0EH,09CH,040H,000h,000h;10e4
DB 11H,0C3H,050H,000h,000h;10e5
DB 14H,0F4H,024H,000h,000h;10e6
DB 18H,098H,096H,080h,000h;10e7
DB 1BH,0BEH,0BCH,020h,000h;10e8
DB 1EH,0EEH,06BH,028h,000h;10e9
DB 22H,095H,002H,0f9h,000h;10e10
DB 25H,0BAH,043H,0b7h,040h;10e11
DB 28H,0E8H,0D4h,0a5h,010h;10e12
DB 2CH,091H,084H,0e7h,02ah;10e13
DB 2FH,0B5H,0E6H,020h,0f5h;10e14
DB 32H,0E3H,05fH,0a9h,032h;10e15
DB 36H,08EH,01bH,0c9h,0bfh;10e16
DB 39H,0b1H,0A2H,0bch,02eh;10e17
DB 3CH,0DEH,00BH,06bh,03ah;10e18
DB 40H,08AH,0c7H,023h,005h;10e19
(7)标号: DTOF 功能:四字节十六进制定点数转换成格式化浮点数
入口条件:四字节定点数的绝对值在中,数符在位26H的D7上,整数部分的位数在AL中。
出口信息:转换成格式化浮点数在中(四字节)。
dtof:
push cx
ldb 1ah,al;al=wei shu max=32
ldb 2fh,
ldb 2eh,1
ldb 2dh,2
ldb 2ch,3
call rln
jmp mov0
太老了,而且平时汇编也少用了,当纪念了 记得这个单片机好多寄存器,比51多很多,但后来学了AVR 比mcs51多了很多不认识的指令 我用这个单片机做过好几个产品,全是用汇编写的,不过现在忘了差不多了{:lol:} 用过这款芯片的,应该都是40好几的人了,用得熟悉的应该50+了
页:
[1]