本文主要是介绍【实验作业】微处理器原理与应用 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命令的区别
-
P和T都是执行,像 add ax, bx,不管用哪个,都是执行此语句
但如果是 call next, next是一个程序段,那么用P直接就把这段程序执行完,用T则进入内部一句一句执行(与C语言的调试一样,有的进入函数内部,有的执行完函数)
-
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【子程序汇编实验 流程图 十六进制数转十进制数 键盘录入 屏幕显示 闰年判断 两位数求和 汇编小程序】的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!