实验五 子程序设计实验设计性实验汇编语言资料.docx
《实验五 子程序设计实验设计性实验汇编语言资料.docx》由会员分享,可在线阅读,更多相关《实验五 子程序设计实验设计性实验汇编语言资料.docx(23页珍藏版)》请在冰豆网上搜索。
实验五子程序设计实验设计性实验汇编语言资料
实验五子程序设计实验(设计性实验)
一、实验要求和目的
1.熟悉汇编语言程序设计结构;
2.熟悉汇编语言子程序设计方法;
3.熟悉利用汇编语言子程序参数传递方法;
4.熟悉汇编语言字符串处理基本指令的使用方法;
5.掌握利用汇编语言实现字符串的输入输出程序设计方法;
6.掌握数制转换程序实现方法。
二、软硬件环境
1、硬件环境:
计算机系统windows;
2、软件环境:
装有MASM、DEBUG、LINK、等应用程序。
三、实验涉及的主要知识
A)子程序知识要点:
1、掌握子程序的定义语句;
过程名PROC[near/far]
过程体
RET
过程名ENDP
2.子程序结构形式
一个完整的子程序一般应包含下列内容:
1)子程序的说明部分
在设计了程序时,要建立子程序的文档说明,使用户能清楚此子程序的功能和调用方法.
说明时,应含如下内容:
.子程序名:
命名时要名中见意.
.子程序的功能:
说明子程序完成的任务;
.子程序入口参数:
说明子程序运行所需参数及存放位置;
.子程序出口参数:
说明子程序运行结果的参数及存放位置;
.子程序所占用的寄存器和工作单元;
.子程序调用示例;
2)掌握子程序的调用与返回
在汇编语言中,子程序的调用用CALL,返回用RET指令来完成。
.段内调用与返回:
调用子程序指令与子程序同在一个段内。
因此只修改IP;
.段间调用与返回:
调用子程序与子程序分别在不同的段,因此在返回时,需同时修改
CS:
IP。
3)子程序的现场保护与恢复
保护现场:
在子程序设计时,CPU内部寄存器内容的保护和恢复。
一般利用堆栈实现现场保护和恢复的格式:
过程名PROC[NEAR/FAR]
PUSHAX
PUSHBX
.
.
PUSHDX
.
.
.
POPDX
.
.
.
POPAX
RET
过程名ENDP
4.子程序的参数传递方法
1.寄存器传递参数
这种方式是最基本的参数传递方式。
2.存储器单元传(变量)递参数
这种方法是在主程序调用子程序前,将入口参数存放到约定的存储单元中;子程序运行时到约定存储位置读取参数;子程序执行结束后将结果也放在约定存储单元中。
3.用堆栈传递参数
利用共享堆栈区,来传递参数是重要的的方法之一。
B)字符、字符串输入输出知识要点:
在实际应用中,经常需要从键盘输入数据并将结果等内容显示到屏幕上,方便程序控制
及查看结果。
汇编语言的数据输入和输出分成两类,一是单个字符数据的输入输出,一是字
符串数据的输入输出。
都可以通过DOS功能调用来实现,下面就分别介绍下用来实现数据输
入输出的功能调用的使用方法。
1、单个字符输入
单个字符输入可以利用DOS的1号功能调用来完成,使用方法为:
MOVAH,1
INT21H
这两条语句执行后,光标会在屏幕上闪烁,等待输入数据,输入的数据以ASCII
码形式存储在AL寄存器中。
2、单个字符输出
单个字符输出可利用DOS2号功能调用来完成,使用方法为:
MOVDL,’?
’
MOVAH,2
INT21H
单个字符输出需要把要输出字符的ASCII码放在DL寄存器中。
3、字符串输入
从键盘输入一串字符串可以利用DOS的10号功能调用来完成,使用方法为:
BUFDB50;预定义可以输入的最大字符个数
DB?
;实际输入字符个数,根据输入自动统计
DB50DUP(?
);存放输入字符串数据缓冲区
LEADX,BUF
MOVAH,10
INT21H
4、字符串输出
字符串输出可由DOS9号功能调用来完成,使用方法为:
STRINGDB‘HELLO$’
LEADX,STRING
MOVAH,9
INT21H
C)表的处理知识要点:
表的处理在实际数据处理中应用较为广泛,主要有排序、搜索、插入和删除等操作。
有
一些常用的冒泡法、对分搜索法等需要掌握。
四、实验内容与步骤
1、从键盘输入一串字符串(显示提示)到内存中,在该字符串的某一个指定位置,插入某一字符或删除某一字符,并显示操作后的字符串。
程序代码:
DATASSEGMENT
BUFDB20
DB?
DB20DUP(0)
DB6DUP(0)
STRING0DB'PLEASEINPUTSTRINGS:
',0AH,0DH,'$'
STRING1DB'PLEASECHOOSEINSERTORDELETE:
1.INSERT2.DELETE',0AH,0DH,'$'
STRING2DB'PLEASEINPUTTHEADDRESSTODELETE',0AH,0DH,'$'
STRING3DB'PLEASEINPUTTHEADDRESSTOINSERT',0AH,0DH,'$'
STRING4DB'PLEASEINPUTTHESYMBOLTOINSERT',0AH,0DH,'$'
BUF1DB20DUP(0),'$'
INSERDB0,0
DELEDB0
NUMBERDB0
DATASENDS
STACKSSEGMENT
DB256DUP(0)
STACKSENDS
CODESSEGMENT
ASSUMECS:
CODES,DS:
DATAS,SS:
STACKS
START:
MOVAX,DATAS
MOVDS,AX
MOVES,AX
LEABX,STRING0
CALLOUTPUTSTR;输出字符串0
CALLINPUTSTR;输入字符串
CALLHUICHE
MOVAL,[BUF+1]
MOVNUMBER,AL
LEABX,STRING1
CALLOUTPUTSTR;输出字符串1
MOVAH,01H;输入1或2
INT21H
CMPAL,'1'
CALLHUICHE
JZIN1
LEABX,STRING2;为2,执行删除操作
CALLOUTPUTSTR
MOVAH,01H
INT21H
ANDAL,0FH
MOV[DELE],AL
CALLHUICHE
CALLDELETE
CALLMOVE1
LEABX,BUF1
CALLOUTPUTSTR
CALLHUICHE
JMPFINAL
IN1:
LEABX,STRING3;执行插入操作
CALLOUTPUTSTR
MOVAH,01H
INT21H
ANDAL,0FH
MOV[INSER],AL
CALLHUICHE
LEABX,STRING4
CALLOUTPUTSTR
MOVAH,01H
INT21H
MOV[INSER+1],AL
CALLHUICHE
CALLINSERT
CALLMOVE1
LEABX,BUF1
CALLOUTPUTSTR
FINAL:
MOVAH,4CH
INT21H
INPUTSTRPROCNEAR;输入函数
LEADX,BUF
MOVAH,0AH
INT21H
RET
INPUTSTRENDP
HUICHEPROCNEAR;回车换行函数
MOVDL,0DH
MOVAH,02H
INT21H
MOVDL,0AH
MOVAH,02H
INT21H
RET
HUICHEENDP
OUTPUTSTRPROCNEAR
MOVDX,BX;输出字符串函数
MOVAH,09H
INT21H
RET
OUTPUTSTRENDP
DELETEPROCNEAR删除函数
LEABX,BUF
MOVDI,BX
ADDDI,2
MOVAL,DELE
XORAH,AH
ADDDI,AX
XORCH,CH
MOVCL,NUMBER
ADDBX,CX
ADDBX,1
MOVE:
CMPBX,DI
JELADE
MOVDH,[DI+1]
MOV[DI],DH
INCDI
CMPBX,DI
JNEMOVE
LADE:
MOVBYTEPTR[DI],'$'
DECNUMBER
RET
DELETEENDP
MOVE1PROCNEAR;移动复制函数
LEASI,BUF
ADDSI,2
LEADI,BUF1
MOVCL,NUMBER
XORCH,CH
REPMOVSB
MOVBYTEPTR[DI],'$'
RET
MOVE1ENDP
INSERTPROCNEAR;插入函数
LEABX,BUF
MOVDI,BX
MOVAL,[INSER]
XORAH,AH
ADDDI,AX
INCDI
XORCH,CH
MOVCL,NUMBER
ADDBX,CX
ADDBX,1
INS1:
MOVDH,[BX]
MOV[BX+1],DH
DECBX
CMPBX,DI
JAINS1
INCBX
MOVAL,[INSER+1]
MOV[BX],AL
INCNUMBER
RET
INSERTENDP
CODESENDS
ENDSTART
运行结果:
1.执行插入操作结果
2.执行删除操作结果
2、编写程序把从键盘输入的四位十六进制数,转换为十进制形式在屏幕上打印出来。
程序代码:
DATASSEGMENT
BUFDB10
DB?
DB10DUP(0)
BIAODB0
STRIDB0,0
FLAGDB0
DATASENDS
STACKSSEGMENT
STADW20HDUP(0)
STACKSENDS
CODESSEGMENT
ASSUMECS:
CODES,DS:
DATAS,SS:
STACKS
START:
MOVAX,DATAS
MOVDS,AX
CALLINPUT;输入4位16进制数
CALLHUICHE
CALLEXCHASC;将ASC码转换
CALLYASUO;将实际数值放在ax
MOVAL,[STRI]
MOVAH,[STRI+1]
CALLEXCHSHI;转换为十进制并输出
MOVAH,4CH
INT21H
INPUTPROCNEAR;输入字符串函数
MOVDX,BX
MOVAH,0AH
INT21H
RET
INPUTENDP
HUICHEPROCNEAR;回车换行函数
MOVDL,0DH
MOVAH,02H
INT21H
MOVDL,0AH
MOVAH,02H
INT21H
RET
HUICHEENDP
EXCHASCPROCNEAR;ASC码转换
MOVCX,4
LEADI,BUF
ADDDI,2
S:
CMPBYTEPTR[DI],39H
JNASHUZI
SUBBYTEPTR[DI],37H
JMPNEXT
SHUZI:
ANDBYTEPTR[DI],0FH
NEXT:
INCDI
LOOPS
RET
EXCHASCENDP
YASUOPROCNEAR;将实际大小放进AX
MOVBYTEPTRCL,[BUF+5]
MOVBYTEPTR[STRI],CL
MOVCL,4
MOVDL,[BUF+4]
SHLDL,CL
LEASI,STRI
ADD[SI],DL
MOVBYTEPTRCL,[BUF+3]
MOVBYTEPTR[STRI+1],CL
MOVCL,4
MOVDL,[BUF+2]
SHLDL,CL
ADD[SI+1],DL
RET
YASUOENDP
EXCHSHIPROCNEAR
;转成十进制数输出
MOVBX,10
S1:
MOVDX,0
DIVBX
ORDL,30H
PUSHDX
INCFLAG
CMPAX,0
JNZS1
MOVCL,FLAG
XORCH,CH
OUT1:
POPDX
MOVAH,02H
INT21H
LOOPOUT1
RET
EXCHSHIENDP
CODESENDS
ENDSTART
运行结果:
(上面为输入十六进制数,下面输出对应十进制数)
3、从键盘输入(显示提示)十个2位十进制数(正数)到内存中,按从小到大排序,然后
把该数以十六进制形式在屏幕上打印出来。
程序代码:
DATASSEGMENT
BUFDB40
DB?
DB40DUP(0)
SHUZIDB10DUP(0)
BIAODW0
STRINGDB'PLEASEINPUT10NUMBERS:
$'
DATASENDS
STACKSSEGMENT
STADW20HDUP(0)
STACKSENDS
CODESSEGMENT
ASSUMECS:
CODES,DS:
DATAS,SS:
STACKS
START:
MOVAX,DATAS
MOVDS,AX
MOVAX,STACKS
MOVSS,AX
LEABX,STRING;输出提示
CALLOUTPUTSTR
CALLHUICHE
CALLINPUT;输入10个十进制数
CALLHUICHE
CALLEXCHASC;将ASC码转换
CALLRANK;将其排序
LEASI,BUF
ADDSI,5
MOVDI,10
ABC:
MOVAL,[SI]
CALLPUTABYTE;将16进制数输出
CALLKONGGE
ADDSI,3
DECDI
JNZABC
MOVAH,4CH
INT21H
OUTPUTSTRPROCNEAR;输出字符串
MOVDX,BX
MOVAH,09H
INT21H
RET
OUTPUTSTRENDP
INPUTPROCNEAR;输入字符串函数
LEADX,BUF
MOVAH,0AH
INT21H
RET
INPUTENDP
HUICHEPROCNEAR;回车换行
MOVDL,0DH
MOVAH,02H
INT21H
MOVDL,0AH
MOVAH,02H
INT21H
RET
HUICHEENDP
EXCHASCPROCNEAR;ASC码转换函数
LEASI,BUF
ADDSI,2
MOVCX,10
S:
ANDBYTEPTR[SI],0FH
INCSI
ANDBYTEPTR[SI],0FH
ADDSI,2
LOOPS;变成十进制码
LEASI,BUF
ADDSI,2
MOVBL,10
MOVCX,10
S1:
MOVAL,[SI]
MULBL;变成实际数字
ADDAL,[SI+1]
MOV[SI],AL
ADDSI,3
LOOPS1
RET
EXCHASCENDP
RANKPROCNEAR;排序函数
LEASI,BUF
ADDSI,2
LEADI,BUF
ADDDI,5
MOVCX,10
MOVAL,[SI]
S2:
MOVDI,CX
MOVBX,2
S3:
MOVAL,BUF[BX]
CMPAL,BUF[BX+3]
JBECONTINUE
XCHGAL,BUF[BX+3]
MOVBUF[BX],AL
CONTINUE:
ADDBX,3
LOOPS3
MOVCX,DI
LOOPS2
RET
RANKENDP
PUTABYTEPROCNEAR;显示16进制数字
MOVCL,4
MOVDL,AL
SHRDL,CL
MOVBIAO,AX
CALLEXCHANGEDISP
MOVAX,BIAO
MOVDL,AL
ANDDL,0FH
CALLEXCHANGEDISP
RET
PUTABYTEENDP
EXCHANGEDISPPROCNEAR
CMPDL,9
JANOTDIG
ORDL,30H
JMPFINAL
NOTDIG:
ADDDL,37H
FINAL:
MOVAH,02H
INT21H
RET
EXCHANGEDISPENDP
KONGGEPROCNEAR;输出空格函数
MOVDL,20H
MOVAH,02H
INT21H
RET
KONGGEENDP
CODESENDS
ENDSTART
运行结果:
(上面为输入的10个2位十进制数,下面为排序后的16进制结果)
4、英文人名排序。
从终端键入20个人名,当所有人名都键入后,按字母上升的次序将人名
排序,并在屏幕上显示已经排好序的人名。
程序代码:
DATASSEGMENT
BUFDB200
DB?
DB200DUP(0)
BUF1DB200,'$'
STRINGDB'PLEASEINPUT20NAMES:
$'
STRING1DB'AFTERTHERANK,THENAMES:
$'
DATASENDS
STACKSSEGMENT
DB256DUP(0)
STACKSENDS
CODESSEGMENT
ASSUMECS:
CODES,DS:
DATAS,SS:
STACKS
START:
MOVAX,DATAS
MOVDS,AX
MOVES,AX
LEABX,STRING;输出提示
CALLOUTPUTSTR
CALLHUICHE
CALLINPUTSTR;输入人名
CALLHUICHE
LEABX,STRING1;输出提示
CALLOUTPUTSTR
CALLHUICHE
CALLRANK;排序并输出
CALLMOVE1
LEABX,BUF1
CALLOUTPUTSTR
MOVAH,4CH
INT21H
INPUTSTRPROCNEAR;输入函数
LEADX,BUF
MOVAH,0AH
INT21H
RET
INPUTSTRENDP
HUICHEPROCNEAR;回车换行函数
MOVDL,0DH
MOVAH,02H
INT21H
MOVDL,0AH
MOVAH,02H
INT21H
RET
HUICHEENDP
RANKPROCNEAR;排序函数
MOVCX,19
S1:
PUSHCX
LEASI,BUF
ADDSI,2
MOVDI,SI
ADDDI,5
S2:
PUSHCX
PUSHDI
PUSHSI
MOVCX,4
CLD
REPZCMPSB
POPSI
POPDI
JAADJUST
ADDSI,5
ADDDI,5
JMPNEXT
ADJUST:
MOVCX,4
A1:
MOVAL,[SI]
XCHGAL,[DI]
MOV[SI],AL
INCSI
INCDI
LOOPA1
ADDSI,1
ADDDI,1
NEXT:
POPCX
LOOPS2
POPCX
LOOPS1
RET
RANKENDP
OUTPUTSTRPROCNEAR;输出字符串
MOVDX,BX
MOVAH,09H
INT21H
RET
OUTPUTSTRENDP
MOVE1PROCNEAR;移动复制函数
LEASI,BUF
ADDSI,2
LEADI,BUF1
MOVCL,[BUF+1]
XORCH,CH
MO1:
REPMOVSB
MOVBYTEPTR[DI],'$'
RET
MOVE1ENDP
CODESENDS
ENDSTART
运行结果: