开 始 源数据块首地址→SI 源数据块首地址→SI 搬移字节数→CX>> SI←[SI]+[CX]-1 DI←[DI]+[CX]-1DI←[(SI)] SI←[SI]-1 DI←[DI]-1CX←[CX]-1N[CX]=0?Y结 束[SI]>[DI]?DI←[(SI)] SI←[SI]+1 DI←[DI]+1CX←[CX]-1[CX]=0?YN
图5.2 程序流程图
实验程序清单(例程文件名为:A4-1.ASM) SSTACK SEGMENT STACK DW 64 DUP(?) SSTACK ENDS
CODE SEGMENT ASSUME CS:CODE START: MOV CX, 0010H MOV SI, 3100H MOV DI, 3200H CMP SI, DI JA A2
ADD SI, CX ADD DI, CX DEC SI DEC DI
A1: MOV AL, [SI] MOV [DI], AL DEC SI DEC DI DEC CX JNE A1
21
JMP A3
A2: MOV AL, [SI] MOV [DI], AL INC SI INC DI DEC CX JNE A2
A3: MOV AX,4C00H
INT 21H ;程序终止 CODE ENDS END START 5.4 实验步骤
1. 按流程图编写实验程序,经编译、链接无误后装入系统。 2. 用E命令在以SI为起始地址的单元中填入16个数。 3. 运行程序,待程序运行停止。
4. 通过D命令查看DI为起始地址的单元中的数据是否与SI单元中数据相同。
5. 通过改变SI、DI的值,观察在三种不同的数据块情况下程序的运行情况,并验证程序的功能。
二、循环程序设计实验 5.5 实验目的
1. 加深对循环结构的理解。
2. 掌握循环结构程序设计的方法以及调试方法。 5.6 实验设备
PC机一台,TD-PITE实验装置或TD-PITC实验装置一套。 5.7 实验内容及步骤
1. 计算S=1+2×3+3×4+4×5+?+N(N+1),直到N(N+1)项大于200为止。 编写实验程序,计算上式的结果,参考流程图如图5.3所示。
开始实验程序清单(例程文件名为:A5-1.ASM) SSTACK SEGMENT STACK
1→DX DW 64 DUP(?)
2→BLSSTACK ENDS
CODE SEGMENT
[BL]→AL ASSUME CS:CODE
[BL]+1→BLSTART: MOV DX,0001H MOV BL,02H
[AL]×[BL]→AXA1: MOV AL,BL [DX]+[AX]→DX INC BL MUL BL
[AX]>200? ADD DX,AX ;结果存于DX中
CMP AX,00C8H ;判断N(N+1)与200的大小 JNA A1
结束 MOV AX,4C00H
INT 21H ;程序终止 图5.3 程序流程图
22
CODE ENDS END START 实验步骤
(1)编写实验程序,编译、链接无误后装入系统。 (2)运行程序,待程序运行停止。
(3)运算结果存储在寄存器DX中,查看结果是否正确。
(4)可以改变N(N+1)的条件来验证程序功能是否正确,但要注意,结果若大于0FFFFH将产生数据溢出。
2. 求某数据区内负数的个数
设数据区的第一单元存放区内单元数据的个数,从第二单元开始存放数据,在区内最后一个单元存放结果。为统计数据区内负数的个数,需要逐个判断区内的每一个数据,然后将所有数据中凡是符号位为1的数据的个数累加起来,即得到区内所包含负数的个数。 实验程序流程图如图5.4所示。
实验程序清单(例程文件名为:A5-2.ASM)
开 始SSTACK SEGMENT STACK DW 64 DUP(?)
数据区首地址→DISSTACK ENDS
CODE SEGMENT
ASSUME CS:CODE 数据个数→CLSTART: MOV DI, 3000H ;数据区首地
MOV CL, [DI] ;取数据个数
CH、BL置0XOR CH, CH
MOV BL, CH
DI增1 INC DI ;指向第一个数据
A1: MOV AL, [DI]
N TEST AL, 80H ;检查数据首位是否为1
数据首位=1? JE A2
Y INC BL ;负数个数加1
BL+1→BLA2: INC DI
LOOP A1
MOV [DI], BL ;保存结果 DI增1MOV AX,4C00H
INT 21H ;程序终止 NCX=0?CODE ENDS
END START Y实验步骤:
存结果(1)按实验流程编写实验程序。 (2)编译、链接无误后装入系统。
结 束(3)键入E3000,输入数据如下:
3000=06 (数据个数),3001=12
3002=88, 3003=82 图5.4 程序流程图 3004=90, 3005=22 3006=33
23
(4)先运行程序,待程序运行停止。
(5)查看3007内存单元或寄存器BL中的内容,结果应为03。 (6)可以进行反复测试来验证程序的正确性。
三、子程序设计实验 5.8 实验目的
1. 学习子程序的定义和调用方法。
2. 掌握子程序、子程序的嵌套、递归子程序的结构。 3. 掌握子程序的程序设计及调试方法。 5.9 实验设备 PC机一台,TD-PITE实验装置或TD-PITC实验装置一套。
开 始5.10 实验内容及步骤
1. 求无符号字节序列中的最大值和最小值
数据区首地址→SI设有一字节序列,其存储首地址为3000H,字节 数为08H。利用子程序的方法编程求出该序列中的最
序列字节个数→CX大值和最小值。程序流程图如图5.5 所示。 实验程序清单(例程文件名为:A7-1.ASM)
调用子程序SSTACK SEGMENT STACK DW 64 DUP(?)
结 束SSTACK ENDS
CODE SEGMENT
子程序开始ASSUME CS:CODE
START: MOV AX, 0000H YCX=0?MOV DS, AX
N MOV SI, 3000H; 数据区首址
SI,CX,BX入栈 MOV CX, 0008H
CALL BRANCH ; 调用子程序
(SI)→BHHERE: JMP HERE BH→BLBRANCH PROC NEAR
; 子程序,返回参数在AX中 (SI)+1→SI(SI)→AL JCXZ A4
PUSH SI
N(AL)<(BH)AL→BH PUSH CX
YPUSH BX
N(AL)>(BH)AL→BLMOV BH, [SI]
MOV BL, BH Y CLD (CX)-1→CXA1: LODSB
N CMP AL, BH CX=0?JBE A2 YMOV BH, AL
子程序返回 JMP A3
A2: CMP AL, BL 图5.5 程序流程图
JAE A3
24
MOV BL, AL A3: LOOP A1 MOV AX, BX POP BX
POP CX POP SI
A4: RET BRANCH ENDP CODE ENDS
END START
实验步骤
(1)根据程序流程图编写实验程序。 (2)经编译、链接无误后装入系统。
(3)键入E3000命令,输入8个字节的数据,如:D9 07 8B C5 EB 04 9D F9。 (4)运行实验程序。
(5)点击停止按钮,停止程序运行,观察寄存器窗口中AX的值,AX应为F9 04,其中AH中为最大值,AL中为最小值。
(6)反复测试几组数据,检验程序的正确性。
程序说明:该程序使用BH和BL暂存现行的最大值和最小值,开始时初始化成首字节的内容,然后进入循环操作,从字节序列中逐个取出一个字节的内容与BH和BL相比较,若取出的字节内容比BH的内容大或比BL的内容小,则修改之。当循环操作结束时,将BH送AH,将BL送AL,作为返回值,同时恢复BX原先的内容。
2. 求N!
利用子程序的嵌套和子程序的递归调用,实现N!的运算。根据阶乘运算法则,可以得: N!=N(N-1)!=N(N-1)(N-2)!=?? 0!=1
由此可知,欲求N的阶乘,可以用一递归子程序来实现,每次递归调用时应将调用参数减1,即求(N-1)的阶乘,并且当调用参数为0时应停止递归调用,且有0!=1,最后将每次调用的参数相乘得到最后结果。因每次递归调用时参数都送入堆栈,当N为0而程序开始返回时,应按嵌套的方式逐层取出相应的调用参数。
定义两个变量N及RESULT,RESULT中存放N!的计算结果,N在00H~08H之间取值。 实验程序清单(例程文件名为:A7-2.ASM) SSTACK SEGMENT STACK DW 64 DUP(?) SSTACK ENDS
PUBLIC N, RESULT ;设置全局变量 DATA SEGMENT
N DB ? ;N的范围在1~8之间 RESULT DW ? ;N!的结果存于该变量中 DATA ENDS CODE SEGMENT
ASSUME CS:CODE, DS:DATA
25