基于8086的汇编语言程序设计题——读入一个文本文件并以DEBUG中的D命令格式显示
代码与注释如下
DATA SEGMENT ;数据段定义
BUF1 DB 256 DUP( ? ) ;分配文件存放内容单元
BUF DB 20,? ;设置输入缓存区大小
FILE DB 10 DUP( ? ) ;实际来存储内容的单元
HANDLE DW ? ;用于在成功打开文件后存放文件代号
ERROR_MESSAGE DB 0AH,‘ERROR!’,’
′
M
E
S
S
A
G
E
D
B
′
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
W
r
i
t
t
e
n
b
y
w
e
n
j
o
y
′
,
0
D
H
,
0
A
H
,
′
' MESSAGE DB '=====================================================Written by wenjoy',0DH,0AH,'
′MESSAGEDB′=====================================================Writtenbywenjoy′,0DH,0AH,′’
MESSAGE1 DB ‘My Course Design Program==’,0DH,0AH,’
′
M
E
S
S
A
G
E
2
D
B
′
P
l
e
a
s
e
i
n
p
u
t
t
h
e
f
i
l
e
n
a
m
e
(
i
n
c
l
u
d
e
t
h
e
f
i
l
e
p
a
t
h
)
:
′
,
0
D
H
,
0
A
H
,
′
' MESSAGE2 DB 'Please input the filename(include the file path):',0DH,0AH,'
′MESSAGE2DB′Pleaseinputthefilename(includethefilepath):′,0DH,0AH,′’
DATA ENDS
CODE SEGMENT ;代码段定义
ASSUME CS:CODE,DS:DATA ;各段的段寄存器分配
START: MOV AX,DATA ;装入段地址 段寄存器需要使用通用寄存器装入数值
MOV DS,AX
LEA DX,MESSAGE ;取偏移地址 MOV DX,offset MESSAGE
MOV AH,9 ;字符串输出
INT 21H
LEA DX,MESSAGE1
MOV AH,9
INT 21H
LEA DX,MESSAGE2
MOV AH,9
INT 21H
CALL IN_FINAME ; 键盘输入文件名(要包含文件路径)
CALL OPENF ;打开文件
MOV AH,2 ;字符输出
MOV DL,0DH
INT 21H
MOV AH,2
MOV DL,0AH
INT 21H
LEA DX,MESSAGE
MOV AH,9
INT 21H
MOV CX,16
MOV DI,0
FLAG: LEA BX,BUF1[DI] ;将偏移地址交给输入参数寄存器BX
CALL DISPLAY ;D命令显示文件 从左到右依次是 逻辑地址 存储内容 内容ASCII码显示
ADD DI,16 ;使指针指向下一行文字
loop FLAG
MOV AH,1 ;输入字符继续
INT 21H
MOV AX,4C00H ;交还给操作系统
INT 21H
;键盘输入子程序设计
IN_FINAME PROC
LEA DX, BUF ;将BUF的偏移地址赋予给了DX
MOV AH,0AH
INT 21H ;键盘输入到缓存区
MOV BL, BUF+1 ;将BUF的首地址提取出来 只有一字节大小 所以只取低位
MOV BH, 0
MOV FILE[BX], 0 ;将首地址内的内容清零
RET
IN_FINAME ENDP
;打开文件子程序设计
OPENF PROC
PUSH AX ;寄存器保护
PUSH BX
push CX
MOV DX, OFFSET FILE ;将文件名首地址赋给DX
MOV AL,0
MOV AH,3DH ;打开文件中断
INT 21H
JC ERROR ;进位则打开文件失败
MOV HANDLE, AX
MOV BX,AX
MOV CX,256
MOV DX,OFFSET BUF1
MOV AH, 3FH ;读取文件中断
INT 21H
JC ERROR ;进位则读取文件失败
MOV BX,AX
MOV BUF1[BX],’$’
MOV BX, HANDLE
MOV AH, 3EH ;关闭文件中断
INT 21H
JNC END1 ;不进位则关闭文件成功
ERROR:
MOV DX,OFFSET ERROR_MESSAGE
MOV AH,9
INT 21H
END1: POP CX ;寄存器恢复
POP BX
POP AX
RET
OPENF ENDP
;D命令显示子程序设计
DISPLAY PROC
DISPLAY1:PUSH DI
MOV BX,DATA
CALL DISP2
MOV AH,2
MOV DL,’:’
INT 21H
LEA BX,BUF1[DI]
call DISP2
MOV AH,2
MOV DL,20H
INT 21H ;空格
CALL ASCII ;前面8个HEX 一次需显现两个ASCII码 所以一次子程序中有两个CALL ASCII
MOV DL,’-’
MOV AH,2
INT 21H
CALL ASCII ;后面8个HEX
MOV AH,2
MOV DL,20H
INT 21H ;空格
SUB DI,16
CALL ELEMENT
MOV AH,2
MOV DL,0DH
INT 21H
MOV AH,2
MOV DL,0AH
INT 21H
POP DI
RET
DISPLAY ENDP
ASCII PROC ;ASCII码显示
PUSH AX ;寄存器保护
PUSH CX
PUSH DX
MOV SI,0
ASCII1: MOV BL,[DI]
CALL DISP1 ;嵌套使用DISP1
INC DI
INC SI
CMP SI,8
JE EXIT1
MOV AH,2
MOV DL,20H
INT 21H
JMP ASCII1
EXIT1: POP DX
POP CX
POP AX
RET
ASCII ENDP
ELEMENT PROC ;显示字符
PUSH AX
PUSH CX
PUSH DX
MOV SI,0
X: MOV AH,2
MOV DL,[DI]
CMP DL,20H ;小于20H的都是控制字符
JLE NEXTT ;为控制字符时 进入NEXTT
JMP NEXTT1 ;不为控制字符时 进入NEXTT1
NEXTT: MOV DL,’.’ ;控制字符都用’.'显示
NEXTT1:INT 21H
INC DI ;使寄存器地址指向下一个元素
INC SI
CMP SI,16 ;判断寄存器是否读取完了本行元素
JE EXIT2 ;是
JMP X ;否
EXIT2: POP DX
POP CX
POP AX
RET
ELEMENT ENDP
DISP1 PROC ;段地址显示
PUSH AX
PUSH CX
PUSH DX
MOV CH,2 ;循环次数
REP1: MOV CL,4 ;位移次数
ROL BL,CL ;不带进位循环左移
MOV DL,BL
AND DL,0FH
ADD DL,30H
CMP DL,3AH
JL PRIN1
ADD DL,7
PRIN1: MOV AH,2
INT 21H
DEC CH
JNZ REP1
POP DX
POP CX
pop AX
RET
DISP1 ENDP
DISP2 PROC ;偏移地址显示
PUSH AX
PUSH CX
PUSH DX
MOV CH,4 ;循环次数
REP2: MOV CL,4 ;位移次数
ROL BX,CL
MOV DL,BL
AND DL,0FH
ADD DL,30H
CMP DL,3AH ;判断十六进制数是否属于0 ~ 9
JL PRIN2
ADD DL,7
PRIN2: MOV AH,2
INT 21H
DEC CH
JNZ REP2
POP DX
POP CX
POP AX
RET
DISP2 ENDP
CODE ENDS
END START