微机原理
课程设计
一.课程设计目的:
结合微型计算机原理课程的学习,进一步巩固已学的知识,同时针对微型计算机原理知识的具体应用,学会对系统中DOS和BIOS的使用。学会使用全屏幕编辑程序——PE,弄懂汇编程序的上机过程以及如何运用DEBUG软件进行汇编程序的调试。
二.课程设计的任务:
实验一
实验要求:
字符串匹配的设计
编写程序实现两个字符串比较,如相同,则显示“MATCH”;否则,显示“NO MATCH”。
流程图:
程序
CRLF MACRO ;显示回车
MOV DL,0DH
MOV AH,02H
INT 21H
MOV AH,02H
MOV DL,0AH
INT 21H
ENDM
DATA SEGMENT
MESS1 DB 'MATCH',0DH,0AH,'$'
MESS2 DB 'NO MATCH',0DH,0AH,'$'
MESS3 DB 'INPUT STRING1!',0DH,0AH,'$'
MESS4 DB 'INPUT STRING2!',0DH,0AH,'$'
MAXLEN1 DB 100
STRING1 DB 100 DUP(?)
MAXLEN2 DB 100
STRING2 DB 100 DUP(?)
DATA ENDS
CODE SEGMENT
ASSUME CS:CODE,DS:DATA,ES:DATA
START: MOV AX,DATA
MOV DS,AX
MOV ES,AX
MOV AH,09H
MOV DX,OFFSET MESS3
INT 21H ;显示提示信息1
MOV AL,MAXLEN1
MOV BX,OFFSET STRING1
MOV [BX],AL ;最大字符缓冲
MOV AH,0AH
MOV DX,OFFSET STRING1
INT 21H ;接收键入的字符串1
CRLF
MOV AH,09H
MOV DX,OFFSET MESS4
INT 21H ;显示提示信息2
MOV AL,MAXLEN2
MOV BX,OFFSET STRING2
MOV [BX],AL ;最大字符缓冲设置
MOV AH,0AH
MOV DX,OFFSET STRING2
INT 21H ;接收键入的字符串2
CRLF
CLD
LEA SI,STRING1 ;字符串1的地址送给SI
MOV CL,[SI+1] ;字符串1的字符数送给CX
MOV CH,0
BEING: LEA DI,STRING2 ;字符串2的地址送给DI
MOV DL,[DI+1] ;字符串2的字符数送给DX
MOV DH,0
J1: MOV AL,[SI+2] ;字符串1的第一个字符在字符串2中匹配
CMP [DI+2],AL
JE J3 ;匹配成功则跳转
J2: INC DI ;指向字符串2下一个字符
DEC DX
JZ NOMAT ;字符串2完,不匹配
JMP J1 ;字符串2没完,重新匹配
J3: DEC CX
JZ MATCH ;字符串1完,匹配
DEC DX
JZ NOMAT ;字符串2完,不匹配
INC SI ;指向串1下一个字符
INC DI ;指向串2下一个字符
MOV AL,[SI+2]
CMP [DI+2],AL
JE J3 ;匹配,跳转
DEC DX
JZ NOMAT ;字符串2完,不匹配
LEA SI,STRING1 ;重新从串1的第一个字符匹配
MOV CL,[SI+1]
MOV CH,0
JMP J1
MATCH: MOV AH,09H ;输出匹配信息
MOV DX,OFFSET MESS1
INT 21H
JMP NEXT
NOMAT: MOV AH,09H ;输出不匹配信息
MOV DX,OFFSET MESS2
INT 21H
NEXT: MOV AH,4CH ;程序终止
INT 21H
CODE ENDS
END START
运行结果
实验二
实验要求:
从键盘输入数据并显示的设计
为掌握键盘接受数据的方法,并了解将键盘数据显示时必须转换为ASCII码的原理,编写程序,将键盘接受到的四位十六进制数据转换为等值的二进制数显示。
流程图:
程序:
DATA SEGMENT
CUE DB 'PLEASE INPUT SIXTEEN DATA',0DH,0AH,'$'
CHA DB 0DH,0AH,'CHANGE NUM :',0DH,0AH,'$'
DATA ENDS
CODE SEGMENT
ASSUME CS:CODE,DS:DATA
START:MOV AX,0
MOV AX,DATA
MOV DS,AX
MOV DX,OFFSET CUE ;显示输入十六进制数
MOV AH,9
INT 21H
CALL SHOW
MOV AH,4CH
INT 21H
SHOW PROC NEAR
MOV CL,4
MOV CH,4
MOV BX,0
LP1: MOV AH,01H
INT 21H
SUB AL,'0' ;存放差值
CMP AL,9
JNG LP
SUB AL,7
LP: ROL BX,CL ;十六进制数存放到BX中
OR BL,AL
DEC CH
JNZ LP1
MOV DX,OFFSET CHA
MOV AH,9
INT 21H
MOV CX,16
LP2: SHL BX,1 ;二进制转化
JC LP3
MOV DL,0
JMP NEXT
LP3: MOV DL,1
NEXT: ADD DL,'0'
MOV AH,2
INT 21H
LOOP LP2
RET
SHOW ENDP
CODE ENDS
END START
运行结果:
实验三
字符和数据的显示设计
实验要求:
为掌握字符和数据的显示方法。编写程序,先显示信息:INPUT STRING,THE END FLAG IS $,再接收字符。如为0-9,则计数器加1,并显示数据;如为非数字,则直接显示,但不计数。
流程图:
实验程序:
DATA SEGMENT
DATA1 DB 40 DUP(?)
DISPP1 DB 'input string,the end flag is CR,quit with ctrl-c',0DH,0AH,'$'
DISPP2 DB 0DH,0AH,'$'
DISPP3 DB 'the input string is:','$'
DATA ENDS
CODE SEGMENT
ASSUME CS:CODE,DS:DATA
START: MOV AX,DATA
MOV DS,AX
MOV SI,00H
MOV CL,0
MOV BX,OFFSET DATA1
LEA DX,DISPP1
MOV AH,9
INT 21H
L1: MOV AH,1
INT 21H
CMP AL,03H
JZ L4
CMP AL,0DH
JZ L3
MOV [BX+SI],AL
INC SI
CMP AL,30H
JNB kk
JMP L1
kk: CMP AL,39H
JNA L2
JMP L1
L2: INC CL
JMP L1
L3: LEA DX,DISPP2
MOV AH,9
INT 21H
LEA DX,DISPP3
MOV AH,9
INT 21H
ADD CL,30H
MOV [BX+SI+1],CL
MOV AL,0AH
MOV [BX+SI+2],AL
MOV AL,'$'
MOV [BX+SI+3],AL
MOV DX,BX
MOV AH,9
INT 21H
JMP L4
L4: MOV AH,4CH
INT 21H
CODE ENDS
END START
运行结果:
实验四
实验要求:
从键盘按收输入字符,如是数字N,则响铃N次,如不是数字或数字是0,则不响
流程图:
程序:
DATA SEGMENT
CUE DB 'PLEASE INPUT NUM',0DH,0AH,'$'
DATA ENDS
CODE SEGMENT
ASSUME CS:CODE,DS:DATA
START: MOV AX,DATA
MOV DS,AX
LEA DX,CUE
MOV AH,09H
INT 21H
LOP: MOV AH,01H
INT 21H
CMP AL,0DH ;回车转到PPP
JE PPP
CMP AL,39H ;大于39H从新输入
JA LOP;
SUB AL,2FH
XOR AH,AH
MOV BP,AX
LOP1: DEC BP
JZ LOP
MOV AH,02H ;响铃
MOV DL,07H
INT 21H
MOV CX,0FFFFH ;延迟
LOP2: LOOP LOP2
JMP LOP1
PPP: MOV AH,4CH
INT 21H
CODE ENDS
END START
运行结果:
实验五
实验要求:
接收年,月,日信息并显示的设计:掌握响铃使用方法,并掌握年,月,日输入方法。编写程序,先显示“WHAT IS THE DATE(MM/DD/YY)?”并响铃一次,然后接收键盘输入的月/日/年信息,并显示。
流程图:
程序:
CRLF MACRO
MOV AH,02H
MOV DL,0DH
INT 21H
MOV AH,02H
MOV DL,0AH
INT 21H
ENDM
DATA SEGMENT
MESS DB 'PLEASE INPUT MONTH,DAY ,YEAR(MM/DD/YY)',0DH,0AH,'$'
MESS1 DB 0DH,0AH,'MONTH ERROR,PLEASE INPUT AGAIN',0DH,0AH,'$'
MESS2 DB 0DH,0AH,'DAY ERROR,PLEASE INPUT AGAIN',0DH,0AH,'$'
ERROR DB 0DH,0AH,'ERROR,PLEASE INPUT AGAIN',0DH,0AH,'$'
MARK DB ?
REG DW ?
DATA ENDS
STACK SEGMENT
STA DW 32 DUP(?)
TOP DW ?
STACK ENDS
CODE SEGMENT
ASSUME CS:CODE,DS:DATA,ES:DATA,SS:STACK
START: MOV AX,DATA
MOV DS,AX
MOV ES,AX
MOV SP,TOP
HEAD: MOV MARK,0
MOV AH,09H
MOV DX,OFFSET MESS
INT 21H
MOV AH,02H ;响铃一次
MOV DL,07H
INT 21H
CALL GETNUM ;键入月值
CMP MARK,01H
JE HEAD
PUSH DX
CALL GETNUM ;键入日值
CMP MARK,01H
JNE K1
POP DX
JMP HEAD
K1: PUSH DX
CALL GETNUM 键入年值
CMP MARK,01H
JNE K2
POP DX
POP DX
JMP HEAD
K2: MOV AX,DX
CALL DISP ;显示年值
NOP
MOV AH,02H
MOV DL,'-'
INT 21H
POP DX
POP AX
PUSH DX
MOV REG,AX
AND AX,00FFH
CMP AX,0012H
JBE W1
MOV AH,09H
LEA DX,MESS1
INT 21H
JMP START
W1: MOV AX,REG
CALL DISPP ;显示月值
MOV AH,02H
MOV DL,'-' ;显示‘—’
INT 21H
POP AX
MOV REG,AX
AND AX,00FFH
CMP AX,31H
JBE W2
MOV AH,09H
LEA DX,MESS2
INT 21H
JMP START
W2: MOV AX,REG
CALL DISPP ;显示日值
MOV AX,4C00H
INT 21H
DISPP PROC NEAR
MOV BL,AL
MOV DL,BL
MOV CL,04
ROL DL,CL
AND DL,0FH
CALL DISPL
MOV DL,BL
AND DL,0FH
CALL DISPL
RET
DISPP ENDP
DISPL PROC NEAR
ADD DL,30H
CMP DL,3AH
JB DDD
ADD DL,27H
DDD: MOV AH,02H
INT 21H
RET
DISPL ENDP
DISP PROC NEAR
PUSH BX
PUSH CX
PUSH DX
PUSH AX
MOV AL,AH
CALL DISPP
POP AX
CALL DISPP
POP DX
POP CX
POP BX
RET
DISP ENDP
GETNUM PROC NEAR
PUSH CX
XOR DX,DX
GGG: MOV AH,01H
INT 21H
CMP AL,0DH
JZ PPP
CMP AL,20H
JZ PPP
SUB AL,30H
CMP AL,0
JB KKK
CMP AL,0AH
JB GETS
JMP KKK
GETS: MOV CL,04
SHL DX,CL
XOR AH,AH
ADD DX,AX
JMP GGG
KKK: PUSH AX
PUSH DX
MOV AH,09H
MOV DX,OFFSET ERROR
INT 21H
MOV MARK,01H
POP DX
POP AX
PPP: PUSH DX
MOV AH,02H
MOV DX,07H
INT 21H
CRLF
POP DX
POP CX
RET
GETNUM ENDP
CODE ENDS
END START
运行结果:
实验六
实验要求:
将键盘输入的小写字母转换成大写字母的设计
为了解小写字母和大写字母在计算机内的表示方法,并学习如何进行转换,编写程序,接受键盘字符,并将其中的小写字母转变为大写字母,然后显示在屏幕上。
流程图:
实验程序:
DATA SEGMENT
DATA1 DB 20 DUP(?)
DISPP1 DB 'please input letters, end with enter, exit with ctrl-c',0DH,0AH,'$'
DISPP2 DB 'the inverted litter is:', 0DH, 0AH,'$'
DISPP3 DB 0DH,0AH,'$'
DATA ENDS
CODE SEGMENT
ASSUME CS:CODE,DS:DATA
START: MOV AX,DATA
MOV DS,AX
MOV SI,00H
MOV BX,OFFSET DATA1
LEA DX,DISPP1
MOV AH,9
INT 21H
L1: MOV AH,1
INT 21H
CMP AL,03H
JZ L4
CMP AL,0DH
JZ L3
CMP AL,61H
JZ L2
SUB AL,20H
JMP L2
L2: MOV [BX+SI],AL
INC SI
JMP L1
L3: LEA DX,DISPP3
MOV AH,9
INT 21H
LEA DX,DISPP2
MOV AH,9
INT 21H
MOV [BX+SI],AL
MOV AL,0AH
MOV [BX+SI+1],AL
MOV AL,'$'
MOV [BX+SI+2],AL
MOV DX,BX
MOV AH,9
INT 21H
LEA DX,DISPP3
MOV AH,9
INT 21H
JMP L4
L4: MOV AH,4CH
INT 21H
CODE ENDS
END START
运行结果:
实验九
实验要求:
学生成绩名次表设计
为进一步熟悉排序方法,编写程序,将0—100之间的30个成绩存入首地址为1000H的存储区中,1000H+i的学生成绩。编写程序使得在2000H开始的区域排出名次表。2000H+i为学号i的学生的名次。
流程图:
实验程序:
DATA SEGMENT
EN EQU 0DH
TA EQU 0AH
InMark DB 3
DB ?
DB 3 DUP(?)
S1 DB 'Please Input The Mark(00-99)',EN,TA,'$'
S2 DB 'Student ','$'
S3 DB 'Namelist','$'
ORG 1000H ;指定内存位置1000H
Mark DB 30 DUP(?) ;设定学生人数为30 人
ORG 2000H ;指定内存位置2000H
Namelist DB 30 DUP(?)
DATA ENDS
STACK SEGMENT
STACK ENDS
CODE SEGMENT
ASSUME CS:CODE,DS:DATA,SS:STACK
START: MOV AX,DATA
MOV DS,AX
DISPSTR MACRO S ;宏定义显示字符串
PUSH AX ;DOS 功能调用对AX内容影响需保护
MOV DX,OFFSET S
MOV AH,9H
INT 21H
POP AX
ENDM
DISPSIN MACRO D ;宏定义显示单字符
PUSH AX
MOV DL,D
MOV AH,02H
INT 21H
POP AX
ENDM
ENTA MACRO ;宏定义回车换行
PUSH AX
MOV DL,EN
MOV AH,2
INT 21H
MOV DL,TA
INT 21H
POP AX
ENDM
DISPSTR S1 ;宏调用显示“Please Input……”
MOV CX,30
MOV DI,OFFSET Mark
CALL InputM ;调用输入成绩子程序InputM
ENTA
MOV CX,30 ;排序并生成名次表
MOV DI,OFFSET Namelist
M1: MOV AX,31
SUB AX,CX
MOV [DI],AL
INC DI
LOOP M1
MOV CX,29
MOV SI,OFFSET Mark
MOV DI,OFFSET Namelist
XOR BX,BX
CALL PaiXu ;调用排序子程序PaiXu
DISPSTR S3
ENTA ;排序并生成名次表
MOV CX,30
MOV SI,OFFSET Namelist
MOV DI,OFFSET Mark
CALL List ;调用显示名次表子程序List
MOV AH,4CH
INT 21H ;结束返回DOS
ZhuanHuan PROC NEAR ;十六进制转ASCⅡ码输出子程序
PUSH BX
MOV BH,0AH
DIV BH
POP BX
ADD AL,'0'
ADD AH,'0'
DISPSIN AL
DISPSIN AH
RET
ZhuanHuan ENDP
InputM PROC NEAR ;学生成绩输入子程序
I1: MOV AX,31
SUB AX,CX
DISPSTR S2
XOR AH,AH
CALL ZhuanHuan ;换码输出学号
DISPSIN ':'
MOV DX,OFFSET InMark
MOV AH,0AH
INT 21H
ENTA
MOV SI,OFFSET InMark
ADD SI,2 ;SI指向输入数据
MOV BH,[SI]
MOV BL,[SI+1]
SUB BH,'0'
SUB BL,'0'
MOV AL,0AH
XOR AH,AH
MUL BH ;十位数乘以10再加个位
ADD AL,BL
MOV [DI],AL ;存储成绩
INC DI
LOOP I1
RET
InputM ENDP
PaiXu PROC NEAR ;排序子程序
P1: PUSH CX
MOV AH,BL
MOV DX,BX
INC DX ;DX加1指向下一单元
MOV AL,[SI+BX] ;小循环初始化
PUSH BX
P2: MOV BX,DX
CMP AL,[SI+BX]
JNB P3
MOV AL,[SI+BX] ;换成绩
MOV CH,[DI+BX] ;换学号
MOV AH,DL ;换指针
P3: INC DX
DEC CL
JNZ P2
POP BX ;小循环结束
MOV DL,[SI+BX] ;动成绩
MOV CL,[DI+BX] ;动学号
MOV [SI+BX],AL ;动成绩
MOV [DI+BX],CH ;动学号
PUSH BX
XOR BX,BX
MOV BL,AH
MOV [SI+BX],DL ;动成绩
MOV [DI+BX],CL ;动学号
POP BX
INC BX
POP CX
LOOP P1
RET
PaiXu ENDP
List PROC NEAR ;输出显示子程序
L1: MOV AX,31
SUB AX,CX
CALL ZhuanHuan ;输出名次1、2、3……
DISPSIN ' ' ;输出空格
DISPSTR S2 ;输出“STUDENT ”
XOR AX,AX
MOV AL,[SI]
CALL ZhuanHuan ;输出学号
XOR AX,AX
MOV AL,[DI]
DISPSIN ' '
CALL ZhuanHuan ;输出成绩
ENTA
INC SI
INC DI
LOOP L1
RET
List ENDP
CODE ENDS
END START
运行结果:
三.实验心得
近一个星期的课程设计中,通过对一些题目的练习我进一步了解到微机的强大功能,学习到微机的一些简单运用,收获颇多。
这不是第一次用汇编语言来写程序,平时做了很多实验,写了很多小程序。但这次是一个综合的程序,平时的一些程序稍微改动都可以作为子程序用到,这大大方便了我的设计,为我节省了很多的时间。
在这次课程设计中,我真正体会到了合作的重要性,遇到很多问题时,当我看书查资料不能解决时,去找同学讨论一下,可以使很多问题迎刃而解。
当然程序任然存在不少缺点和不足,但通过这次课程设计的却找出了自己在学习上的不足,对以后的工作也有指导作用。我相信在以后的学习中会克服这些不足,达到熟练掌握汇编语言的程度!