【实验作业】微处理器原理与应用 CPUHomework3【子程序汇编实验 流程图 十六进制数转十进制数 键盘录入 屏幕显示 闰年判断 两位数求和 汇编小程序】

本文主要是介绍【实验作业】微处理器原理与应用 CPUHomework3【子程序汇编实验 流程图 十六进制数转十进制数 键盘录入 屏幕显示 闰年判断 两位数求和 汇编小程序】,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

文章目录

  • 实验报告
  • 实验三 子程序汇编实验学习和提高
    • 汇编语言中的 ASSUME 伪指令和标准的汇编程序
    • 1. 复习 Debug -P 和 -G
    • 2. 将键盘上输入的十六进制数转换成十进制数,并在屏幕上显示
    • 3. 较为复杂的汇编实例学习:判断该年是否为闰年
    • 4. 汇编实例学习和改进:两位数加法
  • 【基础学习】
    • 栈的定义
    • 显示提示信息方法
    • 键盘输入方式
      • 从键盘输入一个字符串到缓冲区(AH=0AH)
    • mul 乘法指令
    • 实验心得
  • 【程序欣赏】

实验报告

课程名称:微处理器原理与应用

实验名称:CPUHomework3

实验时间:2022年10月16日

实验三 子程序汇编实验学习和提高

汇编语言中的 ASSUME 伪指令和标准的汇编程序

ASSUME伪指令,通知汇编程序(编译器)代码段,数据段,附加段以及堆栈段选择什么名字

没有 ASSUME 伪指令时,汇编程序假设不分段,并自动把段超越前缀用于所有所有寻址存储器数据的伪指令

ASSUME 语句只能用于完整的段定义, ASSUME 不是汇编指令,仅仅是写给编译软件的,是让编译器知道我的程序的各个段的名字,并不产生机器码

ASSUME 伪指令是指明变量与段寄存器的联系,如 ASSUME DS:DATAS, 告诉编译器以后所有在 DATAS 段中定义的变量寻址时,使用DS作为段地址,但是其不对程序作任何事(伪指令),我们必须自己对DS赋值

因此,要让机器知道实际的段地址,还需要 MOV AX,DATAS MOV DS,AX 告诉CPU数据段的地址

标准格式:
DETAS SEGMENT;
DATAS ENDSSTACKS SEGMENT;
STACKS ENDSCODES SEGMENTASSUME CS:CODES,DS:DATAS,SS:STACKS
START:MOV AX,DATASMOV DS,AX	; 告诉CPU数据段的地址...; 此处输入代码段代码...MOV AH,4CHINT 21H
CODES ENDSEND START

1. 复习 Debug -P 和 -G

debug中P命令与T命令的区别

  1. P和T都是执行,像 add ax, bx,不管用哪个,都是执行此语句

    但如果是 call next, next是一个程序段,那么用P直接就把这段程序执行完,用T则进入内部一句一句执行(与C语言的调试一样,有的进入函数内部,有的执行完函数)

  2. T(跟踪)命令:执行以 cs:ip 开始的一个或几个指令,并显示出执行每条指令后所有寄存器中的内容

P 执行循环、重复的字符串指令、软件中断或子例程

执行命令 G

G [=<地址>[,<断点>]]
等价于:
G
G=<地址>
G=<地址>,<断点>
功能:执行内存中的指令序列
1. 从 CS:IP 所指出开始执行
2. 从指定地址开始执行
3. 从指定地址开始执行,到断点自动停止

2. 将键盘上输入的十六进制数转换成十进制数,并在屏幕上显示

编写程序,详细注释并画程序流程图

代码如下:

data segment	; 定义数据段infon db 0dh,0ah,'Please input a hexadecimal number: $'	; 声明空间存储输入提示信息,其中0d回车,0a换行wrong db 0dh,0ah,'Please input a valid hexadecimal number: $ is wrong'	; 报错
data endsstack segment stackdw 10 dup(?)
stack ends	; 定义一个栈,有10个字的空间code segmentassume cs:code,ds:data,ss:stack
start:mov ax,datamov ds,ax	; 将数据段的地址交给dslea dx,infon	; 使用lea将infon中的内容交给dx,从而在屏幕上显示提示信息mov ah,09h	; 将09h交给ahint 21h	; 输出提示信息mov bx,0input:mov ah,01hint 21h	; 从键盘上输入一个字符,将之对应的ASCII码交给al,并在屏幕上显示add dx,1cmp al,0dhje z	; 如果相等,则跳转到zzjudge:cmp al,'f'	; 比较输入字符与'f'的ASCII码大小ja err	; 无符号大于跳转到errcmp al,'a'jnb branch1	; 无符号不小于跳转到branch1cmp al,'F'ja err	; 无符号大于跳转到errcmp al,'a'jnb branch2	; 无符号不小于跳转到branch2cmp al,'9'ja errcmp al,'0'jnb branch3	; 同理jmp errerr:	; 报错lea dx,wrongmov ah,09hint 21h	; 输出提示语句jmp input	; 跳转,重新输入branch1:sub al,57h	; a~f, al-57hjmp tranbranch2:sub al,37h	; A~F, al-37hjmp tranbranch3:sub al,30h	; 0~9, al-30hjmp trantran:add dx,1mov ah,0hje inputmov cx,04h	; 循环次数为4
shift:	rol bx,1	; bx左移4位loop shiftadd bx,axjmp inputz:mov ax,bxmov bx,10mov cx,0cir:mov dx,0add cx,1div bxpush dxcmp ax,0jne cirfin:pop ax	; 余数出栈mov dl,al	; al的数据交给dl准备输出add dl,30h	; 余数在1~9之间,al + 30mov ah,2int 21h	; 输出十进制数loop fin	; 根据cx的值进行循环输出jmp stopstop:mov ah,4chint 21hcode ends
end start

ROL:循环左移指令
ROL BX, 1 ; 将BX的二进制数全部左移1位,原最高位移入最低位,且复制至进位标志CF
例如,BX原值 =1100 1111 0000 0000 , CF=0
ROL BX, 1 结果: BX=1001 1110 0000 0001 , CF=1

流程图**(流程图格式使用默认)**如下:

在这里插入图片描述

具体代码测试结果如下:

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

3. 较为复杂的汇编实例学习:判断该年是否为闰年

通过注释重点学习并理解程序,活出程序流程图,在理解的基础上可自行修改

代码如下:

示例程序
data segment	; 定义数据段infon db  0dh,0ah,'Please input a year: $'	; 声明空间存储输入提示信息,其中0d回车,0a换行Y db  0dh,0ah,'This is a leap year! $'	; 声明空间存储的是闰年提示信息,同上另起一行输出N db  0dh,0ah,'This is not a leap year! $'	; 声明空间存储不是闰年提示信息,同上另起一行输出w dw 0	; 声明空间存储输入年份解析后生成的年份数字buf db 8db ?db 8 dup(?)	; 声明空间作为缓冲区,总共10个字节,第一个表示准备接收的字符数,即8; 第二个表示实际接受的字符数,初始为空(?); 后面8个字节作为缓冲接收字符,后两行知识做初始化工作data endsstack segment stackdb 200 dup(0)
stack ends	; 定义一个栈,200字节code segmentassume ds:data,ss:stack,cs:codestart: mov ax,datamov ds,ax	; 指定数据段lea dx,infon	; 在屏幕上显示提示信息mov ah,9int 21h	; 将infon开始的字符串输出到屏幕lea dx,buf	; 从键盘输入年份字符串mov ah,10int 21hmov cl,[buf+1]	; 获取实际输入长度
mov ch,0	; 保证cx的值为[buf+1]对应字节的值lea di,buf+2	; 获取字符串首地址call datacate	; 调用子程序,将输入字符串转化为年份数字call ifyears	; 调用子程序,判断是否是闰年jc a1	; 如果进位标记C为1则跳转到a1lea dx,n	; 否则输出不是闰年的信息mov ah,9int 21hjmp exit
a1:	lea dx,y	; 输出是闰年的信息mov ah,9int 21h
exit: mov ah,4ch	; 程序结束int 21hdatacate proc near	; 指明该子程序在主程序段内push cx	; 备份cxdec cx	; cx自减1,保证下面的循环使si指向最后一个字符(buf中回车符前面的一个)lea si,buf + 2	; 将buf中第一个字符(及buf中第三个字节数据)的地址赋给si
tt1: inc si	; 循环,使得si指向最后一个字符(即buf中回车符前面的一个)loop tt1pop cx	; 回复cxmov dh,30h	; 辅助数据,用来将数字字符对应的ASCII码转换为其代表的数字本身mov bl,10	; 辅助数据,用来在每进一位时使得ax乘以10mov ax,1	; ax用来装对应位的权值
l1: push ax	; 备份ax
push bx ; 备份bx
push dx ; 备份dx,下面的dx将接收乘法运算结果的高位(实际上本例中没有任何作用,因为乘法结果不会超过ax表示的范围)
; 之所以需要是因为有时乘数(某些权值)需要用两个字节来表示sub byte ptr  [si],dh	; 将的那个字符转换为对应的数字mov bl, byte ptr [si]	; 获取该位数字
mov bh,0	;因为 1. 我们要用两个个字节装对应位的数字 2. 该数字不会超过一个字节表示的范围mul bx	; 将该位数字乘以相应的权值,结果存储在ax中,我们预定年份最大值不超过两个字节表示的范围add [w],ax	; 加到结果上(易知当所有位都加完时,即是我们想要的年份数字)pop dx	; 恢复dxpop bx	; 恢复bxpop ax	; 恢复axmul bl	; 权值乘以10dec si	; si指向更高一位数字loop l1ret	; 子程序返回
datacate endpifyears proc near	;指明该子程序段在主程序段内,该子程序用于检测是否是闰年,接收年份数据,改变c标记位表示不同结果push bx	; 备份bxpush cx	; 备份cx,下面cx用于存储原始年份数据push dx	; 备份dx,下面dx用于存储除法余数mov ax,[w]	; 获取年份数据mov cx,ax	; 将年份数据备份到cx,因为后面做除法时ax值将会改变mov dx,0	; 因为被除数要为32字节,高位在dx,本程序中为0
mov bx,100	; 这三行半段是否能被100整除div bxcmp dx,0jnz lab1mov ax,cx
mov bx,400div bxcmp dx,0jz lab2	;若能表示是闰年,跳转到lab2clc	; 否则不是闰年,将c标记位清零,并跳转到lab3lab1:mov ax,cx	; 不能被100整除时跳转到此处,进一步判断能否被4整除mov dx,0mov bx,4div bxcmp dx,0jz lab2	; 若不能被100整除但能被4整除时闰年,跳转到lab2clc	; 若不能被100整除也不能被4整除不是闰年,将c标志位置零,并跳转到lab3jmp lab3lab2:stc	; 若是闰年跳转到此处将c标志位置1lab3: pop dx	; 相应寄存器恢复pop cxpop bxret	; 子程序返回ifyears endp
code endsend start

流程图如下:

在这里插入图片描述

请添加图片描述

请添加图片描述

复习一下:

加载有效地址(load effective address)指令就是lea,他的指令形式就是从内存读取数据到寄存器,但是实际上他没有引用内存,而是将有效地址写入到目的的操作数,就像是C语言地址操作符&一样的功能,可以获取数据的地址

jc,如果CF = 1,则跳转至指定位置

jnc,如果CF = 0,则跳转

CF为进位或借位标识符,被运算结果所影响

4. 汇编实例学习和改进:两位数加法

学习和改进程序

不断改造,能力进步

示例: 求和 3 + 5
datas segmentfive db	5	; 定义five为值为5的字节变量
datas endsstacks segmentdb  128 dup(?)	; 定义一个128字节的栈空间
stacks endscodes segmentassume  cs:codes,ds:datas,ss:stacks
start:	; 主程序mov ax,datas	; 段地址交给段寄存器mov ds,axmov al,five	; 将5交给aladd al,3	; al与3相加并将结果交给aladd al,30h	; al与30h相加,得到ASCII码mov dl,al	; 将ASCII码交给dl准备输出mov ah,2int 21h	; 输出dlmov ah,4chint 21h	; 返回DOS
codes ends	; 代码段结束 end start	; 程序结束

在这里插入图片描述

上面的程序是在程序内部定义的数据,以下改进可以使之从键盘输入

start:mov ax,datasmov ds,axmov bl,fivemov ah,1int 21hadd al,blmov dl,almov ah,2int 21h

显然这样不够完善,能否实现输入两个变量,然后相加,我们可以使用以下代码

data segmentx db 0y db 0info db 0dh,0ah,'Please input a number: $'info2 db 0dh,0ah,'Please input another number: $'adds db '+$'res db '=$'
data endsstack segmentdb 128 dup(?)
stack endscode segmentassume cs:code,ds:data,ss:stackstart:mov ax,data	; 将data的段地址交给dsmov ds,axlea dx,info	; 在屏幕上显示提示信息mov ah,9int 21h	; 将infon开始的字符串输出到屏幕mov ah,1int 21h	; 从键盘上输入字符sub al,30h	; al的值-30h,转换为对应的数字mov x,allea dx,addsmov ah,9int 21h	; 输出lea dx,info2	; 在屏幕上显示提示信息mov ah,9int 21h	; 将infon2开始的字符串输出到屏幕mov ah,1int 21h	; 从键盘上输入字符sub al,30h	; al的值-30h,转换为对应的数字mov y,allea dx,resmov ah,9int 21hmov al,xadd al,yadd ax,30h	; 将ax的值+30h转换为对应的ASCII码mov dl,almov ah,2int 21hmov ah,4chint 21h
code ends
end start

运行结果如下:

在这里插入图片描述

但显然不能输入和输出两位数:

在这里插入图片描述

接下来编写两位数求和的程序代码

data segmentinfo1 db 0dh,0ah,'Enter the first number: $'info2 db 0dh,0ah,'Enter the second number: $'info3 db 0dh,0ah,'Sum is: $'buf1 db 8db ?db 8 dup(?)	; 声明空间作为缓冲区,总共10个字节,第一个表示准备接收的字符数,即8; 第二个表示实际接受的字符数,初始为空(?); 后面8个字节作为缓冲接收字符,后两行知识做初始化工作buf2 db 8db ?db 8 dup(?)data endsstack segment stackdb  128 dup(?)	; 定义一个128字节的栈空间
stack endscode segmentassume cs:code,ds:data,ss:stackstart:mov ax,datamov ds,axlea dx,info1mov ah,9int 21hlea dx,buf1mov ah,0ahint 21h	; 输入一个两位数mov bl,[buf1 + 2]	; 将十位交给blsub bl,'0'	; 转ASCII码为数字mov bh,[buf1 + 3]	; 将个位交给bhsub bh,'0'	; 同理转为数字lea dx,info2mov ah,9int 21hlea dx,buf2mov ah,0ahint 21h ; 输入第二个两位数lea dx,info3	; 输出结果mov ah,9int 21hmov cl,[buf2 + 2]	; 将十位交给clsub cl,'0'mov ch,[buf2 + 3]	; 将个位交给chsub ch,'0'add bl,cl	; 十位相加add bh,ch	; 个位相加cmp bh,10	; 考虑进位jge carry1	; 大于等于则进位jmp carry2carry1:sub bh,10	; 个位减10add bl,1	; 十位进1jmp carry2	; 判断十位carry2:cmp bl,10jge carry3	; 大于等于则进位jmp fincarry3:sub bl,10	; 十位减10mov dl,31hmov ah,02hint 21hjmp finfin:mov dl,bladd dl,30hmov ah,02hint 21h	; 将十位的值转化为ASCII码并交给dl并输出mov dl,bhadd dl,30hmov ah,02hint 21h	; 将个位的值转化为ASCII码并交给dl并输出mov ah,4chint 21h	; 返回DOS
code ends
end start

最终流程图如下:

在这里插入图片描述

运行结果如下:

在这里插入图片描述

进位也没有问题

在这里插入图片描述

【基础学习】

栈的定义

db 字节 dw 字 DUP(duplicate) 重复

DB (define byte) : 定义一个字节类型的变量,其后的每个操作数均占用1个字节

DW (define word): 定义一个字类型的变量,其后的每个操作数均占用1个字(2个字节)

DD (define doubleword): 定义一个双字类型的变量,其后的每个操作数均占用2个字(4个字节)

DQ (define quadword): 定义一个四字类型的变量,其后的每个操作数

DT (define ten bytes): 定义一个十字节类型的变量,其后的每个操作数占用5个字(10个字节)

比如
stack segment stackdb 200 dup(0)
stack ends		; 定义一个栈,200字节
STACKS SEGMENT STACK	; 栈段DW 128 DUP(?)	; 注意这里只有128个字
STACKS ENDS

qword全称是Quad Word

2个字节就是1个Word(1个字,16位),q就是英文quad-这个词根(意思是4)的首字母,所以它自然是word(2字节)的四倍,也就是8字节

此外,它还是 Pascal 和 nasm 语言中的关键字

显示提示信息方法

lea dx,infon	; 在屏幕上显示提示信息
mov ah,9
int 21h		; 将infon开始的字符串输出到屏幕

键盘输入方式

从键盘输入一个字符串到缓冲区(AH=0AH)

  • 功能:从键盘输入一串ASCII码字符到缓冲区,输入结束为缓冲区的个数或者回车字符
  • 入口参数: DX=缓冲区首偏移地址; DS=缓冲区段地址
  • 调用方法:
MOV  AX,缓冲区的首址的段地址
MOV  DS,AX
MOV  DX, 缓冲区的首址的偏移地址
MOV  AH, 0AH
INT  21H
  • 执行完上面的调用,将从键盘接受字符串送到内存的输入缓冲区(由DS:DX指定缓冲区),需预先定义一个缓冲区

  • 缓冲区的第一个字节指定容纳的最大字符个数,由用户给出

  • 第二个字节存放实际的最大字符个数,由系统最后添入

  • 从第三个字节开始存放从键盘接受的字符,直到ENTER键结束

e.g.

DATA SEGMENT
BUF DB 20	; 存放最大字符个数20个DB ?	; 存放实际输入字符个数DB 20 DUP(?)	; 存放输入字符
DATA ENDS

mul 乘法指令

理解 mul bx 和 mul bl

MUL 汇编语言无符号数乘法指令

MUL  SRC  执行的操作:
字节操作数: (AX)<--(AL)*(SRC)
字操作数:   (DX,AX)<--(AX)*(SRC)

编写程序从理解范例程序开始,在masm for windows 软件中实现效果,并通过注释进一步理解汇编语言的写法规范,以及汇编中子程序的写法(call 和 ret指令,详见王爽第十章),学习 jmp 跳转语句的使用,画出程序实现的流程图

实验心得

这次的实验比以往的都要综合,因此也更加复杂,但通过流程图的绘制以及不断地报错调试,最终可以实现完整的程序功能

这次的汇编程序编写有当初学习C语言的感觉,感觉基本逻辑和框架差不多,但是汇编要更偏向于底层,我们通常在与寄存器(静态的数据),各种指令(动态的语句),从某种程度上让我对数据结构与算法有了更加具体的感受,也加深了对计算机以及微处理器的了解

子程序调用也很像高级语言中的函数调用,跳转的实现使得语句(代码块)可以得到封装,从而提升了程序的灵活性

【程序欣赏】

My heart beats with yours

在 masm for windows 中运行

Data segment 
full db 0 
buff1 db ' Welcome you to run this programme!' db ' ' db ' *****Please press any key*****$' 
buff2 db ' My heart beats with yours!' db ' ***** Please q to quit *****$' 
Data ends 
code segment assume cs: code , ds: Data 
start: push ds sub ax,ax push ax mov ax, Data mov ds, ax mov ah, 0 mov al, 4 int 10h mov ah,0bh mov bh, 0 mov bl, 1 int 10h mov ah,0bh mov bh, 1 mov bl, 2 int 10h mov dx,offset buff1 ;显示提示信息 mov ah, 9 int 21h mov ah, 8 int 21h call clear ;cls 
sss: call text ;display the text mov di, 2 mov al,1 ;draw the big box mov cx, 70 mov dx, 20 mov bx, 160 Call box mov cx, 71 mov dx, 21 mov bx, 158 
again: mov al, 1 mov di, 0 Call box Call delay mov al, 0 mov di, 0 Call box inc cx inc dx sub bx,2 cmp cx, 94 jnz again mov di,0 ;draw the 2nd box mov cx, 95 mov dx, 45 mov al, 1 mov bx, 110 Call box mov cx, 96 mov dx, 46 mov bx, 108 
again_00: mov al, 1 mov di, 0 Call box Call delay Call delay mov al, 0 mov di, 0 Call box inc cx inc dx sub bx,2 cmp cx, 114 jnz again_00 mov cx,115 ;draw the 3rd box mov dx, 65 mov al, 1 mov bx, 70 Call box mov cx, 116 mov dx, 66 mov bx, 68 
again_01: mov al, 1 mov di, 0 Call box Call delay Call delay mov al, 0 mov di, 0 Call box inc cx inc dx sub bx,2 cmp cx, 129 jnz again_01 mov di, 2 mov al,1 ;draw the small box mov cx, 130 mov dx, 80 mov bx, 40 Call box mov di, 2 mov al,3 ;对角线 mov si, 0 mov cx, 71 mov dx, 21 mov bx, 59 Call xie_line mov cx, 171 mov dx, 121 mov bx, 59 Call xie_line mov si, 1 mov cx, 71 mov dx, 179 mov bx, 59 Call xie_line mov cx, 171 mov dx, 79 mov bx, 59 Call xie_line mov cx,150 ;十字线 mov dx, 20 mov si, 0 mov bx, 60 Call draw_line mov cx, 150 mov dx, 120 mov bx, 60 Call draw_line mov cx, 70 mov dx, 100 mov si, 1 mov bx, 60 Call draw_line mov cx, 170 mov dx, 100 mov bx, 60 Call draw_line mov si, 1 mov cx, 70 mov dx, 60 mov bx, 60 Call mid_line mov cx, 170 mov dx, 110 mov bx, 60 Call mid_line mov si, 2 mov cx, 110 mov dx, 20 mov bx, 30 Call mid_line mov cx, 160 mov dx, 120 mov bx, 30 Call mid_line mov si, 3 mov cx, 70 mov dx, 140 mov bx, 60 Call mid_line mov cx, 170 mov dx, 90 mov bx, 60 Call mid_line mov si, 4 mov cx, 110 mov dx, 180 mov bx, 30 Call mid_line mov cx, 160 mov dx, 80 mov bx, 30 
Call mid_line mov di, 0 mov al,1 ;draw the big box again mov cx, 70 mov dx, 20 mov bx, 160 
Call box mov di, 0 mov al,1 ;draw the small box again mov cx, 130 mov dx, 80 mov bx, 40 
Call box mov di, 0 mov cx, 95 mov dx, 45 mov al, 1 mov bx, 110 
Call box mov cx, 115 mov dx, 65 mov al, 1 mov bx, 70 
Call box mov di,1 ;fill 
Call fill 
Call fill_2 
Call fill_3 mov cx,149 ;bold mov dx, 120 mov al, 2 mov bx, 60 mov si, 0 
Call draw_line mov cx, 151 mov dx, 120 mov al, 2 mov bx, 60 mov si, 0 
Call draw_line 
heart_: ;draw the heart 
Call cls_box 
Call heart mov ah, 8 int 21h cmp al,'q' jz ok cmp al,20h jz heart_ 
Call Clear jmp sss 
ok: 
ret 
fill proc near ;the procedure of fill mov full, 0 mov al, 5 mov cx, 160 mov dx, 121 mov si, 0 mov bx, 60 
fill_Y: push cx push dx push bx 
Call draw_line pop bx pop dx pop cx sub bx,2 inc cx Add dx, 2 inc full cmp full, 30 jne fill_Y ret 
fill endp 
fill_2 proc near mov full, 0 mov al, 5 mov cx, 140 mov dx, 121 mov si, 0 mov bx, 60 
fill_Y1: push cx push dx push bx 
Call draw_line pop bx pop dx pop cx sub bx,2 dec cx Add dx, 2 inc full cmp full, 30 jne fill_Y1 
ret 
fill_2 endp 
fill_3 proc near mov al, 1 mov full, 0 mov si, 0 mov cx, 140 mov dx, 121 mov bx, 60 
re_fill: push bx push cx push dx 
Call draw_line pop dx pop cx pop bx inc cx inc full cmp full, 9 jne re_fill mov full, 0 mov cx, 159 mov dx, 121 mov bx, 60 
re_fill2: push bx push cx push dx 
Call draw_line pop dx pop cx pop bx dec cx inc full cmp full, 9 jne re_fill2 
ret 
fill_3 endp 
draw_Line proc near ;the procedure of draw a line push bx cmp si, 0 jz V_line1 Add bx, cx 
H_line: mov ah,0ch int 10h cmp di, 0 jz aa0 cmp di, 1 jz aa1 
Call delay 
aa1: 
Call delay 
aa0: inc cx cmp cx, bx jne H_line jmp exit_line 
V_line1: Add bx, dx 
V_line: mov ah,0ch cmp di, 0 jz bb0 cmp di, 1 jz bb1 
Call delay 
bb1: 
Call delay 
bb0: int 10h inc dx cmp dx, bx jne V_line 
exit_line: pop bx 
ret 
draw_line endp 
xie_line proc near ;the procedure of draw a xie_line Add bx, cx cmp si, 1 jz xieline_1 
xieline_0: mov ah,0ch int 10h inc dx inc cx cmp cx, bx jne xieline_0 jmp exit_xie 
xieline_1: mov ah,0ch int 10h dec dx inc cx cmp cx, bx jne xieline_1 
exit_xie: 
ret 
xie_line endp 
Mid_line proc near ;draw a xie_line Add bx, cx cmp si, 2 jz midline_2 cmp si, 3 jz midline_3 cmp si, 4 jz midline_4 
midline_1: mov ah,0ch int 10h inc dx Add cx, 2 cmp cx, bx jne midline_1 jmp exit_lines 
midline_2: mov ah,0ch int 10h Add dx, 2 inc cx cmp cx, bx jne midline_2 jmp exit_lines 
midline_3: mov ah,0ch int 10h dec dx Add cx, 2 cmp cx, bx jne midline_3 jmp exit_lines 
midline_4: mov ah,0ch int 10h sub dx,2 inc cx cmp cx, bx jne midline_4 
exit_lines: 
ret 
mid_line endp 
box proc near ;draw a box push cx push dx push cx push dx push cx push dx push cx push dx mov si, 1 call draw_line ;top pop dx pop cx Add cx, bx mov si, 0 call draw_line ;right pop dx pop cx mov si, 0 call draw_line ;left pop dx pop cx mov si, 1 Add dx, bx call draw_line ;bottom pop dx pop cx ret box endp 
space proc near ;display a space mov ah, 2 mov dl,' ' int 21h ret Space endp return proc near ;回车 mov ah, 2 mov dl,0ah int 21h mov dl,0dh int 21h ret return endp text proc near ;显示文本信息 mov bh, 0 mov dh, 0 mov dl, 0 mov ah, 2 int 10h mov dx,offset buff2 mov ah, 9 int 21h Text endp heart proc near mov cx,136 ;draw_heart mov dx, 93 mov si, 0 mov bx, 5 mov al, 2 Call draw_line mov cx,137 ;draw_heart mov dx, 91 mov si, 0 mov bx, 9 Call draw_line mov cx,138 ;draw_heart mov dx, 90 mov si, 0 mov bx, 12 Call draw_line mov cx,139 ;draw_heart mov dx, 89 mov si, 0 mov bx, 14 Call draw_line mov cx,140 ;draw_heart mov dx, 88 mov si, 0 mov bx, 16 Call draw_line mov cx,141 ;draw_heart mov dx, 88 mov si, 0 mov bx, 17 Call draw_line mov cx,142 ;draw_heart mov dx, 87 mov si, 0 mov bx, 19 Call draw_line mov cx,143 ;draw_heart mov dx, 87 mov si, 0 mov bx, 20 Call draw_line mov cx,144 ;draw_heart mov dx, 87 mov si, 0 mov bx, 21 Call draw_line mov cx,145 ;draw_heart mov dx, 88 mov si, 0 mov bx, 21 Call draw_line mov cx,146 ;draw_heart mov dx, 88 mov si, 0 mov bx, 22 Call draw_line mov cx,147 ;draw_heart mov dx, 89 mov si, 0 mov bx, 22 Call draw_line mov cx,148 ;draw_heart mov dx, 90 mov si, 0 mov bx, 22 Call draw_line mov cx,149 ;draw_heart mov dx, 91 mov si, 0 mov bx, 22 Call draw_line mov cx,150 ;1draw_heart mov dx, 91 mov si, 0 mov bx, 22 Call draw_line mov cx,151 ;draw_heart mov dx, 90 mov si, 0 mov bx, 22 Call draw_line mov cx,152 ;draw_heart mov dx, 89 mov si, 0 mov bx, 22 Call draw_line mov cx,153 ;draw_heart mov dx, 88 mov si, 0 mov bx, 22 Call draw_line mov cx,154 ;draw_heart mov dx, 88 mov si, 0 mov bx, 21 Call draw_line mov cx,155 ;draw_heart mov dx, 87 mov si, 0 mov bx, 21 Call draw_line mov cx,156 ;draw_heart mov dx, 87 mov si, 0 mov bx, 20 Call draw_line mov cx,157 ;draw_heart mov dx, 87 mov si, 0 mov bx, 19 Call draw_line mov cx,158 ;draw_heart mov dx, 88 mov si, 0 mov bx, 17 Call draw_line mov cx,159 ;draw_heart mov dx, 88 mov si, 0 mov bx, 16 Call draw_line mov cx,160 ;draw_heart mov dx, 89 mov si, 0 mov bx, 14 Call draw_line mov cx,161 ;draw_heart mov dx, 90 mov si, 0 mov bx, 12 Call draw_line mov cx,162 ;draw_heart mov dx, 91 mov si, 0 mov bx, 9 Call draw_line mov cx,163 ;draw_heart mov dx, 93 mov si, 0 mov bx, 5 Call draw_line ret heart endp delay proc near ;the procedure of delay push cx push dx mov dx, 25 
dl2: mov cx, 2801 
dl3: loop dl3 dec dx jnz dl2 pop dx pop cx ret delay endp clear proc near ;clear mov al, 0 mov bx, 0 mov cx, 0 mov dx, 0 
line: mov ah,0ch int 10h inc cx cmp cx, 320 jne line mov cx, 0 inc dx cmp dx, 200 jne line ret Clear endp cls_box proc near mov al, 0 mov bx, 0 mov cx, 131 mov dx, 81 
s_line: mov ah,0ch int 10h inc cx cmp cx, 170 jne s_line mov cx, 131 inc dx cmp dx, 120 jne s_line ret 
cls_box endp 
code ends end start

结果如下:请添加图片描述

这篇关于【实验作业】微处理器原理与应用 CPUHomework3【子程序汇编实验 流程图 十六进制数转十进制数 键盘录入 屏幕显示 闰年判断 两位数求和 汇编小程序】的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/403071

相关文章

中文分词jieba库的使用与实景应用(一)

知识星球:https://articles.zsxq.com/id_fxvgc803qmr2.html 目录 一.定义: 精确模式(默认模式): 全模式: 搜索引擎模式: paddle 模式(基于深度学习的分词模式): 二 自定义词典 三.文本解析   调整词出现的频率 四. 关键词提取 A. 基于TF-IDF算法的关键词提取 B. 基于TextRank算法的关键词提取

水位雨量在线监测系统概述及应用介绍

在当今社会,随着科技的飞速发展,各种智能监测系统已成为保障公共安全、促进资源管理和环境保护的重要工具。其中,水位雨量在线监测系统作为自然灾害预警、水资源管理及水利工程运行的关键技术,其重要性不言而喻。 一、水位雨量在线监测系统的基本原理 水位雨量在线监测系统主要由数据采集单元、数据传输网络、数据处理中心及用户终端四大部分构成,形成了一个完整的闭环系统。 数据采集单元:这是系统的“眼睛”,

作业提交过程之HDFSMapReduce

作业提交全过程详解 (1)作业提交 第1步:Client调用job.waitForCompletion方法,向整个集群提交MapReduce作业。 第2步:Client向RM申请一个作业id。 第3步:RM给Client返回该job资源的提交路径和作业id。 第4步:Client提交jar包、切片信息和配置文件到指定的资源提交路径。 第5步:Client提交完资源后,向RM申请运行MrAp

深入探索协同过滤:从原理到推荐模块案例

文章目录 前言一、协同过滤1. 基于用户的协同过滤(UserCF)2. 基于物品的协同过滤(ItemCF)3. 相似度计算方法 二、相似度计算方法1. 欧氏距离2. 皮尔逊相关系数3. 杰卡德相似系数4. 余弦相似度 三、推荐模块案例1.基于文章的协同过滤推荐功能2.基于用户的协同过滤推荐功能 前言     在信息过载的时代,推荐系统成为连接用户与内容的桥梁。本文聚焦于

csu 1446 Problem J Modified LCS (扩展欧几里得算法的简单应用)

这是一道扩展欧几里得算法的简单应用题,这题是在湖南多校训练赛中队友ac的一道题,在比赛之后请教了队友,然后自己把它a掉 这也是自己独自做扩展欧几里得算法的题目 题意:把题意转变下就变成了:求d1*x - d2*y = f2 - f1的解,很明显用exgcd来解 下面介绍一下exgcd的一些知识点:求ax + by = c的解 一、首先求ax + by = gcd(a,b)的解 这个

hdu1394(线段树点更新的应用)

题意:求一个序列经过一定的操作得到的序列的最小逆序数 这题会用到逆序数的一个性质,在0到n-1这些数字组成的乱序排列,将第一个数字A移到最后一位,得到的逆序数为res-a+(n-a-1) 知道上面的知识点后,可以用暴力来解 代码如下: #include<iostream>#include<algorithm>#include<cstring>#include<stack>#in

JAVA智听未来一站式有声阅读平台听书系统小程序源码

智听未来,一站式有声阅读平台听书系统 🌟&nbsp;开篇:遇见未来,从“智听”开始 在这个快节奏的时代,你是否渴望在忙碌的间隙,找到一片属于自己的宁静角落?是否梦想着能随时随地,沉浸在知识的海洋,或是故事的奇幻世界里?今天,就让我带你一起探索“智听未来”——这一站式有声阅读平台听书系统,它正悄悄改变着我们的阅读方式,让未来触手可及! 📚&nbsp;第一站:海量资源,应有尽有 走进“智听

zoj3820(树的直径的应用)

题意:在一颗树上找两个点,使得所有点到选择与其更近的一个点的距离的最大值最小。 思路:如果是选择一个点的话,那么点就是直径的中点。现在考虑两个点的情况,先求树的直径,再把直径最中间的边去掉,再求剩下的两个子树中直径的中点。 代码如下: #include <stdio.h>#include <string.h>#include <algorithm>#include <map>#

hdu4407(容斥原理)

题意:给一串数字1,2,......n,两个操作:1、修改第k个数字,2、查询区间[l,r]中与n互质的数之和。 解题思路:咱一看,像线段树,但是如果用线段树做,那么每个区间一定要记录所有的素因子,这样会超内存。然后我就做不来了。后来看了题解,原来是用容斥原理来做的。还记得这道题目吗?求区间[1,r]中与p互质的数的个数,如果不会的话就先去做那题吧。现在这题是求区间[l,r]中与n互质的数的和

poj 3259 uva 558 Wormholes(bellman最短路负权回路判断)

poj 3259: 题意:John的农场里n块地,m条路连接两块地,w个虫洞,虫洞是一条单向路,不但会把你传送到目的地,而且时间会倒退Ts。 任务是求你会不会在从某块地出发后又回来,看到了离开之前的自己。 判断树中是否存在负权回路就ok了。 bellman代码: #include<stdio.h>const int MaxN = 501;//农场数const int