⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 calc.asm

📁 51计算器源代码,4*4键盘输入,采用浮点算法设计的
💻 ASM
📖 第 1 页 / 共 4 页
字号:
           MOV A, @R0
           INC R0
           INC A
           JZ DISP_DP
           DEC A
DISP_LOOKUP:
           MOVC A, @A+DPTR
           MOV DAT, A
           LCALL PR2
           LCALL DELAY
           DJNZ TEMP1, DISP_NORMAL
           SJMP DISP_DONE
           ; -----------
DISP_ZERO:
           MOV A, #00H ; '0'
           MOV TEMP1, #01H
           SJMP DISP_LOOKUP
           ; --------------
DISP_DP: ; DISPLAY, DECIMAL POINT
           MOV A, #0AH
           SJMP DISP_LOOKUP
           ; -----------
DISP_ERR:
           MOV A, #0CH ; 'E'
           MOVC A, @A+DPTR
           MOV DAT, A
           LCALL PR2
           LCALL DELAY
           SJMP DISP_DONE
; ----------------
DISP_DONE:
 RET
;=================
DISPTAB:
           DB 30H,31H,32H,33H,34H,35H,36H,37H, 38H, 39H
           DB 2EH, 2DH, 45H ; '.', '-', 'E'
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

; =======================================================

;;***************************************
;; LCD 初始化程序
;;***************************************
LCDINIT:
           MOV   A,#30H
           MOV   DPTR,#CW_ADD
           MOV   R2,#03H
LCDINT1:
           MOVX  @DPTR,A
           LCALL DELAY
           DJNZ  R2,LCDINT1
           MOV   COM,#38H
           LCALL PR1
           MOV   COM,#01H
           LCALL PR1
           MOV   COM,#06H     ;设置输入方式
           LCALL PR1
           MOV   COM,#0FH
           LCALL PR1
           RET


;********************************
;读BF和AC值
;********************************


PR0:
           PUSH  DPH
           PUSH  DPL
           PUSH  ACC
           MOV   DPTR,#CR_ADD
           MOVX  A,@DPTR
           MOV   COM,A
           POP   ACC
           POP   DPL
           POP   DPH
           RET
;********************************
;写指令代码字程序
;********************************

PR1:
           PUSH  DPH
           PUSH  DPL
           PUSH  ACC
           MOV   DPTR,#CR_ADD
PR11:
           MOVX  A,@DPTR
           JB    ACC.7,PR11
           MOV   A,COM
           MOV   DPTR,#CW_ADD
           MOVX  @DPTR,A
           POP   ACC
           POP   DPL
           POP   DPH
           RET
;********************************
;写显示数据子程序
;********************************
PR2:
           PUSH   DPH
           PUSH   DPL
           PUSH   ACC
           MOV    DPTR,#CR_ADD
PR21:
           MOVX   A,@DPTR
           JB     ACC.7,PR21
           MOV    A,DAT
           MOV    DPTR,#DW_ADD
           MOVX   @DPTR,A
           POP    ACC
           POP    DPL
           POP    DPH
           RET
;********************************
;读显示数据子程序
;********************************
PR3:
           PUSH   DPH
           PUSH   DPL
           PUSH   ACC
           MOV    DPTR,#CR_ADD
PR31:
           MOVX   A,@DPTR
           JB     ACC.7,PR31
           MOV    DPTR,#DR_ADD
           MOVX   A,@DPTR
           MOV    DAT,A
           POP    ACC
           POP    DPL
           POP    DPH
           RET

;*****************************************
;  DELAY
;*****************************************
DELAY:
           MOV   R6,#02H
           MOV   R7,#02H
DELAY1:
           NOP
           DJNZ  R7,DELAY1
           DJNZ  R6,DELAY1
           RET


; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; FLOATLIB          浮点程序库
; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

; ===========================================================

;(1) 标号: FSDT 功能:浮点数格式化

;入口条件:待格式化浮点操作数在[R0]中。
;出口信息:已格式化浮点操作数仍在[R0]中。
;影响资源:PSW、A、R2、R3、R4、位1FH 堆栈需求: 6字节
FSDT: LCALL MVR0 ; 将待格式化操作数传送到第一工作区中
LCALL RLN ; 通过左规完成格式化
LJMP MOV0 ; 将已格式化浮点操作数传回到[R0]中

;(2) 标号: FADD 功能:浮点数加法

;入口条件:被加数在[R0]中,加数在[R1]中。
;出口信息:OV=0时,和仍在[R0]中,OV=1时,溢出。
;影响资源:PSW、A、B、R2~R7、位1EH、1FH 堆栈需求: 6字节
FADD:
           CLR F0 ; 设立加法标志
           SJMP AS ; 计算代数和

;(3) 标号: FSUB 功能:浮点数减法

;入口条件:被减数在[R0]中,减数在[R1]中。
;出口信息:OV=0时,差仍在[R0]中,OV=1时,溢出。
;影响资源:PSW、A、B、R2~R7、位1EH、1FH 堆栈需求:6字节
FSUB:
           SETB F0 ; 设立减法标志
AS:
           LCALL MVR1 ; 计算代数和。先将[R1]传送到第二工作区
           MOV C,F0 ; 用加减标志来校正第二操作数的有效符号
           RRC A
           XRL A,@R1
           MOV C,ACC.7
ASN:
           MOV 1EH,C ; 将第二操作数的有效符号存入位1EH中
           XRL A,@R0 ; 与第一操作数的符号比较
           RLC A
           MOV F0,C ; 保存比较结果
           LCALL MVR0 ; 将[R0]传送到第一工作区中
           LCALL AS1 ; 在工作寄存器中完成代数运算
MOV0:
           INC R0 ; 将结果传回到[R0]中的子程序入口
           INC R0
           MOV A,R4 ; 传回尾数的低字节
           MOV @R0,A
           DEC R0
           MOV A,R3 ; 传回尾数的高字节
           MOV @R0,A
           DEC R0
           MOV A,R2 ; 取结果的阶码
           MOV C,1FH ; 取结果的数符
           MOV ACC.7,C ; 拼入阶码中
           MOV @R0,A
           CLR ACC.7 ; 不考虑数符
           CLR OV ; 清除溢出标志
           CJNE A,#3FH,MV01; 阶码是否上溢?
           SETB OV ; 设立溢出标志
MV01:
           MOV A,@R0 ; 取出带数符的阶码
           RET
MVR0:
           MOV A,@R0 ; 将[R0]传送到第一工作区中的子程序
           MOV C,ACC.7 ; 将数符保存在位1FH中
           MOV 1FH,C
           MOV C,ACC.6 ; 将阶码扩充为8bit补码
           MOV ACC.7,C
           MOV R2,A ; 存放在R2中
           INC R0
           MOV A,@R0 ; 将尾数高字节存放在R3中
           MOV R3,A
           INC R0
           MOV A,@R0 ; 将尾数低字节存放在R4中
           MOV R4,A
           DEC R0 ; 恢复数据指针
           DEC R0
           RET
MVR1:
           MOV A,@R1 ; 将[R1]传送到第二工作区中的子程序
           MOV C,ACC.7 ; 将数符保存在位1EH中
           MOV 1EH,C
           MOV C,ACC.6 ; 将阶码扩充为8bit补码
           MOV ACC.7,C
           MOV R5,A ; 存放在R5中
           INC R1
           MOV A,@R1 ; 将尾数高字节存放在R6中
           MOV R6,A
           INC R1
           MOV A,@R1 ; 将尾数低字节存放在R7中
           MOV R7,A
           DEC R1 ; 恢复数据指针
           DEC R1
           RET
AS1:
           MOV A,R6 ; 读取第二操作数尾数高字节
           ORL A,R7
           JZ AS2 ; 第二操作数为零,不必运算
           MOV A,R3 ; 读取第一操作数尾数高字节
           ORL A,R4
           JNZ EQ1
           MOV A,R6 ; 第一操作数为零,结果以第二操作数为准
           MOV R3,A
           MOV A,R7
           MOV R4,A
           MOV A,R5
           MOV R2,A
           MOV C,1EH
           MOV 1FH,C
AS2:
           RET
EQ1:
           MOV A,R2 ; 对阶,比较两个操作数的阶码
           XRL A,R5
           JZ AS4 ; 阶码相同,对阶结束
           JB ACC.7,EQ3; 阶符互异
           MOV A,R2 ; 阶符相同,比较大小
           CLR C
           SUBB A,R5
           JC EQ4
EQ2:
           CLR C ; 第二操作数右规一次
           MOV A,R6 ; 尾数缩小一半
           RRC A
           MOV R6,A
           MOV A,R7
           RRC A
           MOV R7,A
           INC R5 ; 阶码加一
           ORL A,R6 ; 尾数为零否?
           JNZ EQ1 ; 尾数不为零,继续对阶
           MOV A,R2 ; 尾数为零,提前结束对阶
           MOV R5,A
           SJMP AS4
EQ3:
           MOV A,R2 ; 判断第一操作数阶符
           JNB ACC.7,EQ2; 如为正,右规第二操作数
EQ4:
           CLR C
           LCALL RR1 ; 第一操作数右规一次
           ORL A,R3 ; 尾数为零否?
           JNZ EQ1 ; 不为零,继续对阶
           MOV A,R5 ; 尾数为零,提前结束对阶
           MOV R2,A
AS4:
           JB F0,AS5 ; 尾数加减判断
           MOV A,R4 ; 尾数相加
           ADD A,R7
           MOV R4,A
           MOV A,R3
           ADDC A,R6
           MOV R3,A
           JNC AS2
           LJMP RR1 ; 有进位,右规一次
AS5:
           CLR C ; 比较绝对值大小
           MOV A,R4
SUBB A,R7
MOV B,A
MOV A,R3
SUBB A,R6
JC AS6
MOV R4,B ; 第一尾数减第二尾数
MOV R3,A
LJMP RLN ; 结果规格化
AS6: CPL 1FH ; 结果的符号与第一操作数相反
CLR C ; 结果的绝对值为第二尾数减第一尾数
MOV A,R7
SUBB A,R4
MOV R4,A
MOV A,R6
SUBB A,R3
MOV R3,A
RLN: MOV A,R3 ; 浮点数规格化
ORL A,R4 ; 尾数为零否?
JNZ RLN1
MOV R2,#0C1H; 阶码取最小值
RET
RLN1: MOV A,R3
JB ACC.7,RLN2; 尾数最高位为一否?
CLR C ; 不为一,左规一次
LCALL RL1
SJMP RLN ; 继续判断
RLN2: CLR OV ; 规格化结束
RET
RL1: MOV A,R4 ; 第一操作数左规一次
RLC A ; 尾数扩大一倍
MOV R4,A
MOV A,R3
RLC A
MOV R3,A
DEC R2 ; 阶码减一
CJNE R2,#0C0H,RL1E; 阶码下溢否?
CLR A
MOV R3,A ; 阶码下溢,操作数以零计
MOV R4,A
MOV R2,#0C1H
RL1E: CLR OV
RET
RR1: MOV A,R3 ; 第一操作数右规一次
RRC A ; 尾数缩小一半
MOV R3,A
MOV A,R4
RRC A
MOV R4,A
INC R2 ; 阶码加一
CLR OV ; 清溢出标志
CJNE R2,#40H,RR1E; 阶码上溢否?
MOV R2,#3FH ; 阶码溢出
SETB OV
RR1E: RET

;(4) 标号: FMUL 功能:浮点数乘法

;入口条件:被乘数在[R0]中,乘数在[R1]中。
;出口信息:OV=0时,积仍在[R0]中,OV=1时,溢出。
;影响资源:PSW、A、B、R2~R7、位1EH、1FH 堆栈需求:6字节
HCQ1:
FMUL:
 LCALL MVR0 ; 将[R0]传送到第一工作区中
MOV A,@R0
XRL A,@R1 ; 比较两个操作数的符号
RLC A
MOV 1FH,C ; 保存积的符号
LCALL MUL0 ; 计算积的绝对值
LJMP MOV0 ; 将结果传回到[R0]中
MUL0: LCALL MVR1 ; 将[R1]传送到第二工作区中
MUL1: MOV A,R3 ; 第一尾数为零否?
ORL A,R4
JZ MUL6
MOV A,R6 ; 第二尾数为零否?
ORL A,R7
JZ MUL5
MOV A,R7 ; 计算R3R4×R6R7-→R3R4
MOV B,R4
MUL AB
MOV A,B
XCH A,R7
MOV B,R3
MUL AB
ADD A,R7
MOV R7,A
CLR A
ADDC A,B
XCH A,R4
MOV B,R6
MUL AB
ADD A,R7
MOV R7,A
MOV A,B
ADDC A,R4
MOV R4,A
CLR A
RLC A
XCH A,R3
MOV B,R6
MUL AB
ADD A,R4
MOV R4,A
MOV A,B
ADDC A,R3
MOV R3,A
JB ACC.7,MUL2; 积为规格化数否?
MOV A,R7 ; 左规一次
RLC A
MOV R7,A
LCALL RL1
MUL2: MOV A,R7
JNB ACC.7,MUL3
INC R4
MOV A,R4
JNZ MUL3
INC R3
MOV A,R3
JNZ MUL3
MOV R3,#80H
INC R2
MUL3: MOV A,R2 ; 求积的阶码
ADD A,R5
MD: MOV R2,A ; 阶码溢出判断
JB ACC.7,MUL4
JNB ACC.6,MUL6
MOV R2,#3FH ; 阶码上溢,设立标志
SETB OV
RET
MUL4: JB ACC.6,MUL6
MUL5: CLR A ; 结果清零(因子为零或阶码下溢)
MOV R3,A
MOV R4,A
MOV R2,#41H
MUL6: CLR OV
RET

;(5) 标号: FDIV 功能:浮点数除法

;入口条件:被除数在[R0]中,除数在[R1]中。
;出口信息:OV=0时,商仍在[R0]中,OV=1时,溢出。
;影响资源:PSW、A、B、R2~R7、位1EH、1FH 堆栈需求: 5字节
FDIV: INC R0
MOV A,@R0
INC R0
ORL A,@R0
DEC R0
DEC R0
JNZ DIV1
MOV @R0,#41H; 被除数为零,不必运算
CLR OV
RET
DIV1: INC R1
MOV A,@R1
INC R1
ORL A,@R1
DEC R1
DEC R1
JNZ DIV2
SETB OV ; 除数为零,溢出
RET
DIV2: LCALL MVR0 ; 将[R0]传送到第一工作区中
MOV A,@R0
XRL A,@R1 ; 比较两个操作数的符号
RLC A
MOV 1FH,C ; 保存结果的符号
LCALL MVR1 ; 将[R1]传送到第二工作区中
LCALL DIV3 ; 调用工作区浮点除法
LJMP MOV0 ; 回传结果
DIV3: CLR C ; 比较尾数的大小
MOV A,R4
SUBB A,R7
MOV A,R3
SUBB A,R6
JC DIV4
LCALL RR1 ; 被除数右规一次
SJMP DIV3
DIV4: CLR A ; 借用R0R1R2作工作寄存器
XCH A,R0 ; 清零并保护之
PUSH ACC
CLR A
XCH A,R1
PUSH ACC
MOV A,R2
PUSH ACC
MOV B,#10H ; 除法运算,R3R4/R6R7-→R0R1
DIV5: CLR C
MOV A,R1
RLC A
MOV R1,A
MOV A,R0
RLC A
MOV R0,A
MOV A,R4
RLC A
MOV R4,A
XCH A,R3
RLC A
XCH A,R3
MOV F0,C
CLR C
SUBB A,R7
MOV R2,A
MOV A,R3
SUBB A,R6
ANL C,/F0
JC DIV6
MOV R3,A
MOV A,R2
MOV R4,A
INC R1
DIV6: DJNZ B,DIV5
MOV A,R6 ; 四舍五入
CLR C
RRC A
SUBB A,R3
CLR A

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -