📄 zz51.a51
字号:
ACALL LR0 ;否则,整数、小数部分整体左移一位
DEC R0 ;阶减1
CJNE R0,#60H,LP11
RET ;浮点数为0
NX63: CALL EX ;二进制浮点数转入R4~R7
MOV A,R0
JNB ACC.7,PP6
CALL INC3 ;截去部分四舍五入
CJNE R5,#0,PP6
INC R4 ;调整
MOV R5,#80H
PP6: JBC 7BH,PPX
ANL 0DH,#7FH ;置数符
PPX: RET
;------------------------------------------------
;标号:BTOD 功能: 二进制浮点数转为十进制浮点数
;入口:二进制浮点数在 R4,R5,R6,R7
;出口:十进制浮点数在 R0=阶;R5=阶符,R6=数符,00H为正,非0为负
;注意:这里所说的'阶'--->指的是整数的位数
;R1,R2,R3,R4内为纯小数尾数,R1为高位字节
;------------------------------------------------
BTOD: CLR A ;浮点数x二翻十子程序
MOV 18H,A ;清阶符单元
MOV 19H,A ;清数符单元
MOV 1BH,A ;清阶码单元
MOV A,R4
JZ PP4 ;浮点数为0,转换结果亦为0
MOV A,R5
RLC A
JNC BTA
DEC 19H ;记数符(0→0FFH)
ANL 0DH,#7FH ;取绝对值
BTA: LCALL DDP ;取1010
LCALL FPCP ;|x|与1010比较
JC BTC ;|x|<1010转
BTB: LCALL INVDP ;取10-10
LCALL FPMU ;|x|·10-10→|x|
MOV A,1BH
ADD A,#10H ;十进制浮点数阶码加10
MOV 1BH,A
SJMP BTA
BTC: LCALL INVDP
LCALL FPCP ;|x|与10-10比较
JZ BTE
JNC BT0 ;|x|>10-10,转
BTE: LCALL DDP
LCALL FPMU ;|x|·1010→|x|
MOV A,1BH
ADD A,#10H ;十进制浮点数阶码加10
MOV 1BH,A
DEC 18H ;负阶
SJMP BTC
BT0: LCALL G1
LCALL FPCP ;|x|与1比较
JC BT2 ;|x|<1,转
BT1: LCALL G01
LCALL FPMU ;|x|·10-1→|x|
INC 1BH ;十进制浮点数阶码加1
SJMP BT0
BT2: LCALL G01
LCALL FPCP ;|x|与0.1比较
JZ BT4
JNC BDS ;|x|≥0.1转出
BT3: LCALL G10 ;否则|x|·10→|x|
LCALL FPMU
INC 1BH ;十进制浮点数阶码加1
DEC 18H ;负阶
SJMP BT2
PP4: LJMP LD0 ;取十进制浮点数0
BT4: MOV R1,#10H
CLR A
MOV R2,A
MOV R3,A
MOV R4,A ;取十进制浮点数尾数0.100 000 00
SJMP BT6
BDS: MOV A,#98H
ORL 0DH,#80H ;恢复尾数最高位
CLR C
SUBB A,R4 ;右移位数为98H-阶码
MOV B,A
LCALL CONV31 ;得十进制浮点数尾数
BT6: MOV A,1BH
JNB ACC.3,BT7
JNB ACC.1,BT7 ;低位BCD码为1010B?
ADD A,#6 ;对十进制浮点数的阶检查调整
BT7: MOV R0,A ;回送阶
MOV R5,18H ;回送阶符
MOV R6,19H ;回送数符
RET
BB: JNB ACC.7,BB1
ADD A,#0D0H ;右移后,BCD码最高位为1(代表8)变为5
BB1: JNB ACC.3,BB2
ADD A,#0FDH
BB2: RET
;------------------------------------------------
;标号: DTOB 功能: 将十进制浮点数转成二进制浮点数
;阶符:正为00H,负为0FFH ;数符:正数为00H,负数为0FFH
;注意阶符是指'阶或指数P的符号'.公式:移码(阶码)=补码(阶)±80H
;或 移码=阶+80H (阶带符号);阶=移码-80H
;阶与尾数均为压缩BCD码,尾数为纯小数
;入口: 十进制浮点数在R1,R2,R3,R4,R5,R6,R7单元内,
;其中R1=阶符,R2=数符,R3=阶-->这里所说的阶是十进制浮点数的阶,即为小数点的位置
;如 0.1的阶为'0';0.01的阶为'-1';1的阶为'+1';22.00的阶为'+2'
;R4~R7为纯小数尾数,R4为高位字节
;出口:二进制浮点数在R4,R5,R6,R7中
;------------------------------------------------
DTOB: MOV 30H,R1 ;十进制数阶符
MOV 31H,R2 ;十进制数数符
MOV 32H,R3 ;十进制数阶
CALL CONV4 ;十进制尾数十翻二(定点小数十翻二)
MOV R0,#80H ;置阶码(指数的偏移量)
MOV A,R4
ORL A,R5
ORL A,R6
ORL A,R7
JZ PP8 ;二进制小数等于0,结果二进制数为0
MOV A,R4 ;尾数高字节
LP14: JB ACC.7,NX67 ;左移使 ACC.7=1,向下
CALL SHIF ;尾数算术左移1位子程序
RLC A
DEC R0 ;对二进制小数规格化
SJMP LP14
NX67: XCH A,R5
XCH A,R6
XCH A,R7 ;尾数从A R5 R6 R7转入R5 R6 R7 A中
JNB ACC.7,NX66
CALL INC3 ;四舍五入
CJNE R5,#0,NX66
INC R0
MOV R5,#80H ;调整尾数,阶码
NX66: XCH A,R0
XCH A,R4
MOV A,31H
JNZ NX6A
ANL 0DH,#7FH ;置数符,得x
NX6A: MOV A,30H ;阶符
JZ DBL4 ;正阶,转
DBL1: MOV A,32H ;取阶
CLR C
SUBB A,#10H
JC DBL2
MOV 32H,A
LCALL INVDP ;阶减去10, x·10-1o→x
LCALL FPMU
SJMP DBL1
DBL2: ADD A,#10H ;恢复阶
JZ PP8
DBL3: LCALL G01 ;取0.1
LCALL FPMU
DJNZ 32H,DBL3 ;x·10-1→x,阶减1
RET
DBL4: MOV A,32H
CLR C
SUBB A,#10H
JC DBL5 ;阶减去10, x·101o→x
MOV 32H,A
LCALL DDP
LCALL FPMU
SJMP DBL4
DBL5: ADD A,#10H ;恢复阶
JZ PP8
DBL6: LCALL G10
LCALL FPMU ;x·10→x,阶减1
DJNZ 32H,DBL6
PP8: RET
INVDP: MOV R0,#5FH ;取浮点数10-1o
MOV R1,#5BH
MOV R2,#0E6H
MOV R3,#0FFH
RET
DDP: MOV R0,#0A2H ;取浮点数101o
MOV R1,#15H
MOV R2,#02H
MOV R3,#0F9H
RET
;------------------------------------------------
;清单19 标号: STRT 功能: 最小二乘法拟合直线程序
;------------------------------------------------
ORG 3000H ;最小二乘法拟合直线程序
NUMB EQU 10 ;取10点,即10对浮点数,
;按增地址存放y1,x1,y2,x2,…,yn,xn皆4字节浮点数
TABLA EQU 9000H ;数据指针,首指向y1
STRT: PUSH PSW
SETB RS0
CLR RS1
MOV R0,#18H
LP51: MOV @R0,#0 ;清累加和单元,即LD1,LD2,LD3,LD4和LD5所占用的单元
INC R0
CJNE R0,#1CH,LP51
MOV R0,#30H
LP52: MOV @R0,#0
INC R0
CJNE R0,#40H,LP52
MOV B,#NUMB ;总拟和点数
MOV DPTR,#TABLA ;数据指针
LOOP3: ACALL GETA ;取y1,y2,y3,y4(合称yi)占4字节,下同
LCALL INVX ;计算1/yi
LCALL LD6 ;暂存
LCALL GET1 ;取累加和
LCALL FPAD ;1/yi加入累加和(∑1/yi是 ∑n〖〗i=11/yi 简写形式,下同)
LCALL LD1
ACALL GET6 ;取1/yi
PUSH DPL
PUSH DPH ;保护数据指针
ACALL GETA ;取xi,占4字节(x1,x2,x3,x4),下同
POP DPH
POP DPL
LCALL FPMU ;计算xi/yi
ACALL LD7 ;暂存
LCALL GET2
LCALL FPAD ;xi/yi加入累加和∑xi/yi
LCALL LD2
ACALL GET7 ;取出xi/yi
LCALL SAV0
LCALL FPMU ;计算(xi/yi)2
LCALL GET3
LCALL FPAD ;(xi/yi)2加入累加和∑(xi/yi)2
LCALL LD3
ACALL GET6 ;取1/yi
LCALL SAV0
LCALL FPMU ;计算1/yi2
ACALL LD6 ;暂存
LCALL GET4
LCALL FPAD ;1/yi2加入累加和∑ 1/yi2
LCALL LD4
ACALL GET6 ;取出1/yi2
ACALL GETA ;再取xi
LCALL FPMU ;计算xi/yi2
ACALL GET5
LCALL FPAD ;xi/yi2加入累加和∑xi/yi2
ACALL LD5
DJNZ B,LOOP3 ;未到总点数,循环
LCALL GET4
LCALL SAV0
LCALL GET3
LCALL FPMU ;计算∑1/yi2·∑xi/yi2并存入
ACALL LD6
ACALL GET5 ;取∑xi/yi2
LCALL SAV0
LCALL FPMU ;计算(∑xi/yi2 )2
ACALL GET6
LCALL FPSU ;计算A=∑1/yi2·∑xi/yi2-(∑xi/yi2)2
ACALL LD6 ;存入
LCALL GET2
LCALL SAV0
LCALL GET4
LCALL FPMU ;计算∑ xi/yi·(∑ 1/yi)2并存入
ACALL LD7
LCALL GET1
LCALL SAV0
ACALL GET5
LCALL FPMU ;计算∑ 1/yi·∑ xi/yi2并存入
ACALL GET7
LCALL FPSU ;计算B=∑ xi/yi·(∑ 1/yi)2-∑ 1/yi·∑ xi/yi2
ACALL GET6 ;取A
LCALL EX
LCALL FPDI ;计算b=B/A并存入
ACALL LD7
ACALL GET5 ;取∑xi/yi2
LCALL FPMU ;计算(∑ xi/yi2 )·b
LCALL GET1
LCALL FPSU ;计算∑1/yi-(∑xi/yi2)·b
LCALL GET4 ;取∑1/yi2
LCALL EX
LCALL FPDI ;计算a=\[∑1/yi-(∑xi/yi2)·b\]/∑1/yi2
ACALL LD6 ;结果a在40H~43H中,b在44H~47H中
POP PSW
RET
GETA: PUSH 8 ;保护R0
MOV R0,#0CH
GETL: MOVX A,@DPTR ;从外部RAM中取浮点数到R4~R7中
MOV @R0,A
INC DPTR
INC R0
CJNE R0,#10H,GETL
POP 8
RET
LD5: MOV 3CH,R4 ;计算 ∑xi/yi2 的存储单元
MOV 3DH,R5
MOV 3EH,R6
MOV 3FH,R7
RET
LD6: MOV 40H,R4 ;暂存1/yi等浮点数子程序
MOV 41H,R5
MOV 42H,R6
MOV 43H,R7
RET
LD7: MOV 44H,R4 ;暂存xi/yi等浮点数
MOV 45H,R5
MOV 46H,R6
MOV 47H,R7
RET
GET5: MOV R0,3CH ;取∑ xi/yi2或中间结果
MOV R1,3DH
MOV R2,3EH
MOV R3,3FH
RET
GET6: MOV R0,40H ;取浮点数1/yi等
MOV R1,41H
MOV R2,42H
MOV R3,43H
RET
GET7: MOV R0,44H ;取浮点数xi/yi等
MOV R1,45H
MOV R2,46H
MOV R3,47H
RET
;------------------------------------------------
;清单20:标号: MUL16 功能:定点16位整数×16位整数→32位整数
;------------------------------------------------
MUL16: CLR A ;定点16位整数×16位整数→32位整数
MOV R4,A
MOV R5,A
MOV A,#11H
CLR C
LP15: JNC NX70
ACALL ADD3
NX70: XCH A,R4
RRC A
XCH A,R4
LCALL SRA
DJNZ ACC,LP15
RET
MUL165: ACALL MUL16 ;16位整数×16位小数→16位整数
MOV A,R6 ;精确到0.5
JNB ACC.7,LL1
INC R5
CJNE R5,#0,LL1
INC R4
LL1: RET
ADD3: XCH A,R5
ADD A,R3
XCH A,R5
XCH A,R4
ADDC A,R2
XCH A,R4
RET
SUB3: CLR C
XCH A,R5
SUBB A,R3
XCH A,R5
XCH A,R4
SUBB A,R2
XCH A,R4
RET
DIV16: MOV A,#16 ;定点32位整数÷16位整数→16位整数
LL0: LCALL SHIF ;精确到1
XCH A,R4
RLC A
XCH A,R4
JC D161
LCALL SUB3
JNC D162
LCALL ADD3
SJMP D163
D161: LCALL SUB3
D162: INC R7
D163: DJNZ ACC,LL0
RET
DIV165: ACALL DIV16 ;32位整数÷16位整数→16位整数
MOV A,R5 ;精确到0.5
ADD A,R5
MOV R5,A
MOV A,R4
ADDC A,R4
MOV R4,A
JC D164
ACALL SUB3
JC D165
D164: LCALL INC3
D165: RET
DIV16F: ACALL DIV16 ;32位整数÷16位整数→16位整数+16位小数→4字节规格化浮点数
PUSH 7
PUSH 6
MOV R7,#0
MOV R6,#0
ACALL DIV16
MOV 3,R7
MOV 7,R6
POP 5
POP 6 ;整数部分在R5 R6中,小数部分在R7 R3中
MOV R4,#90H
MOV R2,#32
DIV16L: MOV A,R5
JB ACC.7,NMLDN
MOV A,R3
ADD A,R3
MOV R3,A
LCALL H0 ;左移R5 R6 R7 R3
DEC R4
DJNZ R2,DIV16L
MOV R4,#0
RET
NMLDN: MOV A,R3
JNB ACC.7,DIVRT
LCALL INC3
MOV A,R5
JNZ DIVRT
INC R4
DIVRT: ANL 5,#7FH ;结果(正数)在R4 R5 R6 R7中
RET
DIV24: CLR A ;累加值(被除数)在R4 R5 R6 R7中,除数在R2 R3中
MOV B,#24 ;计数器
LXP: LCALL SHIF
XCH A,R4
RLC A
XCH A,R4
RLC A
JNC LXP1
ACALL SUB2Y ;CY=1 够减
SJMP DIV0
LXP1: ACALL SUB2Y
JNC DIV0 ;CY=0 够减
XCH A,R4
ADD A,R3
XCH A,R4
ADDC A,R2 ;不够减则恢复被除数,本位商0
SJMP DIV1
DIV0: INC R7 ;本位商1
DIV1: DJNZ B,LXP
XCH A,R4
CLR C
RLC A
XCH A,R4
RLC A
JC GINC
ACALL SUB2Y
JNC GINC
RET3: MOV R4,#0
RET ;结果在R4(=0)R5 R6 R7(整数)中
GINC: MOV R0,#7 ;四舍五入,商增1
INC3A: INC @R0
CJNE @R0,#0,RET3
DEC R0
SJMP INC3A
SUB2Y: CLR C ;减去除数子程序
XCH A,R4
SUBB A,R3
XCH A,R4
SUBB A,R2
RET
;================================================
END
;================================================
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -