实验二 两个多位十进制数相加实验
一、实验目的
1.掌握汇编子程序的编写方法。
2.掌握循环程序的设计方法。
二、实验内容
将键盘输入的两个5位十进制数相加,在屏幕上显示相加的结果。
三、实验要求
1.显示格式:被加数+加数=相加的结果;
2.考虑运算结果最高位有进位的情况。
3.输入和显示分别用子程序实现。
四、实验程序(必须加注释)和结果
实验代码:
; 定义一个名为crlf的宏,用于输出回车换行符
crlf macro
; 将AH寄存器设置为2,表示调用21h中断的字符输出功能
mov ah,2
; 将DL寄存器设置为0dh,即回车符(Carriage Return)的ASCII码值
mov dl,0dh
; 调用21h号中断,功能为输出一个字符,这里输出回车符
int 21h
; 再次将AH寄存器设置为2,为下一次字符输出做准备
mov ah,2
; 将DL寄存器设置为0ah,即换行符(Line Feed)的ASCII码值
mov dl,0ah
; 再次调用21h号中断,输出换行符
int 21h
endm
; 定义数据段
DATAS SEGMENT
; 定义data1,初始化为5个字节的0,后面跟着'+'和字符串结束标志'$'
data1 db 5 dup(0)
db '+','$'
; 定义data2,初始化为5个字节的0,后面跟着'='和字符串结束标志'$'
data2 db 5 dup(0)
db '=','$'
; 定义data3,初始化为5个字节的0,后面跟着字符串结束标志'$'
data3 db 5 dup(0)
db '$'
; 定义mess1,这是一个提示输入data1的字符串
mess1 db 'input data1:$'
; 定义mess2,这是一个提示输入data2的字符串
mess2 db 'input data2:$'
; 定义mess3,可能是用于显示一些标识信息(如作者或程序相关的标识)
mess3 db 'GUOZHIHONG Kruanjian221 2022900624',0DH,0AH,'$'
; 定义againMess,这是一个询问是否继续的字符串
againMess db 'Do you want to continue? (y/n):$'
; 此处可添加更多数据段相关的定义
DATAS ENDS
; 定义代码段
CODES SEGMENT
ASSUME CS:CODES,DS:DATAS
; 输入数据1的子程序
input_data1 PROC
; 调用21h号中断的9号功能,输出提示信息mess1
mov ah,9
mov dx,offset mess1
int 21h
; 将DI寄存器设置为data1的偏移地址,用于后续存储输入字符
mov di,offset data1
; 设置循环计数器CX为5,表示要接收5个字符
mov cx,5
input_data1_loop:
; 将AH寄存器设置为1,表示调用21h中断的字符输入功能
mov ah,1
; 调用21h号中断,输入一个字符
int 21h
; 将输入的字符存储到data1中,DI指向存储位置
mov [di],al
; 递增DI寄存器,指向下一个存储位置
inc di
; 循环,直到CX为0,即接收完5个字符
loop input_data1_loop
; 子程序返回
ret
input_data1 ENDP
; 输入数据2的子程序
input_data2 PROC
; 调用21h号中断的9号功能,输出提示信息mess2
mov ah,9
mov dx,offset mess2
int 21h
; 将DI寄存器设置为data2的偏移地址,用于后续存储输入字符
mov di,offset data2
; 设置循环计数器CX为5,表示要接收5个字符
mov cx,5
input_data2_loop:
; 将AH寄存器设置为1,表示调用21h中断的字符输入功能
mov ah,1
; 调用21h号中断,输入一个字符
int 21h
; 将输入的字符存储到data2中,DI指向存储位置
mov [di],al
; 递增DI寄存器,指向下一个存储位置
inc di
; 循环,直到CX为0,即接收完5个字符
loop input_data2_loop
; 子程序返回
ret
input_data2 ENDP
; 计算结果的子程序
calculate_result PROC
; 设置循环计数器CX为5,表示要对5个字符进行计算
mov cx,5
; 将SI寄存器设置为5,用于从后往前访问data1和data2中的字符
mov si,5
calculate_result_loop:
; 取data1中倒数第SI个字符的ASCII码值到AL寄存器
mov al,data1[si - 1]
; 带进位加法,将data2中倒数第SI个字符的ASCII码值与AL相加
adc al,data2[si - 1]
; 对加法结果进行ASCII码调整(用于非压缩BCD码加法)
aaa
; 保存标志寄存器的值到栈中
pushf
; 将计算结果转换为ASCII码(数字0 - 9的ASCII码为30h - 39h)
add al,30h
; 将计算结果存储到data3中倒数第SI个位置
mov data3[si - 1],al
; 从栈中恢复标志寄存器的值
popf
; 递减SI寄存器,指向前一个字符位置
dec si
; 循环,直到CX为0,即完成5个字符的计算
loop calculate_result_loop
; 如果没有进位则跳转到no_carry标签
jnc no_carry
; 如果有进位,将AH寄存器设置为2,表示调用21h中断的字符输出功能
mov ah,2
; 将DL寄存器设置为31h,即字符'1'的ASCII码值
mov dl,31h
; 调用21h号中断,输出字符'1'
int 21h
no_carry:
; 子程序返回
ret
calculate_result ENDP
; 显示结果的子程序
show_result PROC
; 调用21h号中断的9号功能,输出data3中的结果
mov ah,9
mov dx,offset data3
int 21h
; 调用crlf宏,输出回车换行符
crlf
; 子程序返回
ret
show_result ENDP
; 询问是否继续的子程序
ask_continue PROC
; 调用21h号中断的9号功能,输出询问是否继续的字符串againMess
mov ah,9
mov dx,offset againMess
int 21h
; 将AH寄存器设置为1,表示调用21h中断的字符输入功能
mov ah,1
; 调用21h号中断,输入一个字符
int 21h
; 子程序返回
ret
ask_continue ENDP
START:
; 将数据段地址赋给DS寄存器
MOV AX,DATAS
MOV DS,AX
again:
; 调用21h号中断的9号功能,输出mess3字符串
mov ah,9
mov dx,offset mess3
int 21h
; 调用输入data1的子程序
call input_data1
; 调用crlf宏,输出回车换行符
crlf
; 调用输入data2的子程序
call input_data2
; 调用crlf宏,输出回车换行符
crlf
; 调用21h号中断的9号功能,分别输出data1和data2
mov ah,9
mov dx,offset data1
int 21h
mov ah,9
mov dx,offset data2
int 21h
; 调用计算结果的子程序
call calculate_result
; 调用显示结果的子程序
call show_result
; 调用询问是否继续的子程序
call ask_continue
; 比较输入的字符是否为'y'
cmp al,'y'
; 如果是'y',则跳转到continue_again标签
je continue_again
; 比较输入的字符是否为'n'
cmp al,'n'
; 如果是'n',则跳转到exit标签
je exit
; 如果不是'y'或'n',则跳转到show_result标签
jmp show_result
continue_again:
; 调用crlf宏,输出回车换行符
crlf
; 跳转到again标签,重新开始一轮操作
jmp again
exit:
; 将AH寄存器设置为4Ch,表示调用21h中断的程序结束功能
MOV AH,4CH
; 调用21h号中断,结束程序并返回操作系统
INT 21H
CODES ENDS
END START
设计思路:
(一)宏定义(crlf宏)
功能
输出回车换行符,提高代码复用性。
实现原理
利用21h中断的字符输出功能,先输出回车符再输出换行符。
(二)数据段
数据存储
data1、data2、data3:分别存储输入数据和计算结果,有特定初始化。
提示字符串:如mess1、mess2等,用于显示提示信息。
(三)代码段
1. 输入数据子程序
功能:接收用户输入并存入相应变量,input_data1和input_data2操作类似。
实现:输出提示信息后循环接收字符并存入变量。
2. 计算结果子程序
功能:计算data1和data2相加结果存入data3。
实现:从后往前按ASCII码计算,处理进位并转换结果存入data3。
3. 显示结果子程序
功能:输出data3结果并回车换行。
4. 询问是否继续子程序
功能:输出询问字符串并接收用户输入返回。
5. 主程序
流程:初始化后循环执行输入、计算、显示、询问操作。
判断跳转:根据用户输入决定是继续循环、结束程序还是重新询问。