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

📄 136_zhj.asm

📁 一、本程序完成功能要求: 完成两个压缩的8位多字节无符号BCD数相加的程序段。要求提供调试通过的源代码、可执行程序和编程小结readme.txt文件。 两个操作数可以由键盘输入。输出要求:在屏幕
💻 ASM
字号:
;//////////////////////////////////////////////////////////////////
;日期:	2008-03-19
;代码名称:138_ZHJ
;编程者:张宏基
;程序功能:	完成两个压缩的8位多字节无符号BCD数相加的程序段。
;	两个操作数可以由键盘输入或者在数据段定义(常数)。
;	输出要求:在屏幕上显示出参与运算的两个加数和结果和。
;//////////////////////////////////////////////////////////////////
;------------------------------------------------------------------------------------------
.MODEL SMALL
.STACK 64
.DATA

;定义第一个加数存储结构
FirstPRAM  	LABEL	BYTE		
FirstMaxL		DB	9
FisrtActL		DB 	?
FirstADD	DB	9	DUP(0)

;定义第二个加数存储结构
SecondPRAM	LABEL	BYTE		
SesondMaxL		DB	9
SecondActL		DB	?
SecondADD	DB	9	DUP(0)

ONE	DB      4	DUP(0)
TWO	DB		4	DUP(0)
SUM		DB	6	DUP(' ')	
Result		DB	11      DUP(0)

LEFTSPACE		EQU	10
ROWSPACE		EQU	03
COL		DB	00
ROW		DB	00

;定义程序运行过程中会出现的字符串
MESSEG1		DB	'FIRST NUMBER:    '
MESSEG2		DB	'SECOND NUMBER:   '
MSSSEG3		DB	'RESULT:   '
.386
;-------------------------------------------------------------------------------------------


		.CODE						;数据区
main		PROC 	FAR
		MOV 	AX,	@DATA			;进行初始化
		MOV 	DS,	AX
		MOV	ES,	AX
		MOV	AX,	0003H
		INT	10H
		
		CALL	BPUT				;调用BPUT要求用户输入两个BCD数
		
		MOV	AL,	FisrtActL				;如果输入的第一个加数的值不满8位
		LEA	SI,	FirstADD			;则礒xpandTO8扩展为8位
		LEA	DI,	FirstADD+08			;其中进行高位补'0'并存到FirstADD	

		
		MOV	AL,	SecondActL				;如果输入的第二个加数的值不满8位
		LEA	SI,	SecondADD			;则礒xpandTO8扩展为8位
		LEA	DI,	SecondADD+08		;其中进行高位补'0'并存到SecondADD

		
		CALL	BCDADD				;调用BCDADD进行BCD数的相SUM结果存到BCDRES中
		
		LEA     SI,	SUM+4		;将计算得到的BCD数结果
		LEA  	DI,	Result+10		;转换成ASCII字符
		CALL	AConvert			;并存入Result中

		
		CALL 	DISPLAY			;调DISPLAY将计算的结果显示
		
		MOV	AH,	01H
		INT	21H
		MOV	AX,	4C00H				;设置中断结束程序
		INT	21H
main		ENDP


;
;从键盘接受两个量并把他们存储到定义好的FirstADD和SecondADD中
;--------------------------------------------------------------------------------------------
BPUT	PROC	NEAR				;使用到AX BP CX SI
		MOV 	ROW,	ROWSPACE+1		;设置行
		MOV	COL,	LEFTSPACE+3		;设置列
		LEA	BP,	MESSEG1				;提示输入第一个数
		MOV 	CX,	17d				;字符数
		CALL 	KDISPLAY
		MOV	AH,	0AH					;从键盘接受并存放到
		LEA	DX,	FirstPRAM			;FirstADD中
		INT	21H
		
		MOV 	COL,	LEFTSPACE+3
		INC	ROW						;下一行
		LEA	BP,	MESSEG2				;提示输入第二个数
		MOV 	CX,	17d				;字符数
		CALL 	KDISPLAY
		MOV	AH,	0AH					;从键盘接受并存放到
		LEA	DX,	SecondPRAM			;SecondADD中
		INT	21H
		INC	ROW
		RET
BPUT	ENDP




;显示字符,其中BP中存放要显示的字符的地址,CX中存放要显示的字符个数
;-----------------------------------------------------------------------------------------------
KDISPLAY	PROC	NEAR			;BP,CX在入口处设置

		MOV	AX,	1301H				;请求显示行
		MOV	BX,	000FH				;页和属性
		MOV	DH,	ROW					;屏幕行
		MOV	DL,	COL					;屏幕列
		
		INT	10H
		RET
KDISPLAY	ENDP




;用来显示计算得到的结果
;-----------------------------------------------------------------------------------------------
DISPLAY	PROC	NEAR

		INC	ROW
		LEA	BP,	MSSSEG3				;将"The Result is : "的地址装入BP
		MOV 	CX,	10d				;设置显示的字符数			
		CALL 	KDISPLAY			;调KDISPLAY显示"The Result is :"

		MOV	AH,	02H					;调用02中断
		MOV 	CX, 	9			;字符数初始化为9
		LEA	DI,	Result+2			;装入存着计算结果的地址
    LLL:	MOV	DL, 	[DI]			;
 		SUB 	DL, 	30H			;LLL部分用来判断存放的计算
 		JNZ 	XXX					;结果首位是不是为了
 		INC 	DI					;如果是就跳过不显示
 		DEC 	CX					;因为计算结果首位不可能为0
 		JMP 	LLL
 XXX:	
 		MOV	DL, 	[DI]			;利用02中断显示计算结果
 		INT 	21H
		INC 	DI
		LOOP 	XXX 
		 
		RET
DISPLAY	ENDP		

;将存储在FirstADD和SecondADD里的两个数取出来相加
;------------------------------------------------------------------------------------------------
BCDADD		PROC	NEAR
		LEA	SI,	FirstADD+8			;将FirstADD里的ASCII数据取出
		LEA	DI,	ONE+4				;进行BCD转换后
		CALL	BConvert			;存入ONE里
		LEA	SI,	SecondADD+8			;将SecondADD里的ASCII数据取出
		LEA	DI,	TWO+4				;进行BCD转换后
		CALL	BConvert			;存入TWO里
		
		XOR	AH,	AH
		LEA	SI,	ONE+3				;取第一个加数地址
		LEA	DI,	TWO+3				;取第二个加数地址
		LEA	BX,	SUM+4			;取存放BCD结果数地址
		MOV	CX,	04
	NEXT:	
		MOV	AL,	[SI]				;将被加数移入
		ADC	AL,	[DI]				;将加数移入
		DAA							;BCD加法调整
		MOV	[BX],	AL				;存入结果
		DEC	SI						;第一个加数地址减1
		DEC	DI						;第一个加数地址减1
		DEC	BX						;结果地址减1
		LOOP	NEXT
		
		MOV	AL,	0
		ADC	AL,	0
		DAA							;这一步是为了防止最高位有进位
		MOV	[BX],	AL
		RET	
BCDADD		ENDP



;将ASCII码字符转换成压缩BCD码
;--------------------------------------------------------------------------------------------------

BConvert	PROC 	NEAR
		MOV	CX,	05					;设置循环次数
	B:	MOV	AX,	[SI]				;取一个字			
		XCHG	AH,	AL				;高低字节互换
		SHL	AL,	04					;AL左移4位
		SHL	AX,	04					;AX左移4位
		MOV	[DI],	AH				;存入DI指向的存储器中
		DEC	SI						;源地址减1
		DEC	SI						;目标地址减1
		DEC	DI
		LOOP	B
		RET
BConvert	ENDP



;将存SUMDRES里的BCD结果数转换为ASCII字符
;-----------------------------------------------------------------------------------------------------
AConvert	PROC	NEAR
		MOV	CX,	05H
	PPP:	
		MOV	AL,	[SI]				;取源操作数,一个字节
		MOV	BL,	AL
		AND	AL,	0FH					;将高4位清0
		ADD	AL,	30H					;加30h变成ASCII字符
		MOV	[DI],	AL				;存入目的操作数
		DEC	DI						;下一个目的操作数地址
		SHR	BL,	04H					;取高四位11
		ADD	BL,	30H					;加30h变成ASCII字符
		MOV	[DI],	BL				;存入目的操作数
		DEC	DI						;下一个目的操作数地址
		DEC	SI
		LOOP	PPP
		RET
AConvert	ENDP


;如果输入的数不满8位,将其扩展为8位并存到FirstADD和SecondADD中
;-----------------------------------------------------------------------------------------------------
Expand	PROC 	NEAR
		MOVZX	BX,	AL				;暂存AL
		MOVZX	CX,	AL
		INC	CX
		CMP	AL,	08					;如果输入是8位,则直接结束返回
		JE	F
		ADD	SI,	BX					;如果不是,则取得存放的数的最后一位以备用来扩展成8位
	D:	
		MOV	AL,	[SI]				;这个循环是用来将存放的数扩展的,例如输入为12345
		MOV	[DI],	AL				;经过这个循环后变为12312345
		DEC	SI						;下面还要做一个将前面的8-AL位清0的工作
		DEC	DI						;
		LOOP	D
		MOV	AX,	08
		SUB	AX,	BX
		MOV	CX,	AX					;计算得到8-AL,即要清0的位数
		MOV	AL,	' '					;将0装入AL
	E:	
		MOV	[DI],	AL				;清0
		DEC	DI
		LOOP	E
     	F:	
		RET
Expand	ENDP



		END	main

⌨️ 快捷键说明

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