实验一
1.修改一个有语法错误的汇编语言源程序
原来有错误的代码:
.486
DATA SEGMENT USE16
SUM DB ?,?,
MESG DB '25+9='
DB 0,0
N1 DB 9,F0H
N2 DW 25
DATA ENDS
CODE SEGMENT USE16
ASSUME CS:CODE,DS:DATA
BEG:
MOV AX,DATA
MOV DS,AX
MOV BX,OFFSET SUM
MOV AH,N1
MOV AL,N2
ADD AH,AL
MOV [BX],AH
CALL CHANG
MOV AH,9
MOV DX,OFFSET MEST
INT 21H
MOV AH,4CH
INT 21H
CHANG: PROC
LAST:
CMP [BX],10
JC NEXT
SUB [BX],10
INC [BX+7]
JMP LAST
NEXT:
ADD [BX+8],SUM
ADD [BX+7],30H
ADD [BX+8],30H
RET
CHANG: ENDP
CODE ENDS
END BEG
修改后的代码:
.586
DATA SEGMENT USE16
SUM DB ?,? ;改动
MESG DB '25+9='
DB 0,0,'$';结束标志
N1 DB 9,0F0H ;前面加0
N2 DB 25 ;DW改成DB
DATA ENDS
CODE SEGMENT USE16
ASSUME CS:CODE,DS:DATA
BEG:
MOV AX,DATA
MOV DS,AX
MOV BX,OFFSET SUM
MOV AH,N1
MOV AL,N2
ADD AH,AL
MOV [BX],AH
CALL CHANG
MOV AH,9
MOV DX,OFFSET MESG
INT 21H
MOV AH,4CH
INT 21H
CHANG PROC
LAST:
CMP BYTE PTR [BX],10 ;34
JC NEXT ;小于10跳转到NEXT
SUB BYTE PTR [BX],10 ;减10
INC BYTE PTR [BX+7] ;十位加1
JMP LAST
NEXT:
MOV AH,SUM
ADD [BX+8],AH
;ADD [BX+8],SUM ;源操作数和目的操作数不能同时为寄存器
ADD BYTE PTR [BX+7],30H ;长度不相同,[BX+7]对应十位,加30H便是0~9的ASCII码
ADD BYTE PTR [BX+8],30H ;[Bx+8]对应个位
RET
CHANG ENDP
CODE ENDS
END BEG
2.设计汇编程序实现数据的查找、统计,代码转换及屏幕显示等功能
【实验2.9】从BUF单元开始存有一字符串(长度<255),编程实现统计该字符串中的ASCII码在42H~45H之间的字符个数,并将统计结果以二进制形式显示在屏幕上。
三、实验原理及内容
○1【实验1.2】排除语法错误
原来有错误的代码:
.486
DATA SEGMENT USE16
SUM DB ?,?,
MESG DB '25+9='
DB 0,0
N1 DB 9,F0H
N2 DW 25
DATA ENDS
CODE SEGMENT USE16
ASSUME CS:CODE,DS:DATA
BEG:
MOV AX,DATA
MOV DS,AX
MOV BX,OFFSET SUM
MOV AH,N1
MOV AL,N2
ADD AH,AL
MOV [BX],AH
CALL CHANG
MOV AH,9
MOV DX,OFFSET MEST
INT 21H
MOV AH,4CH
INT 21H
CHANG: PROC
LAST:
CMP [BX],10
JC NEXT
SUB [BX],10
INC [BX+7]
JMP LAST
NEXT:
ADD [BX+8],SUM
ADD [BX+7],30H
ADD [BX+8],30H
RET
CHANG: ENDP
CODE ENDS
END BEG
修改后的代码:
.586
DATA SEGMENT USE16
SUM DB ?,? ;改动
MESG DB '25+9='
DB 0,0,'$';结束标志
N1 DB 9,0F0H ;前面加0
N2 DB 25 ;DW改成DB
DATA ENDS
CODE SEGMENT USE16
ASSUME CS:CODE,DS:DATA
BEG:
MOV AX,DATA
MOV DS,AX
MOV BX,OFFSET SUM
MOV AH,N1
MOV AL,N2
ADD AH,AL
MOV [BX],AH
CALL CHANG
MOV AH,9
MOV DX,OFFSET MESG
INT 21H
MOV AH,4CH
INT 21H
CHANG PROC
LAST:
CMP BYTE PTR [BX],10 ;34
JC NEXT ;小于10跳转到NEXT
SUB BYTE PTR [BX],10 ;减10
INC BYTE PTR [BX+7] ;十位加1
JMP LAST
NEXT:
MOV AH,SUM
ADD [BX+8],AH
;ADD [BX+8],SUM ;源操作数和目的操作数不能同时为寄存器
ADD BYTE PTR [BX+7],30H ;长度不相同,[BX+7]对应十位,加30H便是0~9的ASCII码
ADD BYTE PTR [BX+8],30H ;[Bx+8]对应个位
RET
CHANG ENDP
CODE ENDS
END BEG
○2【实验2.9】从BUF单元开始存有一字符串(长度<255),编程实现统计该字符串中的ASCII码在42H~45H之间的字符个数,并将统计结果以二进制形式显示在屏幕上。
.486
DATA SEGMENT USE16
BUF DB 'ABCDEFGEB'
COUNT EQU $-BUF
DATA ENDS
CODE SEGMENT USE16
ASSUME CS:CODE,DS:DATA
BEG: MOV AX,DATA
MOV DS,AX ;DS而不是DX !!!!
MOV BX,OFFSET BUF
MOV CX,COUNT
MOV DL,0
LAST: CMP BYTE PTR[BX],42H ;小于42H跳转
JC NEXT
CMP BYTE PTR[BX],45H ;大于45H跳转
JA NEXT
INC DL
NEXT: INC BX
LOOP LAST
CALL DISP
; ADD DL,30H ;显示十进制
; MOV AH,2
; INT 21H
EXIT: MOV AH,4CH
INT 21H
;-------------------------
DISP PROC
MOV CX,8
MOV BL,DL
A0:
RCL BL,1
JNC A1 ;若进位标志为0,则跳转到A1
MOV DL,'1' ;进位标志不为0,将DL赋'1'
JMP NEXT2 ;无条件跳转
A1: MOV DL,'0' ;将DL赋'0'
NEXT2:
MOV AH,2 ;每次循环显示一次DL里的字符
INT 21H
LOOP A0
RET
DISP ENDP
CODE ENDS
END BEG
实验二
实验要求
程序执行后,给出操作提示,请用户键入用户名和密码。
用户在键入密码时,程序不回显键入字符。
只有当用户键入的用户和密码字符串和程序内定的字符串相同时,显示欢迎界面,并返回DOS。
可对密码进行加密和解密;动画显示欢迎界面。(选做)
源码
三、实验原理及内容
1.源代码:
.586
DATA SEGMENT USE16
MESG1 DB 'Please enter username:'
COUNT1 EQU $-MESG1 ;获取长度
USER DB 'NJUPT'
COUNT2 EQU $-USER
PASS DB '122333'
COUNT3 EQU $-PASS
ERROR DB ' Wrong!try again!$';为了显得居中
COUNT4 EQU $-ERROR
MESG2 DB 'Please enter password:'
COUNT5 EQU $-MESG2
MESG3 DB '---- WELCOME! ----'
COUNT6 EQU $-MESG3
BUF1 DB 30 ;数据缓冲区
DB ?
DB 30 DUP(?)
BUF2 DB 30 ;数据缓冲区
DB ?
DB 30 DUP(?)
DATA ENDS
CODE SEGMENT USE16
ASSUME CS:CODE,DS:DATA,ES:DATA
BEG: MOV AX,DATA
MOV DS,AX
MOV ES,AX
MOV AX,0003H ;80列x25行彩色文本方式
INT 10H
USERNAME: MOV AX,1301H ;显示彩色字符串"Please enter username:"
MOV BH,0
MOV BL,0AH
MOV CX,COUNT1
MOV DH,2
MOV DL,(80-COUNT1)/2 ;居中显示
MOV BP,OFFSET MESG1
INT 10H
RUSER: MOV CX,COUNT2 ;键盘读入用户名
MOV AH,0AH
MOV DX,OFFSET BUF1
INT 21H
MOV CL,BUF1+1
MOV CH,0
CMP CX,COUNT2
JNZ WRONGUSER
MOV SI,OFFSET BUF1+2
MOV DI,OFFSET USER
CLD
MOV AX,2H ;清屏
MOV BH,0
MOV DH,0
MOV DL,0
LOAD: REPE CMPSB ;两字符串比较
JZ PASSWORD ;相等的话跳转到password
WRONGUSER:
MOV AH,2
MOV DL,0AH
INT 21H
MOV AH,2
MOV DL,0AH
INT 21H
MOV AX,2H ;清屏
MOV BH,0
MOV DH,0
MOV DL,0
INT 10H
MOV AH,9 ;黑白显示
MOV DX,OFFSET ERROR
INT 21H
JMP USERNAME ;跳转到USERNAME,让用户重新输入用户名
PASSWORD: ;与用户名代码类似
INT 10H
MOV AX,1301H
MOV BH,0
MOV BL,0AH
MOV CX,COUNT5
MOV DH,2
MOV DL,(80-COUNT5)/2
MOV BP,OFFSET MESG2
INT 10H
MOV BX,OFFSET BUF2
MOV CX,0
LAST2:
MOV AH,07H ;不回显字符
INT 21H ;光标下移一行
MOV [BX],AL ;低位传给BX
MOV DH,AL ;提前把AL寄存器里的字符备份,否则用了02H会破坏掉AL寄存器里的内容
MOV AH,02H ;显示 *
MOV DL,'*'
INT 21H
INC BX ;BX后移一位,一共移CX次
INC CX
CMP DH,0DH
JNZ LAST2
DEC CX ;减一是因为回车使CX+1了,实际CX值应该减掉1
MOV DI,OFFSET BUF2
MOV SI,OFFSET PASS
CLD
REPE CMPSB ;字符串比较
JZ WELCOME ;ZF=1,表示一样,跳到WELCOME
WRONGPASS:
MOV AH,2
MOV DL,0AH
INT 21H
MOV AH,2
MOV DL,0AH
INT 21H
MOV AX,2H ;清屏
MOV BH,0
MOV DH,0
MOV DL,0
INT 10H
MOV AH,9 ;黑白显示
MOV DX,OFFSET ERROR
INT 21H
JMP PASSWORD
WELCOME:
MOV AX,0007H ;输入字符
INT 10H
MOV AX,1301H
MOV BH,0
MOV BL,0BAH ;对照p156改了一下颜色,能闪烁了
MOV CX,COUNT6
MOV DH,2
MOV DL,(80-COUNT6)/2
MOV BP,OFFSET MESG3
INT 10H
EXIT:MOV AH,4CH
INT 21H
CODE ENDS
END BEG
运行结果
测试输入错误的情况:
输入错误会回显“Wrong!try again!”
,并让用户重新输入用户名。
测试输入正确的情况:
用户名输入正确会提示用户输入密码
下面测试密码错误情形:(密码不直接显示,以***代替)
下面测试密码正确的情形:
实验三
运用微机系统串行口知识,进行微机系统串行口的测试;完成硬件测试环境;编写程序对微机系统的串口进行自收自发外环测试;数据发送从键盘输入,接收数据时在屏幕显示。
.586
DATA SEGMENT USE16
BUF DB 30 DUP(?)
DATA ENDS
CODE SEGMENT USE16
ASSUME CS:CODE, DS:DATA
START:
MOV AX, DATA
MOV DS, AX
CALL I8250 ; 8250初始化
MOV BX, OFFSET BUF
SEND:
MOV DX, 2FDH ;通信状态寄存器
IN AL, DX
TEST AL, 20H ;0010 0000 B 检查发送保持寄存器是否为空,D5为1 空闲,为0继续循环等待
JZ SEND ;不空闲
MOV DX, 2F8H ; 发送保持寄存器
MOV AH, 1 ;1号功能调用,键盘输入字符
INT 21H
CMP AL, 0DH ;接收到回车表明发送结束,0DH是回车
JZ DISP
OUT DX, AL ;写数据
RECE:
MOV DX, 2FDH
IN AL, DX
TEST AL, 01H
JZ RECE ; 判断一帧数据接收完整
MOV DX, 2F8H
IN AL, DX
MOV [BX], AL
INC BX
JMP SEND
DISP:
MOV BYTE PTR [BX+1], '$'
MOV AH, 09H ; 09号功能调用,显示字符串
MOV DX, OFFSET BUF
INT 21H
EXIT:
MOV AH,4CH
INT 21H ; 结束程序
I8250 PROC
MOV DX, 2FBH ;通信控制寄存器
MOV AL, 80H ; 1000 0000B D7=1,访问除数寄存器
OUT DX, AL
MOV DX, 2F9H ;设置分频系数
MOV AL, 0
OUT DX, AL
MOV DX, 2F8H
MOV AL, 60H ;1200波特
OUT DX, AL
MOV DX, 2FBH ;定义一帧数据格式(8个数据位,一个停止位,无校验)
MOV AL, 03H
OUT DX, AL
MOV DX, 2F9H ;设置中断允许寄存器,此处使用查询方式,即禁止中断
MOV AL, 0
OUT DX, AL
MOV DX, 2FCH ;设置MODEM控制寄存器
MOV AL, 0 ;D3=0采用查询方式
OUT DX, AL
RET
I8250 ENDP
CODE ENDS
END START
实验四
在开放式微机实验装置上完成相应硬件电路连接;编写程序实现:8254的三个计数器输出不同周期的信号,控制发光二极管,达到流光效果。
注:
实验时所用的外扩8254的OUT0,OUT1,OUT2分别接到LED显示区L7,L6,L5,其中OUT0为计数器0的输出,通过公式 N = fclk/fout = Tout/Tclk(N为计数器初值) 可计算得到输出信号的频率与周期。以计数器0为例,我们选用的CLK0,CLK1,CLK2均为1kHz,即周期为1ms,想使L7的闪烁周期为1s,即Tout=1s,则N=1s/1ms=1000。数制选择使用二进制,则在向计数器0写初值时可以直接写1000,或者写1000的16进制。
.486
CODE SEGMENT USE16
ASSUME CS:CODE
BEG: JMP START
CCONBIT1 EQU 00110110B ; 0号计数器初始化控制字
CCONBIT2 EQU 01110110B ; 1号计数器初始化控制字
CCONBIT3 EQU 10110110B ; 2号计数器初始化控制字
CDPORT1 EQU 210H ; 0号计数器口地址
CDPORT2 EQU 211H ; 1号计数器口地址
CDPORT3 EQU 212H ; 2号计数器口地址
CCONPORT EQU 213H ;控制口地址
CHDBIT1 EQU 1000 ;计数器0初值 T_OUT=1S
CHDBIT2 EQU 2000 ;计数器1初值 T_out=2s
CHDBIT3 EQU 4000 ;计数器2初值 T_out=4s
START: NOP ;启动延时
MOV DX,CCONPORT ;写入控制字_计数器0
MOV AL,CCONBIT1
OUT DX,AL
MOV AX,CHDBIT1 ;写入初值_计数器0
MOV DX,CDPORT1
OUT DX,AL
MOV AL,AH
OUT DX,AL
MOV DX,CCONPORT ;写入控制字_计数器1
MOV AL,CCONBIT2
OUT DX,AL
MOV AX,CHDBIT2 ;写入初值_计数器1
MOV DX,CDPORT2
OUT DX,AL
MOV AL,AH
OUT DX,AL
MOV DX,CCONPORT ;写入控制字_计数器2
MOV AL,CCONBIT3
OUT DX,AL
MOV AX,CHDBIT3 ;写入初值_计数器2
MOV DX,CDPORT3
OUT DX,AL
MOV AL,AH
OUT DX,AL
WT: NOP
JMP WT
CODE ENDS
END BEG