东华大学微机原理实验指导书2015

更新时间:2024-06-08 12:51:01 阅读量: 综合文库 文档下载

说明:文章内容仅供预览,部分内容可能不全。下载后的文档,内容与下面显示的完全一致。下载之前请确认下面内容是否您想要的,是否完整无缺。

微机系统及应用实验指导书

东华大学信息科学与技术学院自动化系

2015年9月

1

实验一 基本程序编程和程序调试

一、 实验目的

1、 掌握数码转换等基本程序设计的技巧和方法。 2、 熟悉DEBUG命令。

3、 学会和掌握用DEBUG调试程序的方法。

二、 实验设备

PC机一台,装有DOS基本系统

三、 实验内容及步骤

用DEBUG建立、汇编和运行调试程序的操作。DEBUG是DOS系统支持的用于汇编语言源程序调试的系统软件。它共有19条命令完成相应的功能,命令及其格式可参阅附录一。

(一) DEBUG操作练习

1)实验调试程序

程序的功能是从3500H内存单元开始建立0-15共16个数据。程序如下: 地址 (H) 机器码(H) 助记符 2000 BF0035 MOV DI, 3500 2003 B91000 MOV CX, 0010 2006 B80000 MOV AX, 0000 2009 9E SAHF 200A 8805 MOV BYTE[DI],AL 200C 47 INC DI 200D 40 INC AX 200E 27 DAA 200F E2F9 LOOP 200A 2011 F4 HLT

2)实验步骤: (1)输入与修改

① 启动DOS,在DOS提示符下输入D E B U G后回车,屏幕立即显示DEBUG提示符“—”,表明已进入DEBUG状态,可以执行DEBUG的各种命令。

② 用DEBUG中的汇编命令 “A 地址”将程序建立在内存单元中。 在提示符“—”下键入 : “A 2000 ?” 此时显示器上将会显示程序的段地址CS和偏移地址IP,你就可以输入以上的程序了。即

2

显示 169C :2000 键入 MOV DI, 3500

169C: 2003 MOV CX, 0010

169C: 2011 HLT

: : :

③ 用反汇编命令 “U 地址”检查程序

在提示符“—”下,键入 “U 2000?”,将从2000内存单元开始的内容反汇编,屏幕上显示 169C:2000 BF0035 MOV DI, 3500 169C:2003 B91000 MOV CX, 0010 169C:2006 B8000 MOV AX, 0000 : : : : : : 169C:2011 F4 HLT

当发现程序有错时,可用汇编命令“A 地址”进行修改,如要修改200A单元中的指令, 则键入 “A 200A?” ,屏幕显示 169C:200A ,然后再键入MOV BYTE[DI], AL?,就把错误的程序改正了。

(2)显示和修改数据

①用修改内存单元命令 “E 地址” 在指定内存单元中存入一个数。

如要在3500为首址的单元中存入14H和25H两个数据,可在提示符“—”下,键入:“E 3500?” 显示 169C:3500 ××. 键入14,按空格键 ××. 25,按空格键

②用显示内存命令 “D 地址” 检查指定单元的内容 在提示符“—”下,键入 “D3500?”

显示 1489:3500 14 25 48 02 ???? 1489:3510 ** ** ** ** ???? : : : :

1489:3570 ** ** ** ** ????

若某单元内容有错则可用命令: “E 地址 ”进行修正。

③用显示和修改命令 “R ”或“R 寄存器名”显示寄存器或修改其内容 在提示符“—”下,键入 “R?”

显示 AX=0000 BX=0000 CX=0000 DX=0000 SP=FFEE???????? DS=169C ES=169C SS=169C CS=169C IP=2000????????? 要修改IP的内容时,键入命令 “R IP”后, 显示 IP 2000,在2000之后键入新内容。

3

(3)程序运行

程序的运行方式有单步运行、断点运行和连续运行几种方式。

①单步运行

输入DEBUG跟踪命令“T”或“T=地址”或“T=地址 指定次数”,可从指定地址处运行该单元中的一条指令,以后只要连续输入“T”命令就能连续执行一条一条指令。 如在提示符“—”下,键入 “T=2000 ?” 显示 :

AX=0000 BX=0000 CX=001D DX-0000 SP=FFEE BP=0000 SI=0000 DI=0000 DS=169C ES=169C SS=169C CS=169C IP=2000 NV??? 169C:2003 B91000 MOV CX, 0010

②断点运行

用运行命令 “G=地址 地址断点 地址断点?”执行指定地址的程序 在提示符“—”下,键入 “G=2000 2011 ?”

显示 169C:2011 F4 HLT 表示这段程序已经执行完毕。

③连续运行

输入DEBUG命令“G=地址”,执行指定地址的程序 (WIN系统下,不建议使用此方式) (4)用显示内存命令检查运行结果

在提示符“—”下,键入命令 “D 地址?”,根据其中的内容判断程序运行是否正确。

如检查以上程序执行后的结果,在提示符“—”下,键入“ D 3500?”,可显示 169C:3500 00 01 02 03 04 ?? 15 169C:3510

(二)数码转换程序及其调试

1、 将ASCII码表示的十进制数转换为二进制数

1)程序设计的算法及其程序 十进制数据可表示为:

Dn????Dn?????nn?????D??????Di???i?i??n(?)DI代表十进制数1,2,3,?9,0 上式可转换为:

iD????((?(Dn????Dn??)???)?Dn??)??????D?)????D??ii??n(?) 由式(2)可归纳十进制数转换为二进制数的方法:从十进制的最高位Dn开始乘10加次位的操作,将结果再乘10再加下一次位,如此重复,则可求出二进制数结果来。程序流程及参考程序如图1-1。这里我们规定:被转换的ASCII码十进制数存放在3500H——3504H单位中。而转换结果存放

4

在3510H——3511H单元中。 2)实验步骤

(1)输入程序并检查无误。 (2)在3500H——3504H单元存入十进制数12的ASCII码,即E3500H↙,并输入30 30 30 31 32H。 (3)G=2000 201E↙,运行程序

(4)用D3510↙来查看结果,应为:3510 0C 00 (5)反复试几组数,考查程序的正确性。

地址(H) 助记符 注释 2000 MOV SI,3500 ;源地址 2003 MOV DI,3510 ;结果地址 2006 MOV BX,000A ;乘数 10 2009 MOV CX,0004 ;计数 200C MOV AH,00 ;AH 清零 200E MOV AL,[SI] ;取被转换数

2010 SUB AL,30 ;ASCII码变十进制数 2012 IMUL BX ;高位(AX)*(BX)送AX 2014 ADD AL,[SI+01] ;取下一位

1017 SUB AL,30 ;ASCII码减30变十进制数 2019 INC SI ;源地址指针+1

201A LOOP 2012 ;CX-1,若CX不等于零则继续 201C MOV [DI],AX ;若CX不等于零则存结果 201E INT 3

图1-1

2 将十进制数的ASCII码转换为BCD码

1)程序流程和程序

设从键盘输入的五位十进制数的ASCII码已存放在3500H起始的内存单元内,把它转换成BCD码后,再按位分别存入350AH起始的内存单元内。若输入的不是十进制数的ASCII码,则对应存放结果的内容为“FF”。一字节ASCII码取其低四位即变为BCD码,程序流程图及考程序如图1-2所示。

2)实验步骤

(1) 输入程序并检查无误。

(2) 在3500H——3504H单元中存入五位十进制数的ASCII码,即 E3500↙,并输入31,32,33,34,35。 (3) G=2000 201C↙,运行以上程序。 (4) D350A↙,显示结果为:

0000:350A 01 02 03 04 05 CC? (5) 反复试几组数,考查程序的正确性。

5

地址(H) 助记符 注释

2000 MOV CX,0005;循环计数器赋初值 2003 MOV DI,3500;ASCII码首址 2006 MOV BL,FF; 错误标志送BL 2008 MOV AL,[DI];送ASCII码至AL 200A CMP AL,3A; 比较AL与3AH

200C JNB 2014; 不低于3A则转2014

200E SUB AL,30; 低于3A则取ASCII码的低四位 2010 JB 2014; 低于30则转2014

2012 MOV BL,AL; 否则AL内容送BL,取代FF 2014 MOV AL,BL; 结果或错误标志送AL 2016 MOV [DI+0A],AL 2019 INC DI 201A LOOP 2006 201C INT 3

3 将十六位二进制数转换为ASCII码表示的十进制数

1)程序及其流程

十六位二进制数的值域为0——65535,最大可转换为五位十进制数。 算法:五位十进制数可表示为:

ND?D??????D??????D??????D?????D?

Di:表示十进制数0——9。

因此,将十六位二进制数转换为五位ASCII码表示表示的十进制数,就是求D1——D4,并将它化为ASCII码。程序流程图如图1-3所示,设源数据存于3500——3501H单元中,结果数存于3510——3514H单元中。

2)实验步骤

(1) 输入程序并检查无误。

(2) 在3500——3501H单元中存放0C00,运行程序并检查结果,应看到3510——3514H单元中

的数依次为30 30 30 31 32。

(3) 反复试几组数,并运行程序、观察结果。

地址(H) 助记符 注释

2000 MOV DX,[3500];取二进制数

6

2004 MOV SI,3515; 目标首址在3510 2007 DEC SI 2008 MOV AX,DX 200A MOV DX,0000 200D MOV CX,000A

2010 DIV CX; ; 除10 2012 XCHG AX,DX 2014 ADD AL,30 2016 MOV [SI],AL 2018 CMP DX,0000 201B JNE 2007

201D CMP SI,3510 ; 填余下高位为0 2021 JZ 202A; 2023 DEC SI 2024 MOV AL,30 2026 MOV [SI],AL 2028 JMP 201D 202A INT 3

图1-3

4、 十六进制数转换为ASCII码

1) 程序及其流程

经过CPU处理后的十六进制数存放在起始地址为3500H的内存单元中,把它们转换成ASCII码之后,再分别存入起始地址为350AH的内存单元中。

从表2-1中可知,十六进制数加30H即可得到0H——9H的ASCII码,而要得到AH——FH的ASCII码,则需再加7H。程序流程图及参考程序如图1-4所示。

2)实验步骤 (1) 输入程序并检查无误。 (2) 在3500——3501H单元中存入四位十六进制数203B,即 E3500↙,并输入3B,20。 (3) G=2000 2021↙,运行以上程序 (4) D350A↙,显示结果为:

0000:350A 42 33 30 32 CC? 输入数据与结果ASCII码对应顺序相反。 (5) 反复试几组数。考查程序的正确性。

地址(H) 助记符 注释 2000 MOV CX,0004

7

2003 MOV DI,3500 2006 MOV DX,[DI] 2008 MOV AX,DX

200A AND AX,000F ;取低四位值

200D CMP AL,0A; ; 判是否“0”-“9” 200F JB 2013 ; 是“0”-“9”转2013 2011 ADD AL,07; 是“A”-“F”,加7 2013 ADD AL,30; 转换为ASCII码 2015 MOV [DI+0A],AL 2018 INC DI

2019 PUSH CX ;保护循环计数器内容 201A MOV CL,04; 移位次数送CL 201C SHR DX,CL 201E POP CX 201F LOOP 2008 2021 INT 3

图1-4

4 BCD码转换为二进制数

1) 程序及其流程

设四个二位十进制数的BCD码存放在起始地址为3500H, 的单元中,转换出的二进制数码存入起始地址为3510H的内存 单元中,程序流程图及参考程序如图1-5所示。

地址(H) 助记符 注释 2000 MOV CX,0004 2003 MOV DI,3500 2006 MOV AL,[DI]

2008 ADD AL,AL ;乘2 200A MOV BL,AL

200C ADD AL,AL ;乘2 200E ADD AL,AL ;乘2 2010 ADD AL,BL ;乘10 2012 INC DI 2013 MOV AH,00

2015 ADD AL,[DI]; BCD码十位与个位加

2017 MOV [DI+0F],AX;存结果 图1-5 201A INC DI 201B LOOP 2006

8

201D INT 3

2)实验步骤

(1) 输入程序并检查无误。

(2) 在3500——3507单元中存入四个十进制数(12,34,56,78)的BCD码,即E3500↙ 输

入01,02,03,04,05,06,07,08。

(3) G=2000 201D↙,运行以上程序。

(4) D3510↙,显示结果为3510 0C 00 22 00 38 00 4E 00 (5) 反复试几组数,考查程序的正确性。

四、思考题

1、 图1-1程序,将一个五位十进制数转换为二进制数(十六位)时,这个十进制数最小可为多少,

最大又可为多少?为什么?

2、 将一个十六位二进制数转换为ASCII码十进制数时,如何确定D1的值?

3、 在十六进制数转换为ASCII码时,存转换结果后,为什么要把DX向右移四次?

4、 自编ASCII码→十六进制、十进制小数→二进制、二进制→BCD码的程序,并调试运行。

9

实验二 程序设计和PC机上程序调试操作实验

一、 实验目的

1.掌握常用程序设计的基本技巧和方法。

2.学会和熟悉使用MASM汇编程序和LINK连接程序。 3.掌握使用PC机上编程和调试程序的方法。

二、 实验设备

PC机一台,装有DOS基本系统和MASM宏汇编软件

三、 实验内容及步骤

(一)按要求编写程序并在DEBUG下建立、汇编和调试程序

1、

四字节二进制数的加法

1)程序设计要求

两个字的被加数存放于3500H-3503H单元, 加数存于3504H-3507H单元 (存放格式为高位存高地址单元,低位存低地址单元),两数之和(如不超过四字节)存放于3508H-350BH单元。 2)实验步骤

(1)编写程序。

(2)在DEBUG下输入程序并检查(程序可存放于2000H-8000H单元)。 (3)在3500H-3507H单元中存入被加数014527和加数146758。 (4)运行程序后,检查3508H-350BH单元中内容。

(5)反复选择几组被加数和加数,检查结果,验证程序正确性。

2、数据块的搬移

1)程序设计思想和要求

将内存中一数据区中数据(源数据块)传送到另一数据区(目的数据块)。

源数据块和目的数据块区在内存中的位置有两种情况:两区重叠和不重叠,如下图所示。 对于两个数据块不重叠的情况,数据的传送可从数据块的首址开始,也可从数据块的末址开始;对于两个数据块重叠的情况,则要加以分析,否则重叠部分会因搬移而遭破坏。处理方法可以是:在源数据块首址>目的数据块首址时,从数据块的首址开始传送,在数据块首址<目的数据块首址时,从数据块的末址开始传送。

若源数据块首址存放于SI 中,目的数据块首址存放于DI 中,块字节数存放于CX中。要求设计的程序能够实现不同情况下的数据块传送。

10

源数 据块

目的数 据块

源 数 据 块 数 据 块

目的

2)实验步骤

(1)编写程序。

(2)在DEBUG下键入程序并检查(程序可存放于2000H-8000H单元)。

(3)确定源数据块和目的数据块区不重叠时的首址,确定数据块个数为16个。并在源数据区送入任意16个数据。

(4)运行程序后,检查目的数据区的内容。

(5)确定源数据块和目的数据块区重叠时, 源区首址>目的区首址时的首址, 以及数据块个数为16个,并在源数据区送入任意16个数据。运行程序后,检查目的数据区的内容。

(6)确定源数据块和目的数据块区重叠时, 源区首址<目的区首址时的首址, 以及数据块个数为16个,并在源数据区送入任意16个数据。运行程序后,检查目的数据区的内容。

3、无序数据块的递增排序

1)程序设计思想和要求

在首址为3000H 的数据区中存放着一组无符号数, 数据的长度存于3500H单元内,要求用冒泡法对该区中的数据按递增次序排列。

冒泡法的基本思想是从最后一个数(或从第一个数)开始,依次把相邻两个数比较,即第N个数与第N-1个数比较?,若大则交换,否则不交换,直到N个数都比较完为止。此时,其中最小数排在最前列。然后将剩下的N-1个数再按前述方法进行,找到N-1个数中最小的数。以后重复进行,直到全部按序排列。 2)实验步骤

(1)编写程序。

(2)在DEBUG下键入程序并检查(程序可存放于2000H-8000H单元,只要不与数据区重叠即可)。

(3)确定数据个数并输入3500H单元中,在首址为3500H的数据区中存入任意无符号数。 (4)运行程序并检查运行结果。

(6)反复修改数据个数和数据区中的数,运行程序、观察结果,验证程序的正确性。

4、求数的平方根

11

1)程序设计思想和要求

减奇数法是一种求取近似平方根和平方根的整数部分的方法。有公式:

n

2

?(2K-1)=N

k=1

若要求数S的平方根?S, 则可以从S中减去奇数1、3、5?直到减为零或不够减下一个奇数为止,然后统计减去的奇数个数,它就是S的近似平方根。

被开方数为一个足够大的二进制数, 存于首址为4000H的单元内,它的方根存放在以4500H为首的单元内。

2)实验步骤

(1)编写程序。

(2)在DEBUG下输入程序并检查(程序可存放于2000H-8000H单元,和数据存放单元不要重叠)。

(3)在4000H为首的单元中存入一个任意大的数。 (4)运行程序并检查运行结果。

(6)反复修改被开方数,运行程序、观察结果,验证程序的正确性。

5、思考题

① 如果二进制加数和被加数不限于四字节而为任意字节时,程序应作如何改动? ② 修改原有的无符号数的排序程序为带符号数的排序程序。

③ 被开方数是一压缩型的BCD码十进制数时,程序应作如何修改?

(二)MASM汇编程序和LINK连接程序的使用操作

在DEBUG中,使用A命令建立程序,一般不能使用标号和伪指令,并不能保存汇编语言源程序,适用于简单程序。MASM宏汇编程序可以将编辑程序建立的源程序文件进行汇编,汇编后在盘上建立目标文件、列表文件和交叉参考文件。而目标文件经LINK程序连接以后成为可执行的文件,它可以在DOS下执行也可在DEBUG下调试。

1、计算机钢琴程序

1)实验内容

根据乐曲中不同的音符是由输出不同频率的声波而产生的原理,通过设置PC机中 8253定时器不同的计数值,可由扬声器发出不同的曲调。 以下是实现PC机作为一架可弹奏的钢琴演奏预定的曲调。程序中采用了INT 21H软中断调用了DOS的常用子程序。 源程序为:

DATA SEGMENT

12

MESS DB ‘Push any key to stop!’,0dH,0aH,’$’ TABLE DW 524,588,660,698,784,880,988,1048,1176,1320,0

TABLEL DB 31H,31H,32H,31H,34H,33H,3BH DB 31H,31H,32H,31H,35H,34H,3BH DB 31H,31H,38H,36H,34H,33H,32H,3BH DB 36H,36H,36H,34H,35H,34H,3BH,0AAH DATA ENDS

STACK SEGMENT PARA STACK ‘STACK’ STA DB 256 DUP(?) STACK ENDS CODE SEGMENT

ASSUME CS: CODE, DS: DATA, SS: STACK, ES: DATA

START PROC FAR DIV WORD PTR [TABLE+BX] PUSH DS MOV BX, AX XOR AX, AX MOV AL, 10110110B PUSH AX OUT 43H, AL MOV AX, DATA MOV AX, BX MOV DS, AX OUT 42H, AL MOV ES, AX MOV AL, AH MOV AH, 09H OUT 42H, AL LEA DX, MESS IN AL, 61H INT 21H OR AL, 03H KK: LEA SI, TABLEL OUT 61H, AL CALL DELAY IN AL, 61H AND AL, 0FCH OUT 61H, AL QQ: INC SI SING: MOV AH, 06H JMP SING MOV DL, 0FFH FINISH: RET

INT 21H START ENDP JNE FINISH

MOV AL, [SI] DELAY PROC NEAR ; 延时子程序 CMP AL, 3BH PUSH CX JNE DDD PUSH AX

CALL DELAY MOV AX, 500H ; 大循环次数 JMP QQ X1: MOV CX, 0FFFFH ; 小循环次数 DDD: CMP AL, 0AAH X2: DEC CX JE KK JNZ X2 SUB AL, 31H DEC AX SHL AL, 01H JNZ X1

13

MOV BL, AL POP AX MOV AX, 0000H POP CX MOV DX, 12H RET

MOV BH, 00H DELAY ENDP CODE ENDS END START

2)实验步骤 (1)利用EDIT 全屏幕编辑程序或TURBO PASCAL中的编辑功能或任何一款文本编辑程序输入以上程序,以文件名为 PLAYPIA..ASM存盘。 (2)在DOS系统下执行子目录MASM中的执行文件MASM.EXE ,用宏汇编程序将PLAYPIA.ASM.汇编成目标文件PLAYPIA.OBJ。操作过程如下:

显示 键入

C:\\MASM> MASM ? MICROSOFT(R) ???? COPYRIGHT(C)?????

SOURCE FILENAME [.ASM] PLAYPIA ? OBJECT FILENAME [PLAYPIA.OBJ] SOURCE LISTING[NUL.LST] PLAYPIA ?

CROSS-REFERENCE[NUL.CRF]

WARNIING ERRORS 0 SEVERE ERRORS 0

如ERRORS 均为0 表示汇编正确,如不为0,则必须在编辑状态下重新修改源程序。

(3)运行子目录DOS下LINK执行文件将目标文件PLAYPIA.OBJ连接成为可执行的文件PLAYPIA.EXE。操作如下:

显示 键入

C:\\ LINK ? MICROSOFT(R)?????????? COPYRIGHT(C)??????????

OBJECT MODULES[.OBJ]: PLAYPIA ? RUN FILE[PLAYPIA.EXE] ?

14

LIST FILE[NUL.MAP] PLAYPIA ? LIBRARIES[.LIB] ?

C:\\

(4)在DOS下直接键入由MASM宏汇编和LINK连接程序生成的可执行文件文件名PLAYPIA,运行程序观察运行结果。

(6) 修改程序中延时子程序的循环次数,重新汇编、连接后运行。

2、求数据块的最小值和最大值

1)实验内容

在以BUFFER为首址的内存中存放了若干个带符号数, 其个数存放在首单元,寻找出它们最大值放到存储单元MAXVAL中, 最小值放到存储单元MINVAL中。汇编语言源程序如下: DATA SEGMENT

BUFFER DB 10,22,33,-80,127,-76,0,90,-45,60,-1 MINVAL DB ? MAXVAL DB ?

DATA ENDS

STACK SEGMENT PARA STACK ‘STACK’ STA DB 100 DUP(?) STACK ENDS

CODE SEGMENT

ASSUME CS:CODE, DS:DATA, ES:DATA, SS:STACK START PROC FAR PUBH DS MOV AX, 0 PUSH AX

MOV AX, DATA MOV DS, AX MOV ES, AX

LEA BX, BUFFER MOV CH, 0 MOV CL, [BX] INC BX

MOV AL, [BX] MOV MINVAL, AL MOV MAXVAL, AL INC BX DEC CX

AGAIN: MOV AL, [BX]

15

CMP AL, MINVAL JE NEXT JG A1

MOV MINVAL, AL JMP NEXT

A1: CMP AL, MAXVAL JL NEXT

MOV MAXVAL, AL NEXT: INC BX DEC CX JNE AGAIN RETF START ENDP CODE ENDS

END START

2)实验步骤

(1)用编辑程序建立源程序文件,文件名自定。

(2)用MASM宏汇编程序和LINK连接程序将源程序文件汇编生成以EXE为扩展名的执行文件。 (3)用DEBUG调试程序将由上产生的EXE可执行文件送入内存,先用反汇编命令检查程序内容和首末地址,然后检查以BUFFER为首址的存储单元中数据块和MINVAL、MAXVAL单元的内容。BUFFER 地址单元的段地址和偏移地址是由系统在汇编和连接时指定的。各个不同的系统都不一样,一般来说,偏移地址为零,段地址可在反汇编程序时,根据指令MOV AX, DATA 对应机器码中DATA的值来确定。

(4)在DEBUG下运行程序,检查运行结果。

(5)修改源程序中BUFFER数据区的各数据,重新汇编后再运行,检查结果。

3、从无序数列中删除一个元素

1)实验内容

在BUFFER为首址的内存区中存放了一个无序字符串,其长度存放在第一个字节单元,在KEY单元内存放了要删除的一个字符,查找此无序字串,若找到则删除并作相应调整,若字串中无此字符则在FLAG单元内置FFH标志。其程序流程图如下。

2)实验步骤

(1)按以上框图编写程序,并任意设定字符个数和字符串。 (2)输入汇编语言源程序,文件名自定。

(3)用MASM和LINK程序汇编和连接生成EXE执行程序。 (4)运行该程序,并检查结果。

(5)修改字符串及其个数,再运行程序,验证程序的正确性。

16

设地址指针, 取串长度?CX KEY内容?AL 搜索字串 找到否? N Y CX—1 串搜索 N 完否? 以要删除的数据的地址 为目的地址,下一个数 Y 据的地址为源地址,以 剩下的数据个数为传送 置 次数进行传送 FLAGE单元 返回 4、思考题

① 计算机钢琴程序中,INT 21 的作用是什么?指令DIV WORD PTR[TABLE+BX]中为什么要用操作符WORD PTR?延时子程序DELAY中为什么要把AX、CX压入栈?

② 在求最大和最小值的程序中,有指令MOV MINVAL,AL和MOV MAX MAXVAL,AL将第一个数存入这两个单元,可以用哪两个立即数直接存入这两个单元也可达到同样效果? ③ 若求无符号数据块的最大和最小值,那么程序要作哪些修改? ④ 删除一个升序或降序字符串中一个字符时,程序应如何修改可使在找不到这个字符时搜集次数减少?

四、实验报告要求

1.对所有程序写上较详细的注释。 2.整理出实验中数据和运行结果。

3.总结DEBUG程序、MASM宏汇编、LINK连接程序的调试程序的方法和经验。 4.根据思考题写出答案和运行结果。

17

实验三 DOS系统功能调用及模块化程序设计

一、实验目的

2、 熟悉DOS系统中基本功能子程序的作用及其调用方法。

3、 结合DOS系统中键盘和显示功能子程序的调用和汇编语言源程序结构设计有关程序。 4、 掌握复杂程序的设计思想—模块化程序设计的方法。

二、实验设备

PC机一台,装有DOS基本系统和MASM宏汇编软件。

三、实验内容及步骤

(一)DOS键盘、显示基本功能子程序调用

DOS提供了许多系统功能子程序可由程序设计者调用,其中最基本的是键盘和显示操作功能的调用,具体调用的方法可参阅教科书。

1、 显示缓冲区的字符串 1)实验程序: DSEG SEGMENT STRING DB ‘Welcome to DONG HUA University!’,0dH,0aH,’$’ DSEG ENDS STACK SEGMENT PARA STACK ‘STACK’ DB 256 DUP (?) STACK ENDS CSEG SEGMENT MAIN PROC FAR ASSUME CS: CSEG, DS: DSEG SS: STACK START: PUSH DS MOV AX, 0 PUSH AX MOV AH, 9 MOV DX, SEG STRING MOV DS, DX MOV DX, OFFSET STRING INT 21H RET

18

MAIN ENDP CSEG ENDS END START 2) 实验步骤: (1)建立源程序文件。

(2)用MASM宏汇编程序和LINK连接程序生成执行程序。 (3)运行执行程序,输入不同字母,观察结果。

2、键盘输入小写字母,显示器显示大写字母 1)实验程序:

CSEG SEGMENT MAIN PROC FAR ASSUME CS:CSEG START:PUSH DS MOV AX, 0 PUSH AX BEGIN: MOV AH,1

INT 21H

CMP AL, ‘a’ JB STOP CMP AL, ‘z’ JA STOP SUB AL, 20H MOV DL, AL MOV AH, 2 INT 21H JMP BEGIN STOP: RET MAIN ENDP CSEG ENDS END START

2) 实验步骤: (1)建立源程序文件。

(2)用MASM宏汇编程序和LINK连接程序生成执行程序。 (3)运行执行程序,输入不同字母,观察结果。

3、从键盘输入一个二位十进制的月份数(01-12),显示相应月份的英文缩写名

1)程序及其结构

程序采用子程序的结构形式,子程序有:将输入的二位月份数转换为二进制数的子程序;从字符

19

表中查找相应的英文缩写的子程序;将月份的英文字母显示在屏幕上的子程序。 程序如下: DATASG THREE MONIN ALFMON MONTAB DATASG CODESG MAIN MAIN INPUT RETURN: INPUT:

SEGMENT PARA ‘DATA’ DB 3 DB 3,4 DUP(?) DB ‘???’,’$’ DB ‘JAN’,’FEB’,’MAR’,’APR’,’MAY’,JUN’ DB ‘JUL’,’AUG’,’SEP’, ’OCT’,’NOV’,’DEC’ ENDS SEGMENT PARA ‘CODE’ ASSUME CS:CODESG,DS:DATASG PROC FAR PUSH DS SUB AX, AX PUSH AX

MOV AX, DATASG

MOV DS, AX MOV ES, AX CALL INPUT CALL LOCATE CALL DISPLAY RET ENDP PROC NEAR ; 键盘输入并将ASCⅡ码转换二进制数的子程序PUSH DX MOV AH, 0AH ; 键盘输入月份数 LEA DX, MONIN INT 21H MOV AH, MONIN+2 ; 将月份数字的ASCⅡ码取入AH和AL MOV AL, MONIN+3 XOR AX, 3030H ; 将ASCⅡ码转换为BCD码 CMP AH, 00 JZ RETURN SUB AH, AH ADD AL, 10 POP DX RET ENDP 20

LOCATE LOCATE: DISPLAY DISPLAY CODESG

PROC

PUSH PUSH PUSH LEA DEC MUL ADD MOV CLD LEA REP POP POP POP RET ENDP PROC PUSH LEA MOV INT POP RET ENDP ENDS END

NEAR ; 将月份数字转换为英文缩写字母的子程序 SI DI CX

SI, MONTAB AL THREE SI, AX CX, 03 DI, ALFMON MOVSB CX DI SI

NEAR ; DX

DX, ALFMON AH, 09 21H DX

屏幕显示子程序

MAIN

(二)采用DOS功能调用设计源程序,并运行调试程序

1、十进制加法和结果显示程序(自行设计) 1)程序设计要求

将数据段DSEG中的ADDOP1定义的双字变量的4位十进制数和附加段ESEG中的ADDOP2定义的双字变量的4位十进制数相加,和存放于数据段DSEG中的SUM中,采用DOS显示功能调用将和显示在屏幕上。 2) 实验步骤: (1)建立源程序文件。

(2)用MASM宏汇编程序和LINK连接程序生成执行程序。

21

(3)运行执行程序,输入不同的加数和被加数,观察结果。

2、十进制加法和算式显示程序(自行设计) 1) 程序设计要求 在以上十进制数加法要求的基础上,将加法算式及和在显示器上显示。 如ADDOP1中存放1234H,在ADDOP2中存放6789H,执行程序后显示器上显示: 1234+6789=8023 2) 实验步骤: (1)建立源程序文件。

(2)用MASM宏汇编程序和LINK连接程序生成执行程序。 (3)运行执行程序,输入不同的加数和被加数,观察结果。

3、键盘输入加数和被加数进行十进制数加法,显示结果程序(自行设计) 1)程序设计要求 采用DOS的键盘功能调用和显示功能调用,将键盘输入的4位十进制被加数和4位加数相加,和存入有关内存单元,并将算式及和显示在显示器上。 要求采用子程序的设计方法设计程序,例如设计一个从键盘读入输入数据的子程序和将数据显示的子程序。

2)实验步骤:同上

(三)模块化程序设计

模块化程序设计是指将一个较大的功能分解成几个独立功能的子模块,每个子模块独立编缉各自建立一个文件,通过单独的汇编生成各个独立的目标文件,然后由LINK 程序将各个目标文件链接在一起,形成一个完整的执行文件。

1)实验程序的设计思想及其实现功能 程序实现键盘输入十进制数,以十六进制数形式在屏幕上显示的功能。程序分成两个模块,模块A为主程序,负责从键盘输入一个十进制数,处理后存入指定内存单元。模块B主要实现屏幕提示和将十六进制数转换及显示的功能。

实验程序参见教科书“微型计算机原理及应用”(吴宁主编)P185页上 模块化程序设计例1。

2) 实验步骤:

(1) 输入模块A程序和模块B程序,各产生一个文件。 (2) 汇编两个程序生成两个目标文件。

(3) 用LINK 文件名1+文件名2 命令链接为一个可执行文件。 (4) 运行程序,输入不同的十进制数,观察结果。

22

四、 思考题:

1、在实验(一)题3中,如输入01-12以外的数时将会出现什么结果?

2、如果输入非法的十进制数时,你所设计的实验(二)题3的程序是如何处理的?若无这种功能请增加提示、出错处理等功能,完善以上程序。

3、实验(三)的程序中是否对输入任何位的十进制数都能在屏幕上显示其十六进制数? 4、在实验(三)的程序中如果以回车键作为对输入数据的确认,程序应作什么修改?

五、试验报告要求

写出(二)1、2、3自行设计的采用DOS功能调用设计源程序的程序清单。

23

实验四 教材第4章习题程序设计

题目见教材第4章习题. 要求编程并调试通过,.

附录一 DEBUG 常用命令

DEBUG是为汇编语言设计的一种调试工具,它通过单步、设置断点等方式为汇编语言程序员提供了非常有效的调试手段。

6.1 DEBUG 程序的调用

在DOS的提示符下,可键入命令:

C>DEBUG[d: ][path]filename[.exe][parm1][parm2]

其中,文件名是被调试文件的名字。如用户键入文件名,则DUBUG将指定的文件装入存储器中,用户可对其经行调试。如果未键入文件名,则用户可以用当前存储器的内容工作,或者用DUBUG命令N和L把需要的文件装入存储器后再经行调试。命令中的d指定驱动器,path为路径,parm1和parm2则为运行被调试文件时所需要的命令参数。

在DUBUG程序调入后,将出现提示符,此时就可用DUBUG命令来调试程序。

6.2 DUBUG的主要命令

1)显示存储单元的命令D(DUMP),格式为: -D[address]或 -D[range]

例如,按指定范围显示存储单元内容的方法为:

—d100 120

18E4:0100 C7 06 04 02 38 01 C7 06—06 02 00 02 C7 06 08 02 G?8.G??G? 18E4:0110 02 02 BB 04 02 E8 02 00—CD 20 50 51 56 57 8B 67 ?;?h?MPQVW. 7

18E4:0120 8B

其中0100至0120是DUBUG显示的单元内容。左边用十六进制表示每个字节,右边用ASCII字符表

24

示每个,。表示不可显示的字符。这里没有指定段地址,D命令自动显示DS段的内容。如果只指定首地址,则显示从首地址开始的80个字节的内容。如果完全没有指定地址,则显示上一个D命令显示的最后一个单元后的内容。

2)修改存储单元内容的命令有两种。 .输入命令E(Enter),有两种格式如下:

第一种格式可以用给定的内容表来替代指定范围的存储单元内容。命令格式为: —E address [List]

例如,—E DS :100 F3’XYZ’8D

其中F3,’X’,’Y’,’Z’和8D各占一个字节,该命令可以用这五个字节来替代存储单元DS:0100到0104的原先的内容。

第二种格式则是采用逐个单元相继修改的方法。命令格式为: —E address 例如,—e cs :100 则可能显示为:

18E4:0100 89.—

如果需要把该单元的内容修改为78,则用户可以直接键入78,在按“空格”键可接着显示下一个单元的内容,如下:

18E4:0100 89.78 1B

这样,用户可以不断修改相继单元的内容,直到用Enter键结束该命令为止。

3)检查和修改寄存器内容的命令R(Register),它有三种格式如下: .显示CPU内所有寄存器内容和标志位状态,其格式为: —R 例如,

—r

AX=0000 BX=0000 CX=010A DX=0000 SP=FFFE BP=0000 SI=0000 DI=0000 DS=18E4 ES=18E4 SS=18E4 CS=18E4 IP=01OO NV UP DI PL NZ NA PO NC 18E4:0100C70604023801 MOV WORD PTR [0204],0138 DS:0204=0000

其中标志位状态的含义可见第二章表2.1。

.显示和修改某个寄存器内容,其格式为: —R register name 例如,键入

—r ax

系统将响应如下:

AX FIF4 :

即AX寄存器的当前内容为FIF4,如不修改则按Enter键,否则,可键入欲修改的内容,如:

—r bx BX 0369 : 059F

则把BX寄存器的内容修改为059F。

25

4)运行命令G,其格式为

—G[=address1][address2[address3?]。

其中,地址1指定了运行的起始地址,如不指定则从当前的CS:IP开始运行。反面的地址均为断点地址,当指令执行到断点时,就停止执行并显示当前所有寄存器及标志位的内容,和下一条将要执行的指令。

5)跟踪命令T(Trace),有两种格式; .逐条指令跟踪 —T[=address]

从指定地址执行一条指令后停下来,显示所有寄存器内容及标志位的值。如未指定地址则从当前的CS:IP开始执行。

.多条指令跟踪

-T[=address][value]

从指定地址起执行n条指令后停下来,n有value指定。

6)汇编命令A(Assemble),其格式为: —A[address]

该命令允许键入汇编语言语句,并能把它们汇编成机器代码,相继地存放在从指定地址开始的存储区中。必须注意:DUBUG把键入的数字均看成十六进制数,所以如要键入十六进制数,则起后应加以说明,如100D。

7)反汇编命令U(Unassemble),有两种格式。 .从指定地址开始,反汇编32个字节,其格式为: —U[address] 例如:

-u100

18E4:0100 C70604023801 MOV WORD PTR [0204],0138 18E4:0106 C70606020002 MOV WORD PTR [0206],0200 18E4:010C C70608020202 MOV WORD PTR [0208],0202 .对指定范围内的存储单位经行反汇编,格式为: —U[range]

例如:

-u100 10c

18E4:0100 C70604023801 MOV WORD PTR [0204],0138 18E4:0106 C70606020002 MOV WORD PTR [0206],0200 18E4:010C C70608020202 MOV WORD PTR [0208],0202 8)命名命令N(Name),其格式为: —N filespece[filespeces]

命令把两个文件标识符格式化在CS:5CH和CS:6CH的两个文件控制块中,以便在其后用L或W命令把文件装入或存盘。Filespecs的格式可以是:

[d: ][path] filename[.ext] 例如,

—N myprog

26

—L —

可把文件myrong装入存储器。

9)装入命令L(Load),有两种功能。

。把磁盘上指定扇区范围的内容装入到存储器从指定地址开始的区域中。其格式为: L [address[drive sector sector] .装入指定文件,其格式为: —L[address]

此命令装入已在CS:5CH中格式化了控制块所指定的文件中。如未指定地址,则装入CS:0100开始的存储区中。

10)写命令W(Write),有两种功能。 .把数据写入磁盘的指定扇区。其格式为: —W address drive sector sector .把数据写入指定的文件中。其格式为: —W [address]

此命令把指定的存储区中的数据写入由CS:5CH处的文件控制块所指定的文件中。如未指定地址则数据从CS:0100开始。要写入文件的字节数应先放入BX和CX中。

11)退出DEBUG命令Q(Quit),其格式为: —Q

它退出DEBUG,返回DOS.本命令并无存盘功能,如需存盘应先使用W命令。

附录二 键盘和显示的DOS功能调用

表9.5 DOS键盘操作(INT21H)

AH 功能 调用参数 返回参数 1从键盘输入一个字符并回显在屏幕上 AH=字符 6读键盘字符 DL=0FFH AL=字符 (如果准备好) AL=0 (未准备好) 7从键盘输入一个字符,不回显 AL=字符 8从键盘输入一个字符,不回显

检测CtrLBreak AL=字符 A输入字符到缓冲区 DS:DX=缓冲区首址

B 读键盘状态 AL=0FFH有键入 AL=00无键入

C 清除键盘缓冲区,并调用一种键盘功能 AL= 键盘功能号(1,6,8,7或A) 9.1.3.1单字符输入

DOS21H中断的功能1,7,和8都能从键盘读一字符送入AL寄存器。功能1能把字符显示出来并检验是否按下了CtrlBreak键,就自动调用中断23H并结束程序。21H 的功能7不能回打字符

27

或检验CtrlBreak。21H的功能8检验Ctrlbreak,但是不回显 。

在交互程序中常常需要用户对一个提示做出应答,或通过输入一个字母或数字对菜单的各项进行选择,这时就要用到21H的单字符输入功能。例如程序显示出一蹿信息,要求你回答Y或N,回答Y,程序将转入标号为Yes的程序段,而N使程序转入标号为NO的程序段,按下其他键程序就等待。这样的工作由下面的程序段来完成

GET-KEY: MOV AH,1 Read a key with echo INT 21H

CMP AL,Y Is it Y?

JE YES If so,jump to Yes CMP AL,N Is it N ?

JE NO If so,jump to NO

JNE GET-KEY otherwise,wait for Y or N

测试Y,N或其他字母,数字和符号可直接把他们写在CMP指令中,用引号括起来。但是如果想检测Enter(Return)键,就要在指令中写出它的ASC11码0D(16进制)或13(十进制)。例如,要求程序在按下Return键后才继续运行,用下面的指令:

WAIT HERE; MOV AH 7 WAIT FOR ENTER INT 21 H

CMP AL , 0DH JNE WAIT—HERE

这里用AH=7代替AH=1,差别只是不把按下的键显示出来,或不执行键的特定功能。

如果要求程序能接受功能或数字组合键必须进行两次DOS调用,第一次回送00,第二次回送扫描码。例如,程序显示出一个菜单,要求用户通过键入F1,F2或F3来选择1,2或3 项,按其它键则产生错误信息序的应答检测部分如下:

MOV AH,7 ;Wait for key INT 21H

CMP AL,0 ;Is it a function key? JE GET_EC ;yes, read the scan code JMP ERROR ;No, display error message

GET_EC: MOV AH,7

INT 21H

CMP AL,3BH ;F1? JE OPTION1

CMP AL,3CH ;F2? JE OPTION2

CMP AL,3DH ;F3? JE OPTION3

JMP ERROR ;Invalid key ,display ;error message

9.1.3.2 输入字符串

在许多应用程序中,要求用户输入姓名、地址或其它字符串,21H中断的功能A能从键盘读入一串字符并把它存入用户定义的缓冲区中。缓冲区的第一个字节保存最大字符数,这个最大字符数

28

由用户程序给出。如果键入的字符数比此数大,那就会发出“嘟嘟”声,而且光标不再向右移动。

第二个字节是实际输入字符的个数,这个数据是由功能A填入的,而不是由用户填入。在这两个字节之后,字符串就按字节存入缓冲区,最后结束字符串的回车符0DH还要占用一个字节,因此整个缓冲区的字节空间应为最大字符数(包括Return在内)加2。

MAXLEN DB 32 ACTLEN DB ?

STRING DB 32 DUP(?) 输入字符串的指令如下:

LEA DX,MAXLEN ;Make DX point to buffer MOV AH,0AH ;Input the string INT 21H 如果我们键入字符串:

By brooks too broad for leaping↙

此时缓冲区MAXLEN的各存储单元图示如图9.4。 20 lB y b r o o k s t o f o b r o a d f o r l e a p i n g 0d ﹕ ﹕ ﹕ ﹕ ﹕ ﹕

﹕ ﹕ 字符串开始 ﹕ ﹕

﹕ 实际键入的字符数 ﹕

最大字符数

图9.4 字符缓冲区

INT 21的功能A把实际字符数(不包括Return)填入缓冲区的第二个字节,并保持DS:DX指向缓冲区的第一个字节。如果想把实际字符数放入CX寄存器,并把指针(DS:DX)指向字符串的第一个字符,图9.5的程序可完成这个工作。

;Read a string from the keyboard ; this procedure read up to 50 keys

;﹡﹡﹡﹡﹡﹡﹡﹡﹡﹡﹡﹡﹡﹡﹡﹡﹡﹡﹡﹡﹡﹡﹡﹡﹡﹡﹡﹡﹡ dseg segment

user_string db 50,0,50 dup(?) dseg ends

;- - - - - - - - - - - - - - - - - - - - - - - - - - - - cseg segment

assume cs:cseg,ds:dseg read_keys pro far push ds sub ax,ax push ax

29

mov ax,dseg mov ds,ax

lea dx,user_string mov ax,0ah int 21h sub ch,ch

mov cl,user_string+1 add dx,2 ret read_keys endp

; - - - - - - - - - - - - - - - - - - - - - - - - - - - - Cseg ends

;﹡﹡﹡﹡﹡﹡﹡﹡﹡﹡﹡﹡﹡﹡﹡﹡﹡﹡﹡﹡﹡﹡﹡﹡﹡﹡﹡﹡﹡ end

图9.5 输入字符串程序

9.1.3.3 清除键盘缓冲区

从键盘输入的字符实际上先放在一个16字节的键盘缓冲区内,功能1,7,8和0AH实际上是从键盘缓冲区取得字符。

INT 21H的功能0CH能清除键盘缓冲区,然后执行在AL中指定的功能,AL指定的功能可以是1,6,7,8或0AH,使用0CH可以使程序在输入一个字符之前,将以前键入的字符清除掉。

功能0CH的用法如下: MOV AH,0CH MOV AL,08H INT 21H

这几条指令实际提供的输入功能是8,它不回打,但要检测Ctrl_Break。如果不想用Ctr_ INT 10H ;video ROM call

MOV AH,8 ;read char and attr MOV BH,0 ;page 0

INT 10H ;video ROM call 9.2.3 DOS显示功能调用

表9.7为INT 21H的显示操作,其中有两个是显示单字符的功能,另一个是显示字符串 功能,这些功能都自动向前移动光标。

表9.7 INT 21H显示操作

30

AH 功能 调用参数 2 显示一个字符 (检验Ctrl_Break) 6 显示一个字符 (不检验Ctrl_Break) DL=字符 光标跟随字符移动 DL=字符 光标跟随字符移动 9 显示一个字符 DS:DL=串地址 串必须以$结束,光标跟随字符移动

AH=9的功能是显示字符串,它要求被显示输出的字符必须以$字符(24h)作为定界符,此功能是用$作为标记来计算串的长度的。有些ASXII码,如控制码,不能出现在该字符串中。显示字符串时,如果希望光标能自动换行,那么可在字符串结束之前加上回车和换行的ASCII码。

MESSAGE DB ‘The sort operation is finished.’,13,10,’$’ 要显示输出的信息一般定义在数据段。输出该字符串的指令为: MOV AH,9

MOV DX,SEG MESSAGE MOV DS,DX

MOV DX,OFFSET MESSAGE INT 21H

使用赋值伪操作可以使程序的可读性更好,另外也可以根据显示格式的要求使用TAB符,TAB的ASCII码为09。

CR EQU 13(CR EQU 0DH) LF EQU 10(LF EQU 0AH) TAB EQU 09

MESSAGE DB TAB,’The sort operation is finished’ DB CR,LF,’$’

使用INT 21H显示字符串,一定要在显示串之后加上定界符$丢失定界符可能在屏幕上引起意想不到的后果。

31

AH 功能 调用参数 2 显示一个字符 (检验Ctrl_Break) 6 显示一个字符 (不检验Ctrl_Break) DL=字符 光标跟随字符移动 DL=字符 光标跟随字符移动 9 显示一个字符 DS:DL=串地址 串必须以$结束,光标跟随字符移动

AH=9的功能是显示字符串,它要求被显示输出的字符必须以$字符(24h)作为定界符,此功能是用$作为标记来计算串的长度的。有些ASXII码,如控制码,不能出现在该字符串中。显示字符串时,如果希望光标能自动换行,那么可在字符串结束之前加上回车和换行的ASCII码。

MESSAGE DB ‘The sort operation is finished.’,13,10,’$’ 要显示输出的信息一般定义在数据段。输出该字符串的指令为: MOV AH,9

MOV DX,SEG MESSAGE MOV DS,DX

MOV DX,OFFSET MESSAGE INT 21H

使用赋值伪操作可以使程序的可读性更好,另外也可以根据显示格式的要求使用TAB符,TAB的ASCII码为09。

CR EQU 13(CR EQU 0DH) LF EQU 10(LF EQU 0AH) TAB EQU 09

MESSAGE DB TAB,’The sort operation is finished’ DB CR,LF,’$’

使用INT 21H显示字符串,一定要在显示串之后加上定界符$丢失定界符可能在屏幕上引起意想不到的后果。

31

本文来源:https://www.bwwdw.com/article/gi56.html

Top