当前位置: 首页 > news >正文

实验二 两个多位十进制数相加实验

一、实验目的               

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

    ; 设置循环计数器CX5,表示要接收5个字符

    mov cx,5

input_data1_loop:

    ; AH寄存器设置为1,表示调用21h中断的字符输入功能

    mov ah,1

    ; 调用21h号中断,输入一个字符

    int 21h

    ; 将输入的字符存储到data1中,DI指向存储位置

    mov [di],al

    ; 递增DI寄存器,指向下一个存储位置

    inc di

    ; 循环,直到CX0,即接收完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

    ; 设置循环计数器CX5,表示要接收5个字符

    mov cx,5

input_data2_loop:

    ; AH寄存器设置为1,表示调用21h中断的字符输入功能

    mov ah,1

    ; 调用21h号中断,输入一个字符

    int 21h

    ; 将输入的字符存储到data2中,DI指向存储位置

    mov [di],al

    ; 递增DI寄存器,指向下一个存储位置

    inc di

    ; 循环,直到CX0,即接收完5个字符

    loop input_data2_loop

    ; 子程序返回

    ret

input_data2 ENDP

; 计算结果的子程序

calculate_result PROC

    ; 设置循环计数器CX5,表示要对5个字符进行计算

    mov cx,5

    ; SI寄存器设置为5,用于从后往前访问data1data2中的字符

    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 - 9ASCII码为30h - 39h

    add al,30h

    ; 将计算结果存储到data3中倒数第SI个位置

    mov data3[si - 1],al

    ; 从栈中恢复标志寄存器的值

    popf

    ; 递减SI寄存器,指向前一个字符位置

    dec si

    ; 循环,直到CX0,即完成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号功能,分别输出data1data2

    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. 主程序

流程:初始化后循环执行输入、计算、显示、询问操作。

判断跳转:根据用户输入决定是继续循环、结束程序还是重新询问。

相关文章:

  • IPC(进程间通信)---- 信号
  • Java实现AES加密解密终极指南:从基础到高阶实战
  • Python网络编程从入门到精通:Socket核心技术+TCP/UDP实战详解
  • 实战指南 | 通过 Amazon Bedrock 快速接入 DeepSeek-R1 大模型
  • 最佳归并树的虚短怎么处理
  • 【刷题2025】贪心算法+KMP算法+暴力枚举+扫描树线段树+LFU缓存
  • Hanks 液环境镍钛合金应力腐蚀试验机
  • Java练习——day1(反射)
  • 【嵌入式八股4】C++:引用、模板、哈希表与 I/O
  • LeetCode算法题(Go语言实现)_47
  • 操作系统导论——第22章 超越物理内存:策略
  • 基于x86/RK3568电力新能源智能变电站一体化装置
  • CMS 垃圾收集器深度解析
  • 《计算机视觉度量:从特征描述到深度学习》—生成式人工智能在工业检测的应用
  • ceph scrub 导致业务问题优化
  • 【Dify(v1.2) 核心源码深入解析】Agent 模块
  • 深入讲解 CSS 选择器权重及实战
  • 【刷题2025】单指针双指针+滑动窗口+二分法三分法+区间问题
  • 如何一键检查网页里的失效链接和废弃域名?
  • 【加密算法】SM2密钥生成与转换详解:从原理到代码实现
  • 世界免疫周丨专家呼吁加快HPV疫苗纳入国家免疫规划进程
  • 王珊珊读《吾自绝伦》|摘掉皮普斯的“假发”
  • 广西一季度GDP为6833.92亿元,同比增长5.8%
  • 上海银行换帅,顾建忠已任党委书记
  • 常方舟评《心的表达》|弗洛伊德式精神分析在我们时代的延展
  • 分离19年后:陈杨梅首度露面,父亲亲手喂棉花糖给女儿吃