实验报告 子程序设计实验

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

实验5 子程序实验
一.实验目的
1.掌握主程序与子程序之间的调用关系及调用方法;
2.掌握子程序调用过程中近程调用与远程调用的区别;
3.掌握通过堆栈转送参数的方法。

4. 掌握多模块程序设计方法
二.实验内容
1.将BUF开始的10个单元中的二进制数转换成两位十六进制数的ASCII码,在屏幕上显示出来。

要求码型转换通过子程序HEXAC实现,在转换过程中,通过子程序DISP实现显示。

DATAS SEGMENT
BUF DB
00000111B,00100001B,00100010B,00000011B,00000101B,10000010B,10010011B,00100100B, 11100010B,01010010B
CAN DB $-BUF ;定义常量CAN
DATAS ENDS
CODES SEGMENT
ASSUME CS:CODES,DS:DATAS
MAIN PROC FAR ;主程序块
START:
MOV AX,DATAS
MOV DS,AX
MOV CL,10
LEA SI,BUF
LOOP1: ;调用子程序语句
call HEXAC
call DISP
DEC CAN
JNZ LOOP1
EXIT:
MOV AH,4CH
INT 21H
MAIN ENDP
HEXAC PROC NEAR ;二进制转换成十六进制子程序
MOV BL,[SI]
INC SI
RET
HEXAC ENDP
DISP PROC NEAR ;显示子程序
MOV CL,4
MOV CH,2
MOVE: ;移位语句
ROL BL,CL
MOV DL,BL
AND DL,0FH
ADD DL,30H
CMP DL,'9'
JBE PRINT
ADD DL,07H
PRINT:
MOV AH,02H ;显示语句
INT 21H
DEC CH
JNZ MOVE
MOV DL,' '
MOV AH,02H
INT 21H
RET
DISP ENDP
CODES ENDS
END START
2.编写一个主程序,从键盘接收若干个字符,然后用远调用的方法,调用子程序统计字符串中字符’b’的个数.子程序的参数是字符串的首地址TABLE,字符串长度N及字符”b”.子程序返回字符"b”的个数.参数传送采用堆栈实现.主程序在子程序返回后,显示字符”b”及其个数(设为一位十六进制数)。

DATA SEGMENT
STR1 DB 0ah,0dh,'PLEASE INPUT YOUR STRING:$'
STR2 DB 0ah,0dh,'THE NUMBER OF b is:$'
TABLE DB 50, ? ,50 DUP(?),'$'
DATA ENDS
CODE SEGMENT
ASSUME CS: CODE, DS: DATA
START:
MOV AX,DATA
MOV DS,AX
LEA DX,STR1
MOV AH,9
INT 21H
LEA DX,TABLE
MOV AH,0AH
INT 21H
LEA SI , TABLE
MOV CL, [SI+1]
MOV CH, 0
INC SI
INC SI
MOV AL,'b'
MOV AH,0
PUSH SI
PUSH CX
PUSH AX
CALL FAR PTR CHECK
POP AX
MOV CL,AL
LEA DX,STR2
MOV AH,9
INT 21H
MOV DL,CL
AND DL, 0FH
CMP DL,9
JBE CAN
ADD DL,7
CAN:
ADD DL,30H
MOV AH,2
INT 21H
EXIT:
MOV AH,4CH
INT 21H
CODE ENDS
SCODE SEGMENT
ASSUME CS:SCODE CHECK PROC FAR
PUSH BP
MOV BP,SP
MOV SI,[BP+10]
MOV CX, [BP+8]
MOV AX, [BP+6]
XOR AH, AH AGAIN:
CMP AL,[SI]
JNE CAN1
INC AH
CAN1:
INC SI
LOOP AGAIN
MOV AL, AH
MOV [BP+10],AX
POP BP
RET 4
CHECK ENDP
SCODE ENDS
END START
3. 请编写一个程序来实现简单的程序菜单显示。

(采用多模块程序设计方法)
显示一个菜单要求用户从下表中选择:
(1)HEXAC GAME (对应-->程序1)
(2)CHAR STATISTICS PROGRAM(对应-->程序2)
(3)PRESS “ESC”TO QUIT
用户作出选择1~3时,显示输出要执行操作的名字,如“Your selection is 1,the program will execute HEXAC NUMBER GAME!”然后转向相应的程序去执行,执行结束前进行退出的判断,显示一个提示信息“will you continue program really?(Y:N)”要求用户从键盘键入字符,若是“Y”键,则继续程序的执行,若是“N”键,则返回到菜单。

若用户选择3,要求程序显示提示信息“Please press ESC key to exit!”,并能按要求正确退出。

DATAS SEGMENT
OPT DW YI
DW ER
menu DB 0DH,0AH,'THE MENU:' ;显示菜单
DB 0DH,0AH,'(1)HEXAC GAME' ;对应-->程序1
DB 0DH,0AH,'(2)CHAR STATISTICS PROGRAM';对应-->程序2
DB 0DH,0AH,'(3)PRESS "ESC" TO QUIT$'
BUF DB 00000111B,00100001B,00100010B,00000011B,00000101B,10000010B,10010011B,00100100B, 11100010B,01010010B
CAN DB $-BUF ;定义常量CAN
str1 DB 0DH,0AH,'Your selection is 1,the program will execute HEXAC GAME!$'
str2 DB 0dh,0ah,'Your selection is 2,the program will execute CHAR STATISTICS PROGRAM!$'
str3 DB 0DH,0AH,'will you continue program really?(Y:N)$'
str4 DB 0DH,0AH,'Please press ESC key to exit!$'
TABLE DB 50, ? ,50 DUP(?),'$'
char1 db 0ah,0dh,'PLEASE INPUT YOUR STRING:$'
char2 db 0ah,0dh,'THE NUMBER OF b is:$'
DATAS ENDS
CODES SEGMENT
MAIN PROC FAR
ASSUME CS:CODES,DS:DATAS
START:
MOV AX,DATAS
MOV DS,AX
XOR DI,DI
sub bx,bx
xor si,si
LEA DX,menu ;显示主菜单
MOV AH,9
INT 21H
mov dl,0dh ;显示回车
mov ah,2
int 21h
MOV DL,0AH ;显示换行
MOV AH,2
INT 21H
MOV AH,1 ;输入选项
INT 21H
CMP AL,'1'
JE YI
CMP AL,'2'
JE ER
CMP AL,'3'
JE QUIT
YI: MOV DI,0
lea dx,str1
mov ah,9
int 21h
MOV CL,10
LEA SI,BUF
CALL HEXAC
LOOP1: ;调用子程序语句call HEXAC
call DISP
DEC CAN
JNZ LOOP1
JMP CONTINUE
ER: MOV DI,02H
lea dx,str2
mov ah,9
int 21h
LEA DX,char1
MOV AH,9
INT 21H
LEA DX,TABLE
MOV AH,0AH ;输入字符串
INT 21H
LEA SI , TABLE
MOV CL, [SI+1]
MOV CH, 0 ;CX中为字符串长度
INC SI
INC SI ;SI指向串首址TABLE
MOV AL,'b'
MOV AH,0 ;AX中为待查字符
PUSH SI
PUSH CX
PUSH AX ; 参数送堆栈
CALL CHECK
POP AX ;统计个数在AL中
MOV CL,AL
LEA DX,char2 ;显示结果
MOV AH,9
INT 21H
MOV DL,CL
AND DL, 0FH
CMP DL,9
JBE CAN3
ADD DL,7
CAN3:
ADD DL,30H
MOV AH,2
INT 21H ;显示统计个数
JMP CONTINUE
QUIT:
LEA DX,str4 ;退出的子程序
MOV AH,9
INT 21H
MOV AH,1
INT 21H
CMP AL,1BH ;按ESC退出
JE EXIT
CONTINUE:LEA DX,str3 ;用户是否继续执行当前程序
MOV AH,9
INT 21H
MOV AH,1
INT 21H
CMP AL,'Y' ;按y继续,按n退出,不需区分大小写
JE YES
CMP AL,'y'
JE YES
CMP AL,'N'
JE START
CMP AL,'n'
JE START
YES: JMP opt[DI] ;继续运行当前子程序
EXIT:
MOV AH,4CH;退出
INT 21H
MAIN ENDP
CODES ENDS
HEXACCODES SEGMENT
ASSUME CS:HEXACCODES
HEXAC PROC FAR ;二进制转换成十六进制子程序MOV BL,[SI]
INC SI
RET
HEXAC ENDP
HEXACCODES ENDS
DISPCODES SEGMENT
ASSUME CS:DISPCODES
DISP PROC FAR ;显示子程序
MOV CL,4
MOV CH,2
MOVE: ;移位语句
ROL BL,CL
MOV DL,BL
AND DL,0FH
ADD DL,30H
CMP DL,'9'
JBE PRINT
ADD DL,07H
PRINT:
MOV AH,02H ;显示语句
INT 21H
DEC CH
JNZ MOVE
MOV DL,' '
MOV AH,02H
INT 21H
RET
DISP ENDP
DISPCODES ENDS
CHARCODE SEGMENT
ASSUME CS: CHARCODE ;子程序部分CHECK PROC FAR
PUSH BP
MOV BP,SP
MOV SI,[BP+10]
MOV CX, [BP+8]
MOV AX, [BP+6]
XOR AH, AH
AGAIN:
CMP AL,[SI]
JNE CAN1
INC AH
CAN1:
INC SI
LOOP AGAIN
MOV AL, AH
MOV [BP+10],AX
POP BP
RET 4
CHECK ENDP
CHARCODE ENDS
END START
三.实验要求
1.第一个实验程序用子程序的近程调用实现。

由于在调用HEXASC子程序时,子程序又调用了DISP子程序,这叫子程序的嵌套调用。

实验过程中可以从堆栈的内容看到两个子程序的返回地址值。

由于是近调用,地址值只包括返回地址的段内偏移量。

在每个子程序的执行中,检查CS值是不变的。

2.第二个程序是利用远调用的方法调用子程序的。

在远调用情况下,主程序与子程序处在不同的逻辑代码段中,可在子程序执行中查看CS值,它与主程序中的CS值是不同的。

子程序调用后,堆栈中保留了返回地址的段地址及段内偏移量。

3.第二个程序中,主程序与子程序之间参数的传送是由堆栈实现的。

一段是将参数(此处是串首址TABLE,串的长度N及待统计的字符“b”)顺序压如堆栈,在子程序调用后,通过BP指针对堆栈中的参数访问,并将统计的结果通过堆栈返回。

有关该方法的原理此处不再介绍。

4.第三个程序,请采用分文件多模块程序设计方法实现,需注意和实验4中的习题4中采用的地址跳跃表实现方法区分开来,需注意外部符号的定义及其使用方法。

5.预习子程序设计的基本方法,根据实验内容要求,画出子程序及主程序的流程图;熟悉键盘键入字符串及用堆栈传送参数的程序段编制方法。

四.实验环境
PC微机
DOS操作系统或Windows 操作系统
MASM.EXE,LINK.EXE,或宏汇编集成环境
五.实验步骤
1.编辑、汇编三个源程序,生成相应的可执行文件(.EXE)
2.用DEBUG的R命令,T命令或G命令和D命令检查远程调用及近程调用时堆栈的变化。

特别是通过堆栈传送的参数和子程序取出的参数是返回参数的详细过程。

3.检查程序执行的结果是否正确。

六.实验报告要求
1.说明用堆栈传送参数的过程及其具体方法。

2.分析实验结果及所遇到问题,并说明解决的方法。

3、列出各实验题目的程序实现清单,写清楚程序设计思路、各程序模块调用关系及参
数传递方式,源程序中对子程序的入口参数和出口参数及功能应进行适当的注释。

七.思考题
分析远程调用与近程调用的区别,在用DEBUG有关命令观察时,执行过程有何不同。

子程序的远程调用是段间的调用,也就是主程序和子程序不在一个段。

近程的调用是段内的调用。

八、实验小结。

相关文档
最新文档