DEBUG实验参考.docx
《DEBUG实验参考.docx》由会员分享,可在线阅读,更多相关《DEBUG实验参考.docx(17页珍藏版)》请在冰豆网上搜索。
![DEBUG实验参考.docx](https://file1.bdocx.com/fileroot1/2022-11/25/f0750102-c201-48cd-b07f-77268967972b/f0750102-c201-48cd-b07f-77268967972b1.gif)
DEBUG实验参考
实验一顺序程序设计与DEBUG使用
一、实验题目
1.利用串操作传送指今将0FFH送入数据段的0180H开始的128个字节存储单元中,编写一段程序。
2.将数据段中0200H字节存储单元中的二位BCD码转换为二个ASCII码送0201H开始的二个字节单元中,编写—段程序。
3.编写一段程序,在内存中自SQTAB(0200H)地址开始的连续十个单元中存放0~9的平方值。
要求利用计算法查表求NUM(0210H)单元中指定数(0~9中的任意一数)的平方值,并将所求平方值存入RESULT(0211H)单元中。
[注]:
题目二和题目三可选做一个,题目一必做。
二、实验设备
硬件环境IBM/PC及其兼容机
软件环境操作系统DOS6.22
调试程序DEBUG.COM
三、实验要求
1、利用DEBUG程序中的A命令,对编写好的源程序进行编辑和汇编。
2、利用U命令对汇编后的目标程序进行反汇编,可检查编辑的程序是否正确,也可知道每条指令的IP值。
3、利用T、G命令对程序进行单步、没断点和连续执行。
4、利用R、D、E命令可对程序运行前预置数据,运行中检查中间结果和远行后检查最终结果。
5、利用Q命令退出DEBUG程序,返回DOS。
四、预习要求
1、复习DOS启动及DOS的有关命令的使用。
2、阅读本指导书的附录一,了解和掌握DCBUG程序中的A、U、R、D、E、T、G和Q的书规定和功能。
3、预先编写好题目中的源程序。
(第一题已有源程序,见实验步骤)
五、实验步骤
题目一:
1、启动DOS操作系统。
2、运行DEBUG.COM程序
D:
>DEBUG
—(此即处于DEBUG等待命令状态的提示符)
3、用A命令编辑和汇编源程序(黑体字部分为键盘输入部分)
_A
16C0:
0100MOVDI,0180
0103MOVCX,80
0106MOVAL,FF
0108REPSTOSB
010AHLT
010B
-
4、用U命令反汇编验证源程序
_UCS:
0100
16C0:
0100BF8001MOVDI,0180
16C0:
0103B97F00MOVCX,0080
16C0:
0106BOFFMOVAL,FF
16C0:
0108F3REPZ
16C0:
0109AASTOSB
16C0:
010AF4HLT
5、源程序若有错,可返回第3步用A命令进行修改,再进行3—4。
无错误,可运行程序。
6、用R命令观察程序末执行前,程序中各有关寄存器内容,并填人括号中。
_R
AL=(),DI=(),CX=(),DS=(),CS=(),IP=()
7、用D命令观察程序未执行前,存放结果的存储区中内容。
_DES:
0180
8、用T命令执行一条指令,观察DI寄存器内容的变化,并填入此值:
_T
DI=()IP=()CS=()
9、用T命令一条条执行程序,并观察相应的寄存器内容或存储单元内容,一直执行到最后一条指令为止。
10、用D命令观察最终结果
_DES:
0180
此时可观察到ES:
0180~ES:
01FF单元中内容已全部改变为FF。
11、用R命令改变1P值,使它回到程序的第一条指令处
_RIP
_0100
12、用R命令以观察IP值,已改变为0100
_R
13、用A命令对存储数据的缓冲区改变位置
_ACS:
0100
16C0:
0100MOVDI,0200
16C0:
0103
-
14、用D命令观察程序执行前,存储区的内容
_DES:
0200
15.用G命令设置断点为HLT指令处
_G10A
16.再用D命令观察执行结果
_DES:
0200
将会观察到,ES:
0200--ES:
027F的内容全改变为FF。
题目二
1.用A命令将已编写好的源程序进行编辑和汇编。
2.用E命令对DS:
0200单元设置二位BCD码数据。
3.参照题目一的实验步骤,对上述程序进行调试和运行。
4.查看每一条指令执行的中间结果和最终结果,验证是否满足题目设计要求,若不满足,再用A命令对程序进行修改。
重新对程序进行调试和运行,直到结果正确为止。
题目三
1.用A命令将已编写好的源程序进行编辑和汇编。
2.用E命令对DS:
0200开始的平方表置0~9的平方值。
对DS:
0210单元置0~9中的任一数。
3.参照题目一的实验步骤,对上述程序进行调试和运行。
4.查看每一条指令执行的中间结果和最终结果,验证是否满足题目设计要求,若不满足,再用A命令对程序进行修改,重新对程序进行调试和运行,直到结果正确为止。
附录一、调试程序DEBUG的使用
DEBUG是专为汇编语言设计的一种调试工具,是汇编语言程序员必须掌握的调试手段。
一、如何调用DEBUG程序
在PCDOS的提示符D:
>下,可以打人如下命令:
D:
>DEBUGG[d:
][path][filename[ext]][parm1][parm2]
其中DEBUG是调试程序的文件名;后面是要调试的程序的文件标识符。
若在命令中规定了文件标识符,则在DOS把DEBUG程序调入内存后,DEBUG程序把要调试的程序(根据文件标识符)调入内存。
若在命令中没有规定文件标识符,则DEBUG程序或者与正在内存中的内容打交道;或可以用Name和Load命令,从盘上输入要调试的程序。
命令行中的[parm1(参数1)][parm2(参数2)]。
我们在后面结合具体的命令加以介绍。
在DEBUG程序调入后,出现提示符“—”。
说明现在系统在DEBUG程序的管理之下,所有DEBUG命令,也只有在出现此提示符后才有效。
二、DEBUG程序对寄存器和标志位的初始化
在DEBUG程序启动后,它把各个寄存器和标志位,置成以下状态:
1.段寄存器(GSDSES和SS)置于自由存贮空间的底部,也就是DEBUG程序结束以后的第一个段。
2.指令指针(IP)置为0100H。
3.堆栈指针置到段的结尾处,或者是装入程序的临时底部,取决于哪一个更低。
4.余下的寄存器(AXBXCXDXBPSI和DI)置为0。
但是,若调用DEBUG时包含一个要调试的程序文件标识符,则CX中包含以字节表示的文字长度,若文件大于64K,则文件长度包含在BX和CX中(高位部分在BX中)。
5.标志位都置为清除状态。
6.default的磁盘缓冲区置于代码段的80H。
注:
若由DEBUG调入的程序,具有扩展名.EXE,则DEBUG必须进行再分配。
把段寄
存器、维栈指针置为程序中所规定的值。
三、有关DEBUG命令的一些共同信息:
1。
DEBUG命令都是—个字母,后面跟有一个或多个参政。
2.命令和参数可以用大写或小写或混合方式输入。
3.命令和参数间可以用定界符分隔。
然而定界符只是在两个邻接的16进制之间是必需的。
因此,下列命令是等效的;
dcs:
100110
dcs:
100,110
4.可以用按CtrlBreak键来停止一个命令的执行,返回DEBUG提示符。
5.每一个命令,只有按了ENTER键以后才有效,才开始执行。
6.若一个命令产生相当多的输出行,为了能在屏幕上当一行卷走以前读清楚它,可以在显示过程中,按CtrlNumLock键,以暂停上卷;可以按任何一个字符来重新启动。
7.若DEBUG检查出一个语法错误,则显示具有错误的行和指示错误所在。
例如:
dcs:
100cs:
110
error
四、DEBUG的主要命令
1.显示内存单元内容的命令(DumpCommand)
为了了解程序执行的结果,检查内存单元的内容是十分重要的。
此命令能检查指定范围的存贮单元的内容。
命令的格式为:
D[地址]或D[范围]
其中,D是命令字母,[地址]或[范围]都是为了指定要显示的存贮单元的范围。
存贮单元的内容用两种方式显示:
一种是每一个存贮单元的内容(每一字节)用两位16进制数显示;另一种是用相应的ASCII字符显示,句号(.)表示不可显示的字符。
显示有两种格式,若是40列系统显示格式,每—行显示8个字节,若是80列显示格式,每一行显示16字节。
第8、9字节间有一连字符(—)。
显示命令有两种常用的格式:
(1)格式为:
D地址或D
若命令中有指定地址,则从指定地址开始,显示40H个字节(相应于系统的40列显示格),或80H个字节(相应于80列显示格式)。
若命令中没有指定起始地址,则从上一个D命令所显示的最后一个单元的下一个单元开始。
若以前没有使用过D命令,则从由DEBUG初始化的段寄存器的内容,加上地址偏移量0100H作为起始地址。
若在命令中所打人的地址中,只包含起始地址的偏移量,则D命令认为段地址包含在DS中。
例如:
对于80列的显示格式
—D100
显示的起始地址由DS内容(作为段地址)与100H(作为偏移量)组成。
共显示80H个单元的内容。
(2)显示指定范围的内容:
D范围
在范围中包含起始地址和结束地址。
若输入的起始地址中,未包含段地址部分,则D命令认为段地址在DS中;而输入的结尾地址中,只允许有地址偏移量。
例如:
-DDS:
1000200
2、修改存贮单元内容的命令
此命令用于修改存贮单元的内容,它有两种基本格式:
(1)用命令的内容表去代替指定范围的内存单元的内容
E地址内容表
例如:
E DS:
100F3”XYZ”8D
内存单元DS:
100到DS:
104这5个单元的内容由表中给定的5个字节的内容(其中2个字节用16进制数表示,即F3、3D;另三个用字符表示,就是“ XYZ”,用它们的ASCII码值代入)所代替。
(2)一个单元一个单元地连续修改方式
E地址
在输入了上述命令,屏幕上显示指定单元的地址和原有的内容之后,可以采用以下几种操作中的一种:
1、再输入一个字节的16进制数,以代替原单元中的内容,然后可以采取下面三种操作之一。
2、按空格键,则上一个替换要求完成,且显示下一个单元的地址和原有的内容,要修改的话,则输入两位16进制数,再按空格键盘······这样就可以连续地进行修改。
若某一单元的内容不需要修改而操作要进行下去,则可直接按空格键。
3、输入一个连接号(-),则又显示前一单元的地址和内容,若要修改的话,就输入一个字节的内容,然后再按“-”,则又显示前一个单元的地址和内容······这样,就可以连续地进行反向修改。
若所示的前一单元的内容不需要修改,可直接按“-”键。
4、按回车键结束此命令。
3、检查和修改寄存器内容的命令(RegisterCommand)
为了了解程序运行是否正确,检查寄存器内容的操作是十分重要的。
R命令有三种功能:
(1)能显示CPU内部的所有寄存器的内容和全部标志。
(2)能显示和修改一个指定的寄存器的内容。
(3)能显示和修改所有标志位的状态。
下面分别予以介绍:
1、命令格式:
R
则系统的响应为:
A>DEBUGEXAMPLE4.EXE
-r
AS=0000BX=0000CX=004ADX=0000SP=0064BP=0000SI=0000DI=0000DS=07B5ES=07B5SS=07C6IP=0000NVUPDIPLNZNAPONC
07C6:
0000BSC507MOVAX,07C5
前两行显示格式显示了所有CPU内部寄存器内容和全部标志的状态(其含意在下面介绍),第三行显示了现行CS:
IP所指的指令的机器码以及汇编符号,这就是下条即将要执行的指令。
2·命令的格式:
R寄存器名
例如为了检查和修改寄存器AX的内容,可打入以下命令:
-RAX
则系统可能出现如下响应:
AXFIF4
此时,可采取以下两种操作之一:
若不需要改变其内容,直接按Enter键。
若需要改变内容的话,则输入1-4个16进制数值,再按Enter键,以实现修改。
例如:
-rBX
BX0369
:
059F
则BX中的内容由0369H改变成059FH。
3、显示和修改标志状态
在8086/8088中,共有九位标志,其中追踪标志T不能直接用指令改变,其它8个标志位可以显示和修改。
在显示时,8个标志的显示次序和符号如下:
标志名置位于复位
溢出overflow(是/否)OY NY
方向Direction (减量/增量)DNUP
中断Interrupt(允许/屏蔽)EIDI
符号Sign(负/正)NGPL
一Zero(是/否)ZRNZ
辅助进位AnxigiaryCarry(是/否)ACNA
奇偶Parity(偶/奇)PE PO
进位Carry(是/否)CYNC
命令的格式为:
RF
系统可能给出如下响应:
OVDNEINGZGZRACPECY-
于是可以采取以下两种之一的操作:
若不需要修改任一已设置的标志状态,可直接按Enter。
若有一个或多个标志需要修改,则可以输入此标志的相反的值。
输入的标志的次序是无关的、输入的各个标志之间,可以没有空格。
然后按Enter键,以实现修改。
例如:
OVDREINGZRACPECY-PONZDINV
4、运行命令(GoCommand)
为了检查程序运行是否正确,希望在运行中能设置断点,以便一段一段对程序对程序进行调试。
G命令的格式为:
G[=address][address][address…]]
其中,第一个参数=address规定了起始地址;以CS中的内容作为地址,以等号后面的地址作为地址的偏移量。
在输入时=号是不可缺少的(以便与后面输入的数据点地址相区分)。
若不输入起始地址,则以CS:
IP作为起始地址。
后面的地址参数是断点地址。
若在命令行中,除了起始地址以外,没有任何地址参数,则程序执行时没有断点。
在开始调试程序时,往往要设置断点。
DEBUG程序中允许最多可设置10个断点,这些断点地址的次序是任意的。
设置多个断点的好处是:
若程序有多个模块,多个通路,不管是哪一个通路执行,都有可能在断点处停下来。
DEBUG程序用一个中断类型3指令(操作码为CCH)来代替被调试的程序在断点地址处的指令操作码。
当程序行致电一个断点地址时就停了下来显示CPU内部所有寄存器的内容,和全部标志位的状态(相当于一条R命令);被调试程序的所有断点处的指令被恢复(若程序行未遇到断点,则不恢复);全部断点被取消;返回DEBUG。
于是,就可以利用各种DEBUG命令来检查程序执行的结果和进行必要的修改。
注解:
1。
命令中的地址参数所指的单元,必须包含有有效的8086/8088的指令码。
若指定的地址单元,不包含有效指令的第一个字节,则会出现不可预料的结果。
2。
对于GO命令,堆栈必须至少包含有6个可用的字节;否则会出现不可预料的结果。
3。
若输入的断点地址,只包含地址偏移量,则G命令认为其段地址在段寄存器CS中。
5、追踪命令
追踪命令有两种格式:
(1)一条指令一条指令地追踪
若打入命令
T[=address]
则执行一条指定地址处的指令,就停下来,显示CPU所有寄存器和全部标志位的状态,以及下一条指令的地址和内容,返回DEBUG。
此时可以用其它DEBUG命令进一步检查此条指令执行的结果,和作必要的修改。
若在指令中没有指定地址,则从CS:
IP的现行值执行。
(2)多条追踪命令
命令的格式为:
T=[=address][值]
此命令从指定的地址开始(若命令中用[=地址]给定了起始地址,则从这起始地址开始,若未给定,则从当前的CS:
IP开始),执行由命令中的[值]所决定的几条指令,执行就停下来了。
T命令显示每条指令执行后的寄存器的内容和全部标志位的状态。
执行停下来后,返回DEBUG,可以用DEBUG的其它命令进一步检查指令执行后的结果,和作必要的修改。
6.汇编命令(AssembleCommand)
若在调试中发现程序中的某一部分要改写;或要增补一段等等,就可以直接在DEBUG下输入、汇编、运行和调试这一段程序。
这比每一次修改都要经过编辑、汇编、连接……这样的过程简便多了。
汇编命令的格式为:
A[地址]
于是从指定的地址开始,可以输入汇编语言的语句,A命令把它们汇编成机器码从指定的地址单元开始连续存放。
若在命令中没有指定地址,但前面用过汇编命令的话,则接着上一个汇编命令的最后一个单元开始存放。
若前面未用过汇编命令,则从CS:
100单元开始存放。
若输入的语句中有错,DEBUG就显示
Error
且重新显示现行的汇编地址,等待新的输入。
DEBUG支持标准的8086/8088汇编语言语法(和8087指令系统),具有以下一些规则:
(1)所有输人的数字值,全为16进制数,可输入1—4个16进制数字字符。
(2)前缀助记符,必须在相关的指令之前输入,也可以分别放在不同的行。
(3)段超越助记符为CS:
、DS:
、ES:
、SS:
。
(4)串操作助记符中,必须注明串操作的长度:
即说明是字操作还是字节操作。
(5)交叉段返回(远返回)的助记符为BETF。
(6)汇编程序能自动汇编短、近和远的转移和调用,取决于到目的地址的字节偏移量。
这些也能够由NEAR和FAR前级来超越。
例如:
0100:
0500JMP502;两字节短转移指令
0100:
0502JMPNEAR505;三字节短转移指令
0100:
0505JMPFAR50A;五字节远转移指令
(7)DEBUG不能确定某些数涉及的是字存储单元还是字节存储单元。
在这种情况下,必须用前缀“WORDPTR”(可缩写为“WO”)0R“BYTEPTR”(可缩写为“BY”)来明确说明数据类型。
例如:
NEGBYTEPTR[126]
DECWORDPTR[SI]
(8)DEBUG也不能确定一个操作数是立即数还是存贮单元的地址。
所以DEBUG中存贮单元的地址,放在方括号中。
例如:
MOVAX,21H;把21H送至Ax
MOVAX,[21];把地址为21H以及22H存贮单元的内容送至Ax
(9)两个最常用的指令DB和DW也能被使用;用来直接把字节和字的值送入相应的存贮单元。
例如:
DB1,2,3,4,“THISISANEXAMPLE”
DW1000,2000,3000,“CH”
(10)DEBUG支持所有形式的寄存器间接寻址命令。
例如:
ADDBX,34[BP+2][SI—1]
POP[BP+DI]
(11)DEBUG支持所有的操作码的同义词。
例如:
LOOP100
JA200
下面我们举一个例子,来说明A命令的使用。
-ACS:
0100
08F8:
0100db30,31,32,33,34,356,37,38,39,41,42,43,44,45,46
08F8:
0110movsi,0100
08F8:
0113movdi,0200
08F8:
0116movcx,10
08F8:
0119repmovsb
08F8:
011bhlt
例:
08F8:
011C
先用伪指令DB,输入要传送的源操作数;然后输入数据块传送程序。
在程序输入完毕后,最后一行不输入内容,直接按回车,使返回DEBUG。
7.反汇编命令(UnassembleCommand)
若在内存某一区域中,已经有了某一个程序的目标码。
为了能清楚了解此程序的内容,就希望能把目标程序反汇编为源程序。
这朱要用到U命令。
U命令有两种常用的格式。
(1)一种格式为:
U或U地址
则从指定的地址开始,反汇编16个字节(在系统的40列显示方式)或反汇编32个字节(在80列显示方式)。
若在命令中没有指定地址,则以上一个U命令的最后一条指令的地址的下一单元作为起始地址;若没有输入过U命令,则以由DEBUG初始化的段寄存器的值,作为段地址;以0100作为地址偏移量。
例如:
A>debugexaml1.exe
-u
0091:
0000B81F00MOVAX,091F
0091:
00038ED8MOVDS,AX
0091:
00058EC0MOVES,AX
0091:
0007B82209MOVAX,0922
0091:
000A8ED0MOVSS,AX
这样的U命令一次显示32个字节(80列显示格式),但程序未完,可再用U命令接着显示。
(2)第二种格式为:
U范围
对指定范围的内存单元进行反汇编。
范围可以由起始地址、结束地址来规定,例如:
U04Ba:
01000108
也可以由起始地址及长度来规定。
例如:
U04BA:
0100L9
这与上一个命令的结果是相同的。
若命令中规定结束地址,则结束地址中只包含地址偏移量。
此命令一次把指定范围的内容反汇编出来。
故若已知要反汇编的程序的长度(字节数),则用此命令,一次可把整个程序都反汇编出来。
是很方便的。
8.输入命令(InputCommand)
此命令能从指定的端口输入一个字节且显示出来。
命令的格式为:
I 端口地址
I34
5F
从端口地址34H输入一字节的内容5FH。
9.输出命令(OutputCommand)
此命令能向指定的端口输出一个字节。
命令的格式为:
O端口地址字节值
10.命名命令(NameCommand)
此命令有两个功能:
(1)用命令中给定的两个文件标识符<filespec)格式化在CS:
5CH和CS:
6CH的两个文件控制块(若在调用DEBUG程序时具有一个文件标识符,则它已格式化在CS:
5CH的文件控制块)。
文件控制块是后面要介绍的Load命令和Write命令所需要的;且能提供所要求的文件名。
(2)能把命令中所打入的文件标认符和别的参数,精确地按照打入的情况(包括定界符),放至自CS:
81H开始的参数保存区中,在CS:
80H中保存输入的字符个数。
在寄存器AX中保存前两个文件标识符中的驱动器标志。
N命令的格式为:
N文件标识符[文件标识符]
若在调用DEBUG程序时,没有规定文件标识符,则必须先用N命令把要调用的文件标识符,格式化到CS;5CH的文件控制块中,才能用Load命令把它调入内存以进行调试。
A>DEBUG
-Nmyprog
-L
-
为了定义正在调试的程序所需要的文件标识符及其他参数,可输入以下命令。
A>DEBUGMYPROG
—Nfile1file2
-
在这种情况下,在调用DEBUG时;就已经把文件MYPROG调人且放在自CS;100H开始的存贮区中;而且此文件的文件控制块已格式化在CS:
5C开始的区域中。
而N命令要格式化file1和file2的文件控制块至CS:
5CH和CS:
6CH处,这样fil