mon51 发表于 2020-7-9 21:57:14

谁还记得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。

mon51 发表于 2020-7-9 21:57:41

程序清单:
(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,+
        ;***********

mon51 发表于 2020-7-9 21:58:01

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

kkey 发表于 2020-7-10 00:00:25

太老了,而且平时汇编也少用了,当纪念了

Jigsaw 发表于 2020-7-10 01:21:41

记得这个单片机好多寄存器,比51多很多,但后来学了AVR

dz20062008 发表于 2020-7-10 01:58:49

比mcs51多了很多不认识的指令

id20200627 发表于 2020-7-13 19:30:35

我用这个单片机做过好几个产品,全是用汇编写的,不过现在忘了差不多了{:lol:}

dellric 发表于 2020-7-13 21:28:47

用过这款芯片的,应该都是40好几的人了,用得熟悉的应该50+了
页: [1]
查看完整版本: 谁还记得MCS-96单片机?放一个汇编库 MCS-96(196) 五字节浮点库及其使用说明