华北电力大学
实验报告|
|
实验名称汇编语言程序设计实验
课程名称IBM-PC汇编语言程序设计
|
|
专业班级:学生姓名:
学号:成绩:
指导教师:实验日期
实验一用表格形式显示字符
一、实验要求
按15*16列的表格形式显示ASCⅡ码为10H—100H的所有字符,即以行为主的顺序及ASCⅡ码递增的次序依次显示对应的字符。每16个字符为一行,每行中的相邻两个字符之间用空白符隔开。
二、设计说明
(1)显示每个字符可使用功能号为02的显示输出功能调用:
Mov ah,02h
Mov dl,输出字符的ASCⅡ码
Int 21h
将dl初始化为10H,然后使用其加1以取得下一个字符的ASCⅡ码。
(2)显示空白符是,用其ASCⅡ码置0入dl寄存器。每行结束时,用回车和换行来结束本行并开始下一行。
(3)由于逐个显示相继的ASCⅡ码字符是,需要不断修改dl寄存器的内容,而显示空白、回车、换行也需要使用dl寄存器,为此可使用堆栈保存dx。
三、实验程序及调试结果
CODES SEGMENT
;**********************************************
main proc far
ASSUME CS:CODES
START:
push ds
sub ax,ax
push ax
mov di,15
mov dl,10h
loo:
mov cx,16
next:
mov ah,02h
int 21h
inc dl
push dx
mov dl,0
mov ah,02h
int 21h
pop dx
loop next
push dx
mov dl,0dh
mov ah,02h
int 21h
mov dl,0ah
mov ah,02h
int 21h
pop dx
dec di
jne loo
je exit
exit: ret
main endp
CODES ENDS
END START
实验二查找匹配字符串
一、实验要求
程序接受用户键入的一个关键字以及一个句子,如果句子中不包含关键字则显示“No match!”;如果句子中包含关键字则显示“match!”,且把该字在句子中的位置用十六进制数显示出来。要求程序的执行过程如下:
Enter keyword:abc
Enter sentence:we are studying abc
Match at location:11H of the sentence
Enter sentence:xyz
No match!
Enter sentence:
二、设计说明
程序由三部分组成:
(1)输入关键字和一个句子,分别存入相应的缓冲区中。
(2)在句子中查找关键字
(3)输出信息。用功能调用09h分‘找到’和‘未找到两种情况分别显示不同的信息。
在“找到”时,显示关键字在字符串中位置。
三、使用说明
根据提示输入关键字和句子,按回车键结束输入。程序将显示字符串中是否含有关键字,有则提示‘match’并显示关键字位置,无则提示‘no match’。
四、实验程序
DA TAS SEGMENT para 'data'
mess1 db 'match!',13,10,'$'
mess2 db 'no match!',13,10,'$'
mess3 db 'enter keyword:','$'
mess4 db 'enter sentence:','$'
mess5 db 'match at location:','$'
mess6 db ' H of the sentence','$'
stoknim label byte
max db 10
act db ?
stokn db 10 dup(?)
sentence label byte
ma db 100
ac db ?
sto db 100 dup(?)
DA TAS ENDS
STACKS SEGMENT
;此处输入堆栈段代码
STACKS ENDS
;*****************************************
CODES SEGMENT para 'code'
ASSUME CS:CODES,DS:DA TAS,es:datas
main proc far
START:
push ds
sub ax,ax
push ax
MOV AX,DATAS
MOV DS,AX
mov es,ax
;*****************输入关键字和一个句子***********
k:
lea dx,mess3
mov ah,09
int 21h ; 显示字符串‘enter word’
lea dx,stoknim
mov ah,0ah
int 21h ;输入关键字到缓冲区Word
push dx
mov dl,0dh
mov ah,02h
int 21h
mov dl,0ah
mov ah,02h
int 21h ;回车换行
pop dx
d: lea dx,mess4
mov ah,09
int 21h ;显示字符串‘enter sentence’
lea dx,sentence
mov ah,0ah
int 21h ;输入句子到缓冲区sentence
push dx
mov dl,0dh
mov ah,02h
int 21h
mov dl,0ah
mov ah,02h
int 21h ;回车换行
pop dx
;****************比较查找信息******************** lea si,stoknim ;si指向关键字
lea di,sentence ;di指向句子
mov ax,0
mov bl,1 ;初始化bx
mov cl,0 ;初始化外循环计数单元
mov al,act
mov ah,ac
sub ah,al
add ah,1
mov cl,ah ;cl中循环次数
cmp cl,0
je nomatch
a:
push cx
mov cl,al
repnz cmpsb
jz match
sub di,1
sub si,2
add bl,1
pop cx
cmp cl,0
jne a
je nomatch
;***************输出信息************************* match:
lea dx,mess1
mov ah,09h
int 21h ;显示match
push dx
mov dl,0dh
mov ah,02h
int 21h
mov dl,0ah
mov ah,02h
int 21h ;回车换行
pop dx
lea dx,mess5
mov ah,09h
int 21h ;显示match at location
mov al,bl
and al,0fh
add al,30h
cmp al,3ah
jl p
add al,7h
p: mov dl,al
mov ah,02h
int 21h
lea dx,mess6
mov ah,09h
int 21h
push dx
mov dl,0dh
mov ah,02h
int 21h
mov dl,0ah
mov ah,02h
int 21h ;回车换行
pop dx
jmp wer
nomatch:
lea dx,mess2
mov ah,09h
int 21h ;显示no match
mov dl,0dh
mov ah,02h
int 21h
mov dl,0ah
mov ah,02h
int 21h ;回车换行
pop dx
wer: jmp d
main endp
CODES ENDS
END START
五、程序框图
实验三分类统计字符个数
一、实验要求
程序接受用户键入一行字符(字符个数不超过80个,该字符串用回车符结束),并按字母、数字、其它字符分类计数,然后将结果存入以letter、digit和other为名的存储单元中。
二、设计说明
(1)程序可采用01H功能调用把键入字符先分类计数再存入缓冲区中。(2)程序进入debug运行并查看计数结果。
三、实验程序
datarea segment
tou db 'enter word ',13,10,'$'
letter db 'letter:','$'
number db 'number:','$'
other db 'other:','$'
datarea ends
;***************************************************
codes segment
main proc far
assume cs:codes,ds:datarea
start:
push ds
sub ax,ax
push ax
mov ax,datarea
mov ds,ax
mov bx,0
mov cx,0
mov di,0
lea dx,tou
mov ah,09h
int 21h input:
mov ah,1
int 21h
cmp al,0dh
je disp
cmp al,30h
jae n1
o:
inc di
jmp short input n1:
cmp al,39h
ja n2
inc cx
jmp short input n2:
cmp al,41h
jae n3
jmp o
n3:
cmp al,5ah
ja n4
inc bx
jmp short input n4:
cmp al,61h
jae n5
jmp short o
n5:
cmp al,7ah
ja short o
inc bx
jmp short input disp:
push ax
mov dl,0dh
mov ah,09h
int 21h
mov dl,0ah
mov ah,09h
int 21h
pop ax
lea dx,letter
mov ah,09h
int 21h
pop ax
call binihex
push ax
mov dl,0dh
mov ah,09h
int 21h
mov dl,0ah
mov ah,09h
int 21h
pop ax
lea dx,number
push ax
mov ah,09h
int 21h
pop ax
mov bx,cx
call binihex
push ax
mov dl,0dh
mov ah,09h
int 21h
mov dl,0ah
mov ah,09h
int 21h
pop ax
lea dx,other
mov ah,09h
int 21h
mov bx,di
call binihex
push ax
mov dl,0dh
mov ah,09h
int 21h
mov dl,0ah
mov ah,09h
int 21h
pop ax
ret
main endp
;****************************** binihex proc near
push ax
push dx
mov ch,4
rotate:
mov cl,4
rol bx,cl
mov dl,bl
and dl,0fh
add dl,30h
cmp dl,3ah
jl printin
add dl,07h
printin:
mov ah,02h
int 21h
dec ch
jnz rotate
pop dx
pop ax
pop cx
ret
binihex endp
codes ends
end start
四、使用说明
程序进入后提示输入字符,可以输入任意字符,输入完成后键入回车键表示完成,则会在下一行输出实验结果。
五、程序框图
实验四查找电话号码
一、实验要求
(1)要求程序建立一个可存放50项的电话号码表,每项包括人名及电话号码两部分;
(2)程序可接受输入人名及相应的电话号码,并把它们加入电话号码表中;
(3)凡有新的输入后,程序可按人名对电话号码表重新排序;
(4)程序可接受需要查询电话号码的人名,并从电话号码表中查出其电话号码,再在屏幕上以如下格式显示出来。
Name tel
××××××××
二、设计说明
(1)显示提示符’Input name:’;
(2)调用子程序 input_name 接收人名;
(3)调用子程序 stor_name 把人名存入电话号码表 tel_tab 中:
(4)显示提示符’Input a telephone number:’;
(5)调用子程序 inphone 接收电话号码,并把它存入电话号码表tel_tab中;
(6)如输入已结束则调用 name_sort 子程序对电话号码表接人名排序;
(7)显示提示符’Do you want a telephone number ?(Y/N)’;
(8)回答N收退出程序;
(9)回答Y则再显示提示符’name ?’;
(10)调用子程序 input_name接收人名;
(11)调用子程序 name_search 在电话号码表中查找所要的电话号码; (12)调用子程序 printline 按要求格式显示人名及电话号码; (13)重复查号提示符直至用户不要求查号为止。
三、实验程序
dataseg segment
namepar label byte
maxnlen db 21
actnlen db ?
_name db 21 dup(?)
phonepar label byte
maxplen db 9
actplen db ?
phone db 9 dup(?)
crlf db 13,10,'$'
endaddr dw ?
mess1 db 'enter name:','$'
mess2 db 'enter a telephone number:','$'
mess3 db 'Do you want a telephone number?(Y/N)','$'
mess4 db 'name?','$'
mess5 db 'name',16 dup(' '),'tel',0dh,0ah,'$'
mess6 db 'Not in the table.',0dh,0ah,'$'
mess7 db 'Invalid input!',0dh,0ah,'$'
count db 0
tel_tab db 50 dup(20 dup(' '),8 dup(' '))
temp db 20 dup(' '),8 dup(' '),0dh,0ah,'$'
swapped db 0
dataseg ends
;********************************************************************** codeseg segment
main proc far
assume cs:codeseg,ds:dataseg,es:dataseg
start:
push ds
sub ax,ax
push ax
mov ax,dataseg
mov ds,ax
mov es,ax;
cld
lea di,tel_tab ;di中存放表首地址
inputloop:
mov ah,09h
int 21h
call input_name
cmp actnlen,0 ;没有输入人名时
jz a1 ;直接跳到提示是否查找的地方
cmp count,50 ;输入上限
je a1
call stor_name ;保存人名到tel_tab
mov ah,09h
lea dx,mess2
int 21h
call input_stor_phone ;输入并保存电话号码
jmp inputloop
a1:
cmp count,1
jbe searchloop ;如果没有输入或者输入一个
call name_sort ;排序
call disp_all ;显示所有
searchloop:
lea dx,mess3
mov ah,09h
int 21h
mov ah,01h
int 21h
cmp al,'N'
je exit
cmp al,'n'
je exit
cmp al,'Y'
je showname
cmp al,'y'
je showname
mov ah,09
lea dx,crlf
int 21h
lea dx,mess7 ;非法输入
mov ah,09h
int 21h
jmp searchloop
showname:
mov ah,09
lea dx,crlf
int 21h
lea dx,mess4 ;当输入Y时,显示'name?'
mov ah,09
call input_name ;输入要查找的人名
call name_search ;查找
call printline
jmp searchloop
exit:
ret
main endp
;******************************************************
input_name proc near
mov ah,0ah
lea dx,namepar
int 21h ;输入名字
mov dl,0ah
mov ah,02h
int 21h ;换行
mov bh,0 ;bx高位置0
mov bl,actnlen ;bx低位置输入名字个数
mov cx,21
sub cx,bx ;计算剩下的长度
i1:
mov _name[bx],20h
inc bx
loop i1 ;把bx之后剩下的填充空格
ret
input_name endp
;*********************************************************
stor_name proc near
inc count ;有人名输入所以个数加1
cld
lea si,_name ;把si指向刚才输入名字的位置
mov cx,10 ;把name中的前20个字符放入tel_tab中每一个人信息的前20个byte中rep movsw ;把si所指名字赋值给di所指地方tel_tab
ret
stor_name endp
;*****************************************************
input_stor_phone proc near
mov ah,0ah
lea dx,phonepar
int 21h ;把电话号码存入phonrpar
mov ah,02h
mov dl,0ah ;换行
int 21h
mov bh,0
mov bl,actplen
sub cx,bx ;计算剩下的长度
s2:
mov phone[bx],20h ;剩下的地方填充空格
inc bx
loop s2
cld
lea si,phone ;再把名字放入之后di就已经移动到名字之后了
mov cx,4 ;把phone中的前8个字符放入tel_tab中每一个人信息的后8个byte中rep movsw
ret
input_stor_phone endp
;*****************************************************************
name_sort proc near
sub di,56
mov endaddr,di
n1:
mov swapped,0
lea si,tel_tab
n2:
mov cx,20
mov di,si
add di,28 ;下一个被比较的名字
mov ax,di
mov bx,si
repe cmpsb ;比较20次
jbe n3 ;小于或等于不用交换
call npxchg
n3:
mov si,ax
cmp si,endaddr
jbe n2
cmp swapped,0
jnz n1
ret
name_sort endp
;*****************************************************
npxchg proc near
mov cx,14 ;交换名字和电话号码
lea di,temp
mov si,bx
rep movsw ;move lower item to save
mov cx,14
mov di,bx
rep movsw
lea si,temp
rep movsw
mov swapped,1
ret
npxchg endp
;************************************************************ disp_all proc near
mov ah,09h
lea dx,mess5
int 21h
lea si,tel_tab
d1:
lea di,temp
mov cx,14
rep movsw
mov ah,09h
lea dx,temp
int 21h
dec count
jnz d1
ret
disp_all endp
;*********************************************
name_search proc near
lea si,tel_tab
mov bx,si
add endaddr,28
e1:
lea di,_name ;存放待查找的人名地址
mov cx,10
repe cmpsw
jcxz exit3 ;相等
add bx,28 ;表中下一个比较的人名
mov si,bx
cmp si,endaddr
jbe e1
mov cx,-1
ret
exit3:
mov si,bx
lea di,temp
mov cx,14
rep movsw
ret
name_search endp
;*******************************************************
printline proc near
cmp cx,-1
je norecord
mov ah,09h
lea dx,mess5
int 21h ;输出name和tel
mov ah,09h
lea dx,temp
int 21h ;输出名字和电话号码
ret
norecord:
mov ah,09h
lea dx,mess6
int 21h ;输出没找到
ret
printline endp
;************************************************************
codeseg ends
end start
四、使用说明
根据提示输入人名及电话号码,使用回车键表示输入结束,如不需输入人名,则在提示后直接输入回车键,表示输入完成,程序将自动显示电话号码表。如需查询则可输入y(大小写均可),否则输入n (大小写均可)。
五、模块层次图及说明
(1)主函数main:用来显示用户操作提示,调用子模块,使程序完成查找电话号码的过程;
(2)接收人名函数input_name:输入人名,将此人名保存至缓冲区,并用空格补足剩余空间;(3)保存人名函数stor_name:将人名从缓冲区中取出,保存在电话号码表中的人名区中;
(4)接收并且保存电话号码函数inphone:输入电话号码,将此电话号码保存至缓冲区,并用空格补足,然后,将电话号码从缓冲区中取出,保存在电话号码表中的电话号码区(即人名区之后);(5)电话号码表排序函数name_sort:运用冒泡排序法,对电话号码表按人名ASCⅡ码递增方向的排序;
(6)交换条目位置函数exchange:将不符合排序规律的条目的位置进行调整;
(7)查找电话号码函数name_search:输入人名,在电话号码表中依次比较人名进行查找;
(8)输出电话号码条目函数printline:查找到条目之后,将条目输出;
(9)输出电话号码表函数printall:将整个电话号码表的所有条目依次输出。
实验心得体会:
这次汇编实验历时一周,五天时间完成了4个编程实验:用表格形式显示字符、查找匹配字符串、分类统计字符个数、查找电话号码。
用表格形式显示字符和查找匹配字符串是使用了循环程序设计思想。显示字符实验较为简单,只需要一些基础知识即可完成。而查找字符串较耗费时间,这个实验主要难点就在从句子中查找关键字。查找关键字是使用的串比较指令。这个指令只能进行比较,查找就需要移动指针,将整个句子都与关键字比较一遍,才能确定是否找到了关键字。
分类统计字符个数与查找电话号码较难,花费了我最多的时间。分类统计字符个数是应用了分支程序设计,而查找电话号码是应用了子程序设计。分类统计字符个数是将输入的字符与多个条件进行比较,找到符合条件的程序段就执行,否则就跳到下一个。查找电话号码是使用子程序较多,整个程序主要都有子程序组成,程序难点就在子程序调用条件,应当按照实验要求调整各个子程序的调用时间。
实验过程中遇到了很多问题,有许多问题是我自己无法解决的,只能通过向其他同学学习,才能将实验完成。这次实验培养了我的实践能力,使我将书本中的理论知识转变成了现实的程序,为今后的学习和使用打下了结实的基础。通过实验使我进一步巩固所学汇编课程内容并掌握汇编程序在程序设计中的应用方法,并对汇编程序设计及应用有整体的认识。