实验六 子程序设计实验
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
实验六子程序设计实验
一、实验目的
1.掌握过程调用指令与过程返回指令的用法;
2.掌握主程序与子程序之间的参数传送方法;
3.掌握调用子程序时堆栈的变化情况及利用压栈、出栈保护现场的方法;
4.掌握嵌套及递归子程序的设计方法。
二、实验要求
1.仔细阅读教材中有关子程序设计的章节;
2.学会编写子程序说明文件;
3.学会设置断点检查堆栈指针的变化及堆栈内容;
4.学会用DEBUG中的P命令调试子程序;
5.学会在子程序设计中保护所用到的寄存器。
三、实验举例
【例3.6】编写一个计算绝对值的子程序。利用该子程序计算S=|a|+|b|+|c|的值(a、b、c为带符号数),计算结果存入指定的内存单元。
【解题思路】
本题采用子程序设计方法,求一个数的绝对值。正数的绝对值是它本身,负数的绝对值,需对这个数进行取补操作。求得一个数的绝对值后,采用循环的方法将它们逐个累加,得到三个数绝对值的和。
【步骤一】启动EDIT编辑器,编辑主程序和子程序。
主程序清单:
DSEG SEGMENT
DATA DW -3425H,1236H,-3454H
ABSM DW 0
DSEG ENDS
CSEG SEGMENT
ASSUME CS:CSEG,DS:DSEG
START: MOV AX,DSEG
MOV DS,AX
LEA SI,DATA
MOV CX,3
XOR BX,BX
AGAIN: MOV AX,[SI]
CALL ABSX
ADD BX,AX
INC SI
INC SI
LOOP AGAIN
MOV ABSM,BX
MOV AH,4CH
INT 21H
CSEG ENDS
END START
ABSX子程序说明文件:
⑴ 子程序名:ABSX
⑵ 子程序功能:求带符号整数的绝对值
⑶ 入口条件:带符号整数放在AX中
⑷ 出口条件:绝对值放在AX中
⑸ 受影响的寄存器:AX和标志寄存器F
子程序清单:
ABSX PROC NEAR
AND AX,AX
JNS L1
NEG AX
L1: RET
ABSX ENDP
在输入程序时,将子程序放到主程序的代码段中即可。主程序和子程序输入完成后,以EXAM6.ASM为文件名存入磁盘,进行下一步操作
【步骤二】启动宏汇编程序MASM,对汇编语言源程序EXAM6.ASM进行汇编,生成目标程序EXAM6.OBJ。操作如下:
C:>\MASM EXAM6;↙
屏幕显示如下信息:
Microsoft (R) Macro Assembler Version 5.00
Copyright (C) Microsoft Corp 1981-1985, 1987. All rights reserved.
50466 + 450014 Bytes symbol space free
0 Warning Errors
0 Severe Errors
对源程序进行汇编通过,没有产生错误信息,可以进行下一步操作。
【步骤三】对目标程序EXAM6.OBJ进行连接,生成可执行程序EXAM5.EXE。
操作如下:
C:>\LINK EXAM6;↙
屏幕显示如下信息:
Microsoft (R) Segmented-Executable Linker Version 5.13
Copyright (C) Microsoft Corp 1984-1991. All rights reserved.
LINK: warning L4021: no stack segment
连接过程产生错误信息:no stack segment
此错误信息是说源程序没有设置堆栈段,该错误不影响程序的执行,可以忽略,进行下一步操作。
【步骤四】启动DEBUG应用程序,在DEBUG下用G命令执行EXAM6.EXE文件,并用D命令观察程序的已知数据和执行结果。
操作如下:
C:>\DEBUG EXAM6.EXE↙ ;启动DEBUG,并将EXAM6.EXE载入DEBUG环境
-U 0↙ ;对EXAM6.EXE进行反汇编,以便确定程序的起始地址和结束地址
0B9C:0000 B89B0B MOV AX,0B9B
0B9C:0003 8ED8 MOV DS,AX
0B9C:0005 8D360000 LEA SI,[0000]
0B9C:0009 B90300
MOV CX,0003 0B9C:000C 33DB
XOR BX,BX 0B9C:000E 8B04
MOV AX,[SI] 0B9C:0010 E80E00 CALL 0021 0B9C:0013 03D8
ADD BX,AX 0B9C:0015 46
INC SI 0B9C:0016 46
INC SI 0B9C:0017 E2F5
LOOP 000E 0B9C:0019 891E0600
MOV [0006],BX 0B9C:001D B44C
MOV AH,4C 0B9C:001F CD21 INT 21 -G=0 1F↙ ;执行程序,从0单元开始到1F单元结束
AX=4C45 BX=7AAF CX=0000 DX=0000 SP=0000 BP=0004 SI=0006 DI=0000
DS=0B9B ES=0B8B SS=0B9B CS=0B9C IP=001F NV UP EI PL NZ NA PE NC
0B9C:001F CD21 INT 21 - D 0 F↙ ;显示已知数据和结果数据
0B9B:0000 DB CB 36 12 AC CB AF 7A-00 00 00 00 00 00 00 00 ..6....z........
-
至此,程序执行完毕,计算出三个数的绝对值为7AAF。
四、实验内容
1.采用一般子程序设计方法和递归子程序设计方法,编写计算X n 的子程序。要求:X 值与n 值由键盘输入,计算结果以十六进制形式在屏幕上显示。
2.用递归子程序设计方法,编写计算N !(0≤N ≤8)的子程序。要求:N 值由键盘输入,N !值以十六进制形式在屏幕上显示。
3.编写程序,完成一位十六进制数的加、减、乘、除运算。
要求:从键盘输入参加运算的一位十六进制数,运算结果以十六进制形式在屏幕上显示,加、减、乘、除运算要用子程序编写。
4.编制程序,计算3~255之间的所有素数之和,并将3~255之间的所有素数存放在由DATA 开始的连续内存单元中,所有素数之和存放在SUM 单元中。要求:判断一个数是否为素数用子程序编写。
5.利用递归方法计算Fibnacci 级数的第N 项,设0≤N≤20。已知:
{
N (N≤1时)
F(N)=
F(N-1) + F(N-2) (N>1时)
利用该子程序产生数值在100~500之间的Fibnacci 级数项,并存入RUL 开始在存储单元。
6. 编制递归子程序,解HANOI 谜题。在该谜题中,有A、B、C 三个轴,在A 轴上自上而下地叠放由小到大的N 个盘子,顺序编号为1,2,…,N,现欲将它们从A 轴移到C 轴上,并保持原来的次序,移动时允许将盘子暂时存放在B 轴上,移动盘子必需遵循以下两条规则:
⑴ 每次从一个轴上移动最上面的一个盘子到另一个轴上;
⑵ 在任何时候都不能将一个盘子放在比它小的盘子上面;
⑶ 盘子只能在A、B、C 三个轴上放置。
要求:从键盘输入盘子个数N,并将搬动盘子的过程在屏幕上显示出来,每次搬动的显示格式为:源轴名,盘子号,目标轴名。