📄 newmath.asm.svn-base
字号:
name newmath
?newmath segment code
public newmath
rseg ?newmath
using 0 ;using bank0
extrn xdata (TEMPSTART)
public MBCD_ADD
public MBCD_SUB
public MBCD_MUL
public MBCD_DIV
;public TEMPSTART
;***********************
; 用到的所有函数列表
;***********************
;ACTDOTLEN: 计算结果的实际有效的小数位数 if(r0+r1>LENTH) r0=LENTH-r1
;ADD1TIME: 被除数加除数一次,结果送回被除数
;ADDSUM: 将 A 加到 #BCDBIN2 指向的BIN 码中(从低位)
;BCSCOPY: 将被乘数 COPY 到 临时乘积
;BCSSAN_RL: 被除数(连同商数,总长为被除数的两倍)循环左移(向高位方向) 1 位
;R7R6ADD1: R7R6加一:用于源指针加一(被除数,被乘数等)
;BCS_RL: 被除数(不带商数)循环左移(向高位方向) 1 位
;BCS_RRR2: 被除数向低位循环右移 R2 位(为了与除数的高位对齐)
;CALBCDLEN: 整数,小数部分的有效BCD码长度
;CALCUL_CLEAR: 缓冲区清零处理
;CALCUBCD: 计算BCD码的被除数(或除数)的有效BCD码长(包括整数及小数)
;CLEAR_CJ: 乘积清零
;CLEAR_LSCJ:临时乘积清零
;CLEAR_SAN: 清商数区
;COMPTOMAX: 取(加减乘)结果送到临时区转换为BCD
;COMPTOM_10:取(除)结果送到临时区转换为BCD (源指针R6R7不同于COMPTOMAX)
;CS_RR1: 将乘数(从高位向低位)右移 1 BIT, 保存于C
;DEC1TIME: 被除数减除数一次,结果送回到被除数
;DEL4SAVE5: 结果的小数部分末位的四舍五入的处理
;DORESULT: 对(加减)计算结果的处理,判断整数及小数的长度
;DORESU_10: 对(乘积)计算结果的处理,判断整数及小数的长度 (源指针R6R7不同于DORESULT)
;DOREMAIN: 处理余数(包括 BIN -> BCD 并左移 B*4次 -> BIN ) IN:B OUT:NO
;DPTRDEC1: DPTR 指针减一
;GETBCS_NOUSE: 获取被除数的无效高位位数(N=B)
;GETCS_NOUSE: 获取除数的无效高位位数(N=B)
;GETDATA: 测试用的初始化 XRAM 数据
;IFREZERO: 判断余数(即被除数区) 是否为零 (Cy=1 余数为零)
;JUDGEINT: 判断乘积(或商数)的整数部分是否溢出(已经转为BCD码) Cy=1 溢出
;JUDGESIGN: 乘除法结果的符号及溢出设定
;JUDEGSIG_16:加减法结果的溢出设定
;LSCJ_RL1: 将临时乘积 左移 1 BIT, C不保存,低位补0
;LSCJ_RLB: 将临时乘积左移 B BITS, C不保存,低位补0
;MBIN_A05: 多字节无符号BIN加法
;MBIN_S05: 多字节无符号BIN减法
;MUL10: 将 #BCDBIN2 所指向的BIN码(从BCD中累加来的)从低到高逐位乘以 10
;MBCD_ADD: 多字节带符号 BCD 码加法
;MBCD_SUB: 多字节带符号 BCD 码减法
;MBCD_ADD_NS: 多字节无符号 BCD 码加法
;MBCD_SUB_NS: 多字节无符号 BCD 码减法
;MBCD_MUL: 多字节无符号 BCD 码乘法 OUT: R0=0xEF 没有溢出; R0=0x10 溢出
;MBCD_DIV: 多字节无符号 BCD 码除法 OUT: R0=0xEF 没有溢出; R0=0x10 溢出
;R5R4ADD1: R5R4加一:用于 目标指针加一(除数,临时乘积等)
;SANADDONE: 商数加 1
;SANTOEND: 判断商数转换为BCD码后的位数是达到有效显示位长(实例中为8位) B=商数BCD码长; (IF Cy=1, B >= LENTH)
;STRCOPY: 字符串拷贝
;TIME10N: 将被除数(BCD码)放大10的N次幂
;XBCD_BIN: converte BCD to BIN (在外部ram中转换)
;XBIN_BCD: converte BIN to BCD (在外部ram中转换)
;XMEMXCH: 将外部MEM中两串数码(从最低字节开始)互换
;WWBCSQD: 判断被乘数是否为零
;WWCSQD: 判断乘数是否为零
;YWBCSQD: 判断被除数是否为零
;YWCSQD: 判断除数是否为零
;MATHSTART: 主调用函数
;MBIN_ADD: 多字节无符号BIN加法( 含MBIN_A05 )
;MBIN_SUB: 多字节无符号BIN减法( 含MBIN_S05 )
;MBIN_DIV: 多字节无符号BIN除法
;MBIN_MUL: 多字节无符号BIN乘法
;XMEMCOMP: 外部MEM中比较两串数码(从最高字节开始比较)
;加减法符号运算列表如下:
;-------------------------------------------------------
; 符 号 操作调用
; A B 结果
;-------------------------------------------------------
; + + + lcall Mbin_add (A+B)
; 加 - - - lcall Mbin_add (A+B)
; + - ? lcall Mbin_sub (A-B)
; 法 - + ? lcall Mbin_sub (B-A)
;-------------------------------------------------------
; + + ? lcall Mbin_sub (A-B)
; 减 - - ? lcall Mbin_sub (B-A)
; + - + lcall Mbin_add (A+B)
; 法 - + - lcall Mbin_add (A+B)
;-------------------------------------------------------
newmath:
;************************
; 起始地址宏定义开始
;************************
;TEMPSTART EQU 7000H
ALLLEN EQU 44H
LENTH EQU 10H ;-> 操作数字节长度16字节
;****************************************
;* 操作数存放地址定义 (均以BCD码格式存放) *
; 运算过程中需转为BIN码,最后再转变为BCD码
; 操作结果存在第三操作数 d3
;****************************************
;D1NUM equ TEMPSTART ;数字串 d1 的小数位数 (1byte -> 8000h)
;BCDD1BUF equ D1NUM+1 ;数字串 d1 (16bytes -> 8001h ~ 8010h 高位数存于高地址)
;D2NUM equ BCDD1BUF+16 ;数字串 d2 的小数位数 (1byte -> 8011h)
;BCDD2BUF equ D2NUM+1 ;数字串 d2 (16bytes -> 8012h ~ 8021h 高位数存于高地址)
;D3NUM equ BCDD2BUF+16 ;结果 d3 的小数位数 (1byte -> 8022h)
;BCDD3BUF equ D3NUM+1 ;结果串 d3 (16bytes -> 8023h ~ 8032) 高位数存于高地址)
;ARITHFLAG equ BCDD3BUF+16 ;符号标志 (1byte -> 8033h)
;MAXNUM equ ARITHFLAG+1 ;最大值 BCD 码 (9999999999999999.0000000000000000)(8byte -> 8034h ~ 8043h 高位数存于高地址)
;TEMPUSE equ MAXNUM+16 ;零时转换区域(从 8044h 开始)
D1NUM equ 0 ;数字串 d1 的小数位数 (1byte -> 8000h)
BCDD1BUF equ D1NUM+1 ;数字串 d1 (16bytes -> 8001h ~ 8010h 高位数存于高地址)
D2NUM equ BCDD1BUF+16 ;数字串 d2 的小数位数 (1byte -> 8011h)
BCDD2BUF equ D2NUM+1 ;数字串 d2 (16bytes -> 8012h ~ 8021h 高位数存于高地址)
D3NUM equ BCDD2BUF+16 ;结果 d3 的小数位数 (1byte -> 8022h)
BCDD3BUF equ D3NUM+1 ;结果串 d3 (16bytes -> 8023h ~ 8032) 高位数存于高地址)
ARITHFLAG equ BCDD3BUF+16 ;符号标志 (1byte -> 8033h)
MAXNUM equ ARITHFLAG+1 ;最大值 BCD 码 (9999999999999999.0000000000000000)(8byte -> 8034h ~ 8043h 高位数存于高地址)
TEMPUSE equ MAXNUM+16 ;零时转换区域(从 8044h 开始)
;************************
;* arithmFlag define *
;************************
;bD1SIGN equ 00000001b ;sign of d1 bit=0 "+"; bit=1 "-"
;bD2SIGN equ 00000010b ;sign of d2 bit=0 "+"; bit=1 "-"
;bD3SIGN equ 00000100b ;sign of d3(result) bit=0 "+"; bit=1 "-"
;bCARRY equ 00001000b ;backup of carry
;bOVERF equ 00010000b ;flag of result overflow bit=0 "未溢出"; bit=1 "溢出"
;***************************
; BCD BIN 互相转换的地址定义
;***************************
BCDBIN1 EQU TEMPUSE ;8044H-8063H 共32 bytes(加减只要16bytes,乘除可能需要32bytes)
BCDBIN2 EQU BCDBIN1+LENTH*2 ;8064H-8083H 共32 bytes(加减只要16bytes,乘除可能需要32bytes)
;***************************
; 二进制操作数的地址定义
;***************************
BIND1BUF EQU BCDBIN2+LENTH*2 ;第一操作数区 起始地址8084H(指向低位字节,长度为16字节) (对于加减->也是结果的起始地址)
BIND2BUF EQU BIND1BUF+LENTH ;第二操作数区 起始地址8094H(指向低位字节,长度为16字节)
;************************************************************
; * BIN 除法地址定义 *
;如果被除数(或除数)为16字节,则做除法时应当予留32字节,因为被除数应当先
;左移(结果将要显示的)小数点的位数(BCD 码的位数).
;************************************************************
SANADD EQU BCDBIN2+LENTH*2 ;商数起始地址(指向低位字节) 8084H
DIVD1BUF EQU SANADD+LENTH*2 ;被除数起始地址(指向低位字节) 80a4H
DIVD2BUF EQU DIVD1BUF+LENTH*2 ;除数起始地址(指向低位字节) 80c4H
;********************
;* BIN 乘积地址定义 *
;********************
CENJI EQU BIND2BUF+LENTH ;-> 乘积起始地址(指向低位字节) 长度为32字节 80a4H
TEMPCENJI EQU CENJI+LENTH*2 ;-> 临时乘积起始地址(指向低位字节) 长度为32字节 80c4H
MATHSTART:
NOP
LCALL GETDATA
NOP
; LCALL MBIN_DIV
; LCALL MBIN_MUL
; LCALL MBIN_ADD
; LCALL MBIN_SUB
; mov r3,#LENTH ;BIN TO BCD (LENTH OF BIN)
; lcall XBIN_BCD
; lcall XBCD_BIN
lcall MBCD_ADD
; lcall MBCD_SUB
; lcall MBCD_MUL
; lcall MBCD_DIV
NOP
NOP
RET
GETDATA:
MOV R3,#ALLLEN
MOV R7,#LOW(BCSSTART)
MOV R6,#HIGH(BCSSTART) ;CODE 的地址
MOV R5,#LOW(TEMPSTART+D1NUM)
MOV R4,#HIGH(TEMPSTART+D1NUM) ;XDATA 的地址(被加数)
LOOP0:
MOV DPL,R7
MOV DPH,R6
MOV A,#0
MOVC A,@A+DPTR
lcall R7R6ADD1 ;指针加一
MOV DPL,R5
MOV DPH,R4
MOVX @DPTR,A
lcall R5R4ADD1 ;指针加一
DJNZ R3,LOOP0
RET
BCSSTART:
; DB 0feH,0ffH,0ffH,0ffH,00H,00H,00H,00H ;被除数
; DB 78H,56H,34H,00H,00H,00H,00H,00H ;除数
; DB 00H,00H,00H,00H,00H,00H,00H,00H
; DB 00H,00H,00H,00H,00H,00H,00H,00H
; DB 34H,56H,78H,00H,00H,00H,00H,00H ;被乘数
; DB 78H,56H,34H,00H,00H,00H,00H,00H ;乘数
; DB 00H,00H,00H,00H,00H,00H,00H,00H
; DB 00H,00H,00H,00H,00H,00H,00H,00H ;乘积
; DB 00H,00H,00H,00H,00H,00H,00H,00H
; DB 00H,00H,00H,00H,00H,00H,00H,00H ;临时乘积
; DB 0FEH,0FFH,FFH,5FH,00H,00H,00H,00H ;被加数
; DB 78H,56H,34H,00H,00H,00H,00H,00H ;加数
; DB 00H,00H,00H,00H,00H,00H,00H,00H
; DB 0FFH,0FFH,0C0H,06FH,0F2H,086H,023H,00H ;BIN~BCD
; DB 11H,22H,33H,44H,55H,66H,77H,88H
; DB 11H,00H,00H,00H,00H,00H,00H,00H
; DB 099H,099H,099H,099H,00H,00H,00H,00H ;BCD~BIN
; DB 11H,22H,33H,44H,55H,66H,77H,88H
; DB 11H,00H,00H,00H,00H,00H,00H,00H
;A小数位数
DB 01H
;A操作数 0000000000000932.7100000000000000
DB 00H,00H,00H,00H,00H,00H,00H,71H ;小数
DB 32H,09H,00H,00H,00H,00H,00H,00H ;整数
;B小数位数
DB 05H ;加减
;B操作数 0000000000032360.5371800000000000
DB 00H,00H,00H,00H,00H,80H,71H,53H ;小数
DB 60H,23H,03H,00H,00H,00H,00H,00H ;整数
;A小数位数
; DB 02H
;A操作数 0000000000031596.0912500000000000
; DB 00H,00H,00H,00H,00H,00H,00H,79H ;小数
; DB 56H,00H,00H,00H,00H,00H,00H,00H ;整数
;B小数位数
; DB 04H ;乘
;B操作数 0000000000000970.4312000000000000
; DB 00H,00H,00H,00H,00H,00H,89H,71H ;小数
; DB 03H,00H,00H,00H,00H,00H,00H,00H ;整数
;A小数位数
; DB 00H
;A操作数 0000000000000000.0000000000000001
; DB 00H,00H,00H,00H,00H,00H,00H,00H ;小数
; DB 56H,34H,12H,00H,00H,00H,00H,00H ;整数
;B小数位数
; DB 01H ;除
;B操作数 0000000000000000.0000000000000003
; DB 00H,00H,00H,00H,00H,00H,00H,70H ;小数
; DB 17H,00H,00H,00H,00H,00H,00H,00H ;整数
;结果小数位数
DB 0E0H
;结果存放 FFFFFFFFFFFFFFFF.FFFFFFFFFFFFFFFF
DB 0FFH,0FFH,0FFH,0FFH,0FFH,0FFH,0FFH,0FFH
DB 0FFH,0FFH,0FFH,0FFH,0FFH,0FFH,0FFH,0FFH
;符号及溢出标志==============================================
DB 00H
;最大值 9999999999999999.0000000000000000
DB 00H,00H,00H,00H,00H,00H,00H,00H
DB 99H,99H,99H,99H,99H,99H,99H,99H
; DB 08H,11H,80H,26H,00H,00H,00H,00H,00H ;操作数1 00000000.00268011
; DB 08H,67H,55H,01H,00H,00H,00H,00H,00H ;操作数2 00000000.00015567
; DB 0FH,0FH,0FH,0FH,0FH,0FH,0FH,0FH,0FH ;结果存放
; DB 0E0H ;符号及溢出标志
; DB 00H,00H,00H,00H,99H,99H,99H,99H ;最大值 99999999.00000000
; DB 05H,00H,50H,12H,09H,96H,15H,03H,00H ;操作数1 00031596.09125000
; DB 04H,00H,00H,12H,43H,70H,09H,00H,00H ;操作数2 00000970.43120000
; DB 0FH,0FH,0FH,0FH,0FH,0FH,0FH,0FH,0FH ;结果存放
; DB 0E0H ;符号及溢出标志
; DB 00H,00H,00H,00H,99H,99H,99H,99H ;最大值 99999999.00000000
; DB 08H,10H,00H,00H,00H,00H,00H,00H,00H ;操作数1 00000000.00000010
; DB 08H,03H,00H,00H,00H,00H,00H,00H,00H ;操作数2 00000000.00000003
; DB 0FH,0FH,0FH,0FH,0FH,0FH,0FH,0FH,0FH ;结果存放
; DB 0E0H ;符号及溢出标志
; DB 00H,00H,00H,00H,99H,99H,99H,99H ;最大值 99999999.00000000
;********************************
; 乘除法结果的符号及溢出设定
;IN:
; R0=0xFF 结果溢出标志.
; R0=0x00 正常状况下
;
;CHANGE: A,B,DPTR
;KEEP: R0
;********************************
JUDGESIGN:
mov dptr,#(TEMPSTART+ARITHFLAG)
movx a,@dptr
anl a,#00000011b
cjne a,#0,JUDEGSIG_10
sjmp JUDEGSIG_12 //两数同为正
JUDEGSIG_10:
cjne a,#3,JUDEGSIG_15
JUDEGSIG_12: //两数同为负
movx a,@dptr
anl a,#11111011b //结果为正
sjmp JUDEGSIG_16
JUDEGSIG_15:
movx a,@dptr
orl a,#00000100b //结果为负
JUDEGSIG_16:
mov b,a
mov a,r0
cjne a,#11101111b,JUDEGSIG_18
anl a,b //未溢出
sjmp JUDEGSIG_20
JUDEGSIG_18:
orl a,b //溢出
JUDEGSIG_20:
movx @dptr,a
ret
;********************************
; 多字节无符号 BCD 码加法
;OUT:
; R0=0x10 结果溢出标志.
; R0=0xef 正常状况下
;********************************
MBCD_ADD_NS:
lcall CHANGECOPY
lcall MBIN_ADD ;R3 未改变,仍然是#LENTH
jc Mbcd_Ad100 ;如果结果溢出(此分支不可能,因为俩7字节BIN加不会溢出8字节)
lcall COMPTOMAX ;取结果送到临时区转换为BCD,并与极大值相比较 out: R7
mov a,r7
cjne a,#2,Mbcd_Ad200 ;小于等于最大值
Mbcd_Ad100:
mov r0,#LENTH
mov dptr,#(TEMPSTART+BCDD3BUF)
lcall Calcul_Clear
mov r0,#00010000b ;设置标志 r0=0x10 结果溢出
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -