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

编程入门 行业动态 更新时间:2024-10-12 14:26:43

【实验作业】微处理器原理与应用 CPUHomework3【子程序汇编实验 流程图 十六进制数转十进制数 键盘录入 屏幕显示 <a href=https://www.elefans.com/category/jswz/34/1751616.html style=闰年判断 两位数求和 汇编小程序】"/>

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

本文发布于:2024-02-11 14:59:31,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1681582.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:闰年   子程序   作业   微处理器   流程图

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!