当前位置:文档之家› 汇编语言程序设计实验报告

汇编语言程序设计实验报告

汇编语言程序设计实验报告
汇编语言程序设计实验报告

实验报告实验名称汇编语言程序设计

|

|

专业班级:信息安全

学号:

姓名:

实验一汇编语言上机过程和Debug常用调试命令

一.实验目的:

学习程序设计的基本方法和技能,熟练掌握用汇编语言设计、编写、调试和运行程序的方法。

二.实验题目:

熟悉与实验有关的系统软件(如编辑程序、汇编程序、连接程序和调试程序等)的使用方法。在调试过程中,学习及掌握debug程序的各种操作命令。

三.问题描述:

试编写一程序:比较两个字符串string1和string2所含的字符是否相同,若相同则显示‘match’; 否则,显示‘no match’。

四.方法说明:

a)使用ws、tc或EDIT编辑程序来建立源文件,然后存盘,使系统返回DOS。

b)用汇编程序masm(或asm)对源文件汇编产生目标文件obj

如:汇编指示出错则需重新调用编辑程序修改错误,直至汇编通过为止。

c)用连接程序link 产生执行文件EXE.

d)执行程序,可直接从DOS执行程序。

e)使用debug程序调试程序的方法。

五.实验步骤:

1.调用字处理程序EDIT 建立以sample.asm文件

datarea segment

string1 db‘move the cursor backward.’

string2 db‘move the cursor backward.’

mess1 db ‘Match..’,13,10,’$’

mess2 db ‘No match!..’,13,10,’$’

datarea ends

prognam segment

main proc far

assume cs:prognam,ds:datarea,es:datarea

start:

push ds

sub ax,ax

push ax

mov ax,datarea

mov ds,ax

mov es,ax

lea si,string1

lea di,string2

cld

mov cx,25

repz cmpsb

jz match

lea dx,mess2

jmp short disp

match:

lea dx, mess1

disp:

mov ah,09

int 21h

ret

main endp

prognam ends

end start

2.对源文件汇编产生目标文件obj

D:\masm 文件名。Asm

3.用连接程序link产生执行文件exe

D:\link文件名。Obj

4.执行程序

D:\ 文件名

5. 使用debug程序调试程序的方法。

d>debug 文件名.exe

_

1.用G命令运行程序

2.用U命令显示程序

3.学会设置断点。

4.学会查看数据段的内容情况D

5.用E命令修改数据区的字符串。

6.用A 命令把数据区的内容恢复原状

7.T命令逐条跟踪程序的执行

8.学会使用F命令、R命令、Q命令等等

五、实验总结

第一次进行汇编实验,主要是学习程序设计的基本方法和技能,熟练掌握用汇编语言设计、编写、调试和运行程序的方法,只有多上机练习,才能更好的掌握汇编语言程序设计的思想。

实验二循环程序设计1

循环结构是控制重复执行某一程序段的基本程序结构. 在汇编语言程序设计中, 循环程序的地位也是极为重要,从本质上来看, 循环程序结构是分支程序结构的一种手特殊形式, 也是使用条件转移指令来控制执行循环的.

一.实验目的:

学会用循环结构进行程序编程。

二.实验题目:

设计一个按表格形式显示ASC||码为10H—100H的所有字符的程序。

三.实验要求:

按15行*16列的表格形式显示ASC||码为10H----100H的所有字符,即以行为主的顺序及ASC||码递增的次序依次显示对应的字符。每16个字符为一行,每行中的相邻两个字符之间用空白符(ASC||为0)隔开。

四.方法说明:

(1) 显示每个字符可使用功能号为02的显示输出功能调用,使用方法

如下:

mov ah,02h

mov dl,0AH

int 21h

本题中可把dl 初始化为10H, 然后不断使其加1(用INC指令) 以取得下一个字符的ASC||码。

(2) 显示空白符时,用其ASC||码0置入dl 寄存器,每行结束时,用

显示回车(ASC||为0dh)和换行符(ASC||为oah)来结束本行并开始下一

行。

(3) 由于逐个显示相继的ASC||字符时,需要保存并不断修改dl寄存

器的内容,而显示空白、回车、换行符时也需要使用dl寄存器,为此

可使用堆栈来保存相继的ASC||字符。具体用法是:在显示空白或回车,

换行符前用指令

push dx 把dl 的内容保存到堆栈中去。在显示空白或回车,换行符后用指令

pop dx 恢复dl寄存器的原始内容。

五、实验代码

stack segment

db 100 dup (?)

stack ends

code segment

assume cs:code,ss:stack

start:

mov dl,10h

mov cl,0fh

loopc:

mov ah,02h

mov al,dl

int 21h

inc dl

push dx

mov dl,0h

mov ah,02h

mov al,dl

int 21h

pop dx

loopnz loopc

push dx

mov dl,0dh

mov ah,02h

mov al,dl

int 21h

mov dl,0ah

mov ah,02h

mov al,dl

int 21h

pop dx

mov cl,0fh

cmp dl,0h

jne loopc

mov ah,4ch

int 21h

code ends

end start

六、实验结果

七、实验总结

本次试验学会用循环结构进行程序编程,学好循环程序是很重要的,在程序设计中,它的地位是极其重要的。

实验三循环程序设计2

一.实验目的:

学会用循环程序设计进行程序编程。

二.实验题目:

设计查找匹配字符串SEARCH的程序。

三.问题要求:

程序接收用户键入的一个关键字以及一个句子。如果句子中不包含关键字则显示’no match’;如果句子中包含关键字则显示‘match’,

且把该字在句子中的位置用十六进制数显示出来,要求程序的执行过程

如下:

enter keyword :abc

enter sentence :we are studying abc

match at location :11H of the sentence

enter sentence: xyz ,ok?

no match

enter sentence :^c

四. 方法说明:

程序可由三部分组成:

(1 ) 输入关键字和一个句子,分别存入相应的缓冲区中,可用功能调用

0AH。

(2)在句子中查找关键字。

1.关键字和一个句子中相应字段的比较可使用串比较指令,为此必须定义附加段,但附加段和数据段可以定义为同一段,以便于串指

令的使用,这样,相应的寄存器内容也有了确定的含义,如下:

SI 寄存器为关键字的指针

DI 寄存器为句子中正相比较的字段的指针

CX寄存器存放关键字的字母个数(长度)

2.整个句子和关键字的比较过程可以用一个循环结构来完成。循环次数为:

(句子长度--关键字长度)+1在计算循环次数时,如遇到句子长度小

于关键字长度的情况则应转向显示“no match”,循环中还需要用

到BX寄存器,它用来保存句子中当前正在比较字段的首地址。

(3)输出信息:

用功能调用09h分“找到”或“找不到”两种情况分别显示不同的信息。在“找到”时,还要求显示出匹配字符串在句子中的位置,在“找到”时BX寄存器的内容为匹配字符串的首地址,将此值减到句子的首地址,再将差值加1 即是所要的匹配字符串在句子中的位置,可将位置转换为十六进制数从屏幕上显示出来。

五、实验代码

sseg segment stack

dw 256 dup (?)

sseg ends

data segment

msg1 db'Enter keyword:',24h

msg2 db'Enter Sentence:',24h

cr db 13,10,24h

keyword db 250,?,250 dup (?)

Sentence db 250,?,250 dup (?)

match db'Match at location:',24h

match1 db' of the sentence',13,10,24h nomatch db'No match',13,10,24h

data ends

code segment

assume cs:code,ds:data,ss:sseg

disp_hex proc near

push ax

push cx

push dx

push ax

mov cl,4

ror al,cl

and al,0fh

add al,30h

cmp al,39h

jna d1

add al,7

d1:

mov dl,al

mov ah,2

int 21h

pop ax

and al,0fh

add al,30h

cmp al,39h

jna d2

add al,7

d2:

mov dl,al

mov ah,2

int 21h

mov dl,'h'

mov ah,2

int 21h

pop dx

pop cx

pop ax

ret

disp_hex endp

begin:

mov ax,data

mov ds,ax

mov es,ax

mov dx,offset msg1

mov ah,9

int 21h

mov dx,offset keyword

mov ah,0ah

int 21h

cmp keyword + 1,0 je quit

mov dx,offset cr

mov ah,9

int 21h

b1:

mov dx,offset msg2

mov ah,9

int 21h

mov dx,offset Sentence

mov ah,0ah

int 21h

mov dx,offset cr

mov ah,9

int 21h

mov dl,Sentence + 1

cmp dl,0

je quit

mov dh,keyword + 1

mov di,offset Sentence + 2

b2:

cmp dh,dl

ja _nomatch

mov si,offset keyword + 2 mov cl,dh

mov ch,0

cld

push di

repe cmpsb

pop di

je _match

inc di

dec dl

jmp b2

_match:

mov ax,di

sub ax,offset Sentence + 2

inc ax

push ax

mov dx,offset match

mov ah,9

int 21h

pop ax

call disp_hex

mov dx,offset match1

mov ah,9

int 21h

jmp b1

_nomatch:

mov dx,offset nomatch

mov ah,9

int 21h

jmp b1

quit:

mov ah,4ch

int 21h

code ends

end begin

六、实验结果

七、实验总结

本次试验主要考察了串比较指令的用法,同时将串指令和REPE联合起来用,使得指令变得简单。实验中还用到了一些数据结构,开始时需要定义空间以及缓冲区。

另外程序需要运用有两层循环,内循环由CX记录关键字长度控制循环计数,外循环是由ax记录外循环次数控制外循环计数。

通过本次实验,使我更加熟悉了课堂上知识,还培养了我将理论知识运用到实际编程中去的能力。

实验四分支程序设计

一.实验目的:

学会用分支程序设计进行程序编程。

二.实验题目:

设计一个程序能分类统计字符个数

三.实验要求:

程序接收用户键入的一行字符(字符个数不超过80个,该字符串用回车符结束),并按字母、数字及其它字符分类计数,然后将结果存入以letter、digit和other为名的存储单元中。

四.方法说明:

程序可采用0AH功能调用把键入字符直接送到缓冲区中,然后再逐个取出分类计数,也可采用01H功能调用在接收字符后先分类计数然后再存入缓冲区中。

程序需进入debug 运行并查看计数结果。

五.实验代码

DATAS SEGMENT

STRING1 DB'Input Your String: $';输入提示信息

STRING2 DB'Digit: $';各类字符提示信息

STRING3 DB'Letter: $'

STRING5 DB'Others: $'

DIGIT DB 0 ;数字

CHARS DB 0 ;字母

OTHERS DB 0 ;其他

DATAS ENDS

CODES SEGMENT

ASSUME CS:CODES,DS:DATAS

START:

MOV AX,DATAS

LEA DX,STRING1 ;显示输入提示信息

MOV AH,9

INT 21H

MOV CX,100 ;设置循环次数足够大

L1:MOV AH,1 ;中断调用,单字符输入

INT 21H

CMP AL,0DH ;若输入回车符则结束

JZ OVER2

CMP AL,30H

JB OTHER ;若<30H(0),OTHERS++

CMP AL,39H ;若>39H(9),跳转进一步比较

JA HIGHER1

JMP DIGITAL ;DIGIT++

HIGHER1: CMP AL,41H ;if<41H(A),OTHERS++

JB OTHER

CMP AL,5AH ;if>5AH(Z),跳转继续比较

JA HIGHER2

JMP CHAR ;ALPHAU++

HIGHER2: CMP AL,61H ;if<61H(a),OTHERS++

JB OTHER

CMP AL,7AH ;if>7AH(z),OTHERS++

JA OTHER

JMP CHAR ;ALPHAL++

JMP OVER ;比较结束

OTHER: INC OTHERS ;OTHERS++

JMP OVER

DIGITAL: INC DIGIT ;DIGIT++

JMP OVER

CHAR: INC CHARS ;ALPHAL++

JMP OVER

JMP OVER

OVER:NOP

LOOP L1 ;循环,输入下一字符

OVER2:CALL ENDLINE ;回车换行

LEA DX,STRING2 ;输出提示信息

MOV AH,9

INT 21H

XOR AX,AX

MOV AL,DIGIT ;将统计的数字送AX,为输出做准备

CALL DISPLAY ;调用输出两位数字的子程序

CALL ENDLINE ;下同

LEA DX,STRING3

MOV AH,9

INT 21H

XOR AX,AX

MOV AL,CHARS

CALL DISPLAY

CALL ENDLINE

LEA DX,STRING5

MOV AH,9

INT 21H

XOR AX,AX

MOV AL,OTHERS

CALL DISPLAY

MOV AH,4CH

INT 21H

ENDLINE PROC NEAR ;控制输出格式,输出回车换行子程序MOV AH,2

MOV DL,0AH

MOV AH,2

MOV DL,0DH

INT 21H

RET

ENDLINE ENDP

DISPLAY PROC NEAR ;输出两位数字的子程序

MOV BL,10 ;10送BL

DIV BL ;AX/BL,AL=商,AH=余数

PUSH AX ;保存AX中的信息

MOV DL,AL

ADD DL,30H

MOV AH,2

INT 21H ;输出十位数

POP AX ;出栈送AX

MOV DL,AH

ADD DL,30H

MOV AH,2

INT 21H ;输出个位数

RET

DISPLAY ENDP

CODES ENDS

END START

六.实验总结

本次实验要求我们学会用分支程序设计进行程序编程,其中运用到许多跳转和比较指令,只要细心一点,理清思路就能很容易的将本程序编写出来。

实验五子程序设计

一.实验目的:

学会用子程序设计进行程序编程。

二.实验题目:

设计一个能查找电话号码phone的程序。

三.实验要求:

i.要求程序建立一个可存放50项的电话号码表,每项包括人名(20个

字符)及电话号码(8个字符)两部分;

ii.程序可接收输入人名及相应的电话号码,并把它们加入电话号码表中;

iii.凡有新的输入后,程序应按人名对电话号码表重新排序;

iv.程序可接收需要查找电话号码的人名,并从电话号码表中查出其电话号码,再在屏幕上以如下格式显示出来。

name tel

**** ****

四.实验提示:

程序采用子程序结构,主程序的主要部分如下:

. 显示提示符‘input name:’;

. 调用子程序input_name接收人名;

. 调用子程序stor_name把人名存入电话号码表tel_tab中;

. 显示提示符‘input a telephone number:’;

. 调用子程序inphone接收电话号码,并把它存入电话号码表tel_tab 中;

. 如输入已结束则调用name_sort子程序对电话号码表按人名排序; . 显示提示符‘DO you want a telephone number?(y/n)’;

. 回答N则退出程序;

. 回答Y则再显示提示符‘ name?’;

. 调用子程序input_name接收人名;

. 调用子程序name_search在电话号码表中查找所要的电话号码;

. 调用子程序printline按要求格式显示人名及电话号码;

. 重复查号提示符直至用户不再要求查号为止。

五、实验代码

data segment

tel_tab db 50 dup( 28 dup(' ')) ; tel_tab电话本空间

tab_len dw 0 ; 已存联系人数目

endaddr dw 0 ; 最后一个联系人的地址+28

tname db 21,?,20 dup(' '),? ; 姓名缓冲区

tphone db 9,?,8 dup(' '),? ; 号码缓冲区

temp db 28 dup(?) ; 一个联系人的临时空间

iname db 13,10,'Input name:',13,10,'$'

iphone db 13,10,'Input a telephone number:',13,10,'$'

go_on db 13,10,'Continue insert? ',13,10,'$'; 提示是否继续插入联系人

sname db 13,10,'Name?',13,10,'$'

name_e db 13,10,13,10,'The name has been in the table! Please input again!',13,10,'$'

text2 db 13,10,'Name Tel. ',13,10,'$'

text3 db 13,10,'The name is not in the telephone table!',13,10,'$'

text4 db 13,10,13,10,'Do you want a telephone number? ',13,10,'$'

data ends

code segment

; ****************************************************************************

; 主程序

; -------------------------------------------------------------------------------------

main proc far

assume cs:code ,ds:data,es:data

start:

push ds ; 保存旧数据用于返回

sub ax,ax

push ax

mov ax,data ; 数据段、附加段初始化

mov ds,ax

mov es,ax

inname: lea dx,iname ; 提示输入姓名

mov ah,09h

int 21h

call input_name ; 调用读入姓名子程序

call name_search ; 调用查找子程序,

cmp bx,-1 ; 如表中不存在该联系人

je stor ; 则跳转到stor

call crlf ; 回车换行

lea dx,name_e ; 否则提示该联系人已在表中,提示重新输入

mov ah,09h

int 21h

jmp inname

stor: call stor_name ; 调用姓名转存子程序,把姓名移动到表中

lea dx,iphone ; 提示输入电话号码

mov ah,09h

int 21h

call inphone ; 调用读入号码子程序

call name_sort ; 排序

call crlf

lea dx,go_on ; 提示是否继续插入

mov ah,09h

int 21h

choice1: mov ah,07 ; 读取用户选择

int 21h

cmp al,'y'

je inname

cmp al,'Y'

je inname

cmp al,'n'

je print_all ; 如选择不插入,则显示所有记录

cmp al,'N'

je print_all

jmp choice1

print_all: call printall ; 显示所有记录

want_search: call crlf

lea dx,text4 ; 提示是否查找号码

mov ah,09

int 21h

call crlf

choice2: mov ah,07 ; 读取用户选择

int 21h

cmp al,'y'

je search ; 如果为y或Y则跳转到查找search

cmp al,'Y'

je search

cmp al,'n' ; 为n或N则退出程序

je exit_m

cmp al,'N'

je exit_m

jmp choice2

search: lea dx,sname ; 提示用户输入要查找的姓名

mov ah,09

int 21h

call input_name ; 读入姓名

call name_search ; 查找

call crlf

call crlf

cmp bx,-1 ; 是否查找到?

je not_find ; (bx)=1 则跳转到未找到not_find

lea dx,text2 ; 找到则输出 'Name Tel. '

mov ah,09

int 21h

call printline ; 显示查找到的联系人

jmp want_search ; 跳转到提示查找

not_find: ; 未找到

call crlf

lea dx,text3 ;输出 'The name is not in the telephone table!'

mov ah,09h

int 21h

jmp want_search

exit_m: ret

printall proc near

;**************************************************************************

;显示所有电话。显示电话表中的所有姓名和号码,查看排序结果是否正确

;---------------------------------------------------------------------------------------------- call crlf

call crlf

lea dx,text2 ; 输出'Name Tel. '

mov ah,09

int 21h

lea bx,tel_tab ; 号码表基址

rept1: call printline ; 显示联系人

add bx,28 ; 求下一个联系人首地址

cmp bx,endaddr ; 是否到达表尾?

jb rept1 ; 未到达则继续显示

ret

printall endp

;*******************************************************************

;输入姓名子程序:读入姓名到tname缓冲区,并把不满20位的部分

;补上空格(方便查找时的比较)

;----------------------------------------------------------------------------------

input_name proc near

call crlf

noinputn: lea dx,tname ; 姓名缓冲区

mov ah,0ah ; 调用dos 0ah读入字符串功能

int 21h

cmp tname[1],0 ; 如果输入为回车

je noinputn ; 继续等待输入

xor bx,bx

mov bl,tname[1]

mov cx,20

sub cx,bx

set_blank: mov tname[bx+2],20h ; 把不满20位的部分补空格

inc bx

loop set_blank

call crlf

ret

input_name endp

;*****************************************************************

;stor_name,该子程序把tname缓冲区的姓名转存入号码表中

;---------------------------------------------------------------------------------

stor_name proc near

xor cx,cx

mov cl,tname[1] ;字符个数

lea si,tname[2]

mov di,endaddr

cld

rep movsb

inc tab_len ;联系人人数增1

add endaddr,28 ;最后一个联系人地址增28

ret

stor_name endp

;***************************************************************

;获取号码子程序:读入用户输入的号码到tphone缓冲区,然后

;转存入号码表对应位置

;------------------------------------------------------------------------------------

inphone proc near

noinputp: call crlf

lea dx,tphone

mov ah,0ah

int 21h ;调用dos 0a号功能输入字符串

cmp tphone[1],0 ;判断输入是否为回车

je noinputp ;是,则继续等待输入

xor cx,cx

mov cl,tphone[1]

lea si,tphone[2]

mov di,endaddr

sub di,8 ;待插入位置

cld

rep movsb ;移动

ret

inphone endp

;**********************************************************************

;排序子程序(用直接插入排序),对号码表进行按人名从小到大排序

;-------------------------------------------------------------------------------------------------- name_sort proc near

cmp [tab_len],1 ;记录数1,不用排序

je exitn

lea di,tel_tab ;第一个记录地址

mov si,endaddr

sub si,28 ;最后一个记录-待排序记录的地址

next1: mov cx,20

mov ax,si ;暂存两个地址

mov dx,di

cld

repe cmpsb ;查找插入位置

jb insert

mov si,ax

mov di,dx

add di,28 ;比较下一个

cmp di,si ;是否比较完

jb next1 ;没有则继续比较

jmp exitn ;否则排序完成

insert:

mov cx,28

mov si,ax

lea di,temp

rep movsb ;待排序数据放到缓冲区

mov di,ax

next2: mov cx,28

mov si,di

sub si,28

rep movsb ;记录后移

sub di,56

cmp di,dx

ja next2

mov cx,28

mov di,dx

lea si,temp

rep movsb ;插入到待插位置

exitn: ret

name_sort endp

;******************************************************************************

;姓名查找子程序。入口参数为tname缓冲区的人名,用寄存器bx返回结果,找到则返回该

;姓名对应记录的地址,未找到则返回(bx)=-1

;-------------------------------------------------------------------------------------------------------------------

name_search p roc near

cmp tab_len,0 ; 记录为0,无法查找

je exit_nofind

lea si,tname[2] ; 待查姓名地址

mov ax,si ; 暂存si

lea bx,tel_tab ; 从第一个记录开始查找

rsearch: mov cx,20

mov di,bx

repe cmpsb

jz exit_n

mov si,ax

add bx,28 ; 查找下一个

cmp bx,endaddr

jb rsearch

exit_nofind: mov bx,-1 ;未找到则(bx)=-1

exit_n: ret

name_search e ndp

;******************************************************************************

;显示姓名和电话子程序。待显示的记录的地址保存在bx寄存器。

;-----------------------------------------------------------------------------------------

printline proc near

push ax ;保存ax

call crlf

xor si,si

mov cx,28 ;共28个字符

mov ah,02h ;调用dos 2 号显示字符功能

nextc: mov dl,[bx][si] ;待显示字符

int 21h

inc si ;输出下一个字符

loop nextc

call crlf

pop ax

ret

printline endp

;******************* ***********************************************************

;回车换行子程序

;-----------------------------------------------------------------------------------------

crlf proc near

push ax

push dx

mov ah,02h

mov dl,0dh ; 回车

int 21h

mov dl,0ah ; 换行

int 21h

pop dx

pop ax

ret

crlf endp

;-----------------------------------------------------------------------------------------

main endp ; 主程序结束

code ends ; 代码段结束

end start ; 程序结束

六、实验总结

本次实验前应先画好程序框图和模块调用图,并在编码中不断修改完善,对把握程序的整体结构很有帮助。把模块设计成子程序在主程序调用,分解了整个程序功能,降低了设计的难度,同时方便调试和修改。总的来说,此次实验有点难度,但是平时多上机练习,完成此次实验并不是难事。

相关主题
文本预览
相关文档 最新文档