debug主要命令详解.docx
《debug主要命令详解.docx》由会员分享,可在线阅读,更多相关《debug主要命令详解.docx(19页珍藏版)》请在冰豆网上搜索。
debug主要命令详解
debug主要命令详解
DEBUG是为汇编语言设计的一种高度工具,它通过单步、设置断点等方式为汇编语言程序员提供了非常有效的调试手段。
一、DEBUG程序的调用
在DOS的提示符下,可键入命令:
C:
\DEBUG[D:
][PATH][FILENAME[.EXT]][PARM1][PARM2]
其中,文件名是被调试文件的名字。
如用户键入文件,则DEBUG将指定的文件装入存储器中,用户可对其进行调试。
如果未键入文件名,则用户
可以用当前存储器的内容工作,或者用DEBUG命令N和L把需要的文件装入存储器后再进行调试。
命令中的D指定驱动器PATH为路径,PARM1和
PARM2则为运行被调试文件时所需要的命令参数。
在DEBUG程序调入后,将出现提示符,此时就可用DEBUG命令来调试程序。
二、DEBUG的主要命令
1、显示存储单元的命令D(DUMP),格式为:
_D[address]或_D[range]
例如,按指定范围显示存储单元内容的方法为:
-d100120
18E4:
0100c70604023801c706-06020002c7060802G...8.G.....G...
18E$:
01100202bb0402e80200-CD20505156578B37..;..h..MPQVW.7
18E4:
01208B
其中0100至0120是DEBUG显示的单元内容,左边用十六进制表示每个字节,右边用ASCII字符表示每个字节,·表示不可显示的字符。
这里没有
指定段地址,D命令自动显示DS段的内容。
如果只指定首地址,则显示从首地址开始的80个字节的内容。
如果完全没有指定地址,则显示上一个
D命令显示的最后一个单元后的内容。
2、修改存储单元内容的命令有两种。
·输入命令E(ENTER),有两种格式如下:
第一种格式可以用给定的内容表来替代指定范围的存储单元内容。
命令格式为:
-Eaddress[list]
例如,-EDS:
100F3'XYZ'8D
其中F3,'X','Y','Z'和各占一个字节,该命令可以用这五个字节来替代存储单元DS:
0100到0104的原先的内容。
第二种格式则是采用逐个单元相继修改的方法。
命令格式为:
-Eaddress
例如,-EDS:
100
则可能显示为:
18E4:
010089.-
如果需要把该单元的内容修改为78,则用户可以直接键入78,再按"空格"键可接着显示下一个单元的内容,如下:
18E4:
010089.781B.-
这样,用户可以不断修改相继单元的内容,直到用ENTER键结束该命令为止。
·填写命令F(FILL),其格式为:
-Frangelist
例如:
-F4BA:
01005F3'XYZ'8D
使04BA:
0100~0104单元包含指定的五个字节的内容。
如果list中的字节数超过指定的范围,则忽略超过的项;如果list的字节数小于指定的范
围,则重复使用list填入,直到填满指定的所有单元为止。
3)检查和修改寄存器内容的命令R(register),它有三种格式如下:
·显示CPU内所有寄存器内容和标志位状态,其格式为:
-R
例如,-r
AX=0000BX=0000CX=010ADX=0000SP=FFFEBP=0000SI=0000DI=0000
DS=18E4ES=18E4SS=18E4CS=18E4IP=0100NVUPDIPLNZNAPONC
18E4:
0100C70604023801MOVWORDPTR[0204],0138DS:
0204=0000
·显示和修改某个寄存器内容,其格式为:
-Rregistername
例如,键入
-RAX
系统将响应如下:
AXF1F4
:
即AX寄存器的当前内容为F1F4,如不修改则按ENTER键,否则,可键入欲修改的内容,如:
-Rbx
BX0369
:
059F
则把BX寄存器的内容修改为059F。
·显示和修改标志位状态,命令格式为:
-RF系统将响应,如:
OVDNEINGZRACPECY-
此时,如不修改其内容可按ENTER键,否则,可键入欲修改的内容,如:
OVDNEINGZRACPECY-PONZDINV
即可,可见键入的顺序可以是任意的。
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]
该命令允许键入汇编语言语句,并能把它们汇编成机器代码,相继地存放在从指定地址开始的存储区中。
必须注意:
DEBUG把键入的数字均看成
十六进制数,所以如要键入十进制数,则其后应加以说明,如100D。
7)反汇编命令U(Unassemble)有两种格式。
·从指定地址开始,反汇编32个字节,其格式为:
-U[address]
例如:
-u100
18E4:
0100C70604023801MOVWORDPTR[0204],0138
18E4:
0106C70606020002MOVWORDPTR[0206],0200
18E4:
010CC70606020202MOVWORDPTR[0208],0202
18E4:
0112BBO4O2MOVBX,0204
18E4:
0115E80200CALL011A
18E4:
0118CD20INT20
18E4:
011A50PUSHAX
18E4:
011B51PUSHCX
18E4:
011C56PUSHSI
18E4:
011D57PUSHDI
18E4:
011E8B37MOVSI,[BX]
如果地址被省略,则从上一个U命令的最后一条指令的下一个单元开始显示32个字节。
·对指定范围内的存储单元进行反汇编,格式为:
-U[range]
例如:
-u10010c
18E4:
0100C70604023801MOVWORDPTR[0204],0138
18E4:
0106C70606020002MOVWORDPTR[0206],0200
18E4:
010CC70606020202MOVWORDPTR[0208],0202
或
-u100112
18E4:
0100C70604023801MOVWORDPTR[0204],0138
18E4:
0106C70606020002MOVWORDPTR[0206],0200
18E4:
010CC70606020202MOVWORDPTR[0208],0202
可见这两种格式是等效的。
8)命名命令N(Name),其格式为:
-Nfilespecs[filespecs]
命令把两个文件标识符格式化在CS:
5CH和CS:
6CH的两个文件控制块中,以便在其后用L或W命令把文件装入存盘。
filespecs的格式可以是:
[d:
][path]filename[.ext]
例如,
-Nmyprog
-L
-
可把文件myprog装入存储器。
9)装入命令(Load),有两种功能。
·把磁盘上指定扇区范围的内容装入到存储器从指定地址开始的区域中。
其格式为:
-L[address[drivesectorsector]
·装入指定文件,其格式为:
-L[address]
此命令装入已在CS:
5CH中格式化了文件控制块所指定的文件。
如未指定地址,则装入CS:
0100开始的存储区中。
10)写命令W(Write),有两种功能。
·把数据写入磁盘的指定扇区。
其格式为:
-Waddressdrivesectorsector
·把数据写入指定的文件中。
其格式为:
-W[address]
此命令把指定的存储区中的数据写入由CS:
5CH处的文件控制块所指定的文件中。
如未指定地址则数据从CS:
0100开始。
要写入文件的字节数应
先放入BX和CX中。
11)退出DEBUG命令Q(Quit),其格式为:
-Q
它退出DEBUG,返回DOS。
本命令并无存盘功能,如需存盘应先使用W命令。
问题:
初学者问一个低级问题,执行debug-a后,如果有一行输入错误,如何更改这一行?
回答:
加入进行如下输入:
D:
\PWIN95\Desktop>debug
-a
2129:
0100movax,200
2129:
0103movbx,200
2129:
0106movcx,200
2129:
0109
此时,发现movbx,200一句错误,应为movbx,20,可以敲回车返回"-"状态,然后输入:
-a103
2129:
0103movbx,20
如果多或者少若干行,不必重新输入,可以用M命令移动后面的程序来去掉或者增加程序空间。
如何除错和汇编你的第一个PCx86汇编语言程序呢?
以下这些简单的解释可以让一个汇编语言新手使用DEBUG:
0)在使用时,如何快速获得debug的使用帮助呢。
1)让我们开始工作吧,例如:
显示BIOS的日期。
2)在你的电脑的COMMANG.COM文件里搜寻"IBM"这几个字符。
3)一位十六进制数的运算。
4)检查x86寄存器内容。
5)我们来编写我们的第一个用机械语言编写的程序-打印一个字符。
6)我们现在用汇编语言指令来做和例5一样的事情。
7)现在,我们不但要编写一个汇编程序,而且我们还要把它存盘。
8)现在,我们试一试查看一个已经编好的程序。
9)你可以用DEBUG的计算功能计算程序的长度。
10)另一种显示在屏幕上字符串的方法。
11)让我们试一试反复输出。
12)我们现在把两个程序连接起来。
13)让我们逐步运行这个刚刚修补的程序。
14)如果一开始的命令不是跳转命令,那么可能就要用这种方法了。
以下所有的命令都是可以运行在WIN9x的MS-DOS方式下的。
进入MS-DOS的方式有:
[开始][程序][MS-DOS方式]
[开始][运行][打开]COMMAND[确定]
或者你可以双击它:
C:
\Windows\C
0)在使用时,如何快速获得debug的使用帮助呢
以下PROMPT>表示目录提示符:
一般为:
C:
\WINDOWS\COMMAND\
PROMPT>DEBUG/?
<按回车presstheenterkeynow>
怎样?
出错了吧。
显示如下
C:
\WINDOWS>DEBUG/?
RunsDebug,aprogramtestingandeditingtool.
DEBUG[[drive:
][path]filename[testfile-parameters]]
[drive:
][path]filenameSpecifiesthefileyouwanttotest.
testfile-parametersSpecifiescommand-lineinformationrequiredby
thefileyouwanttotest.
AfterDebugstarts,type?
todisplayalistofdebuggingcommands.
因为错了所以它给你显示一些提示。
留意到最后一句了吗?
现在我们再来试一试:
PROMPT>DEBUG<按回车>(注意,DEBUG程序的命令是在一条横线"-"后出现的。
)
-?
<在出现的横线后面输入?
再回车>(下面的内容是按字母顺序排列的)
(注意:
Note:
Don'ttypethedashorcomments--justthe?
)
显示如下,但是没有中文的哦,中文是我加上去的。
汇编assembleA[address]
比较compareCrangeaddress
倾倒dumpD[range]
进入enterEaddress[list]
填充fillFrangelist
进行goG[=address][addresses]
十六进制hexHvalue1value2
输入inputIport
装载loadL[address][drive][firstsector][number]
移动moveMrangeaddress
命名nameN[pathname][arglist]
输出outputOportbyte
进行proceedP[=address][number]
离开quitQ
纪录registerR[register]
搜寻searchSrangelist
描述traceT[=address][value]
反汇编unassembleU[range]
写writeW[address][drive][firstsector][number]
分配扩展内存allocateexpandedmemoryXA[#pages]
释放扩展内存deallocateexpandedmemoryXD[handle]
mapexpandedmemorypagesXM[Lpage][Ppage][handle]
displayexpandedmemorystatusXS
-q<按回车>(这是退出DEBUG回到DOS状态)Thisquitsoutofdebug,returningtotheDOSprompt)
Testedexamplesbelowwalktheuserthruthefollowingdebugexamples:
在下面的例子里读者必须明白以下几条DEBUG命令。
-D显示一定范围内存的内容Displaythecontentsofanareaofmemory
-Q退出DEBUG程序Quitthedebugprogram
-S搜寻Searchforwhatever
-H十六进制的运算Hexarithmatic
-R显示或者改变一个或者多个寄存器的内容Displayorchangethecontentsofoneormoreregisters
-E输入数据进入内存,在一个详细的地址里Enterdataintomemory,beginningataspecificlocation
-G运行现在在内存里的程序。
Goruntheexecutableprograminmemory
-U反汇编,把我们不认识的机械代码变为我们可以认识汇编语言符号Unassemblemachinecodeintosymboliccode
-T描述一条指令的用法。
Tracethecontentsofoneinstruction
-P进行或者执行一个相关的指令Proceed,orexecuteasetofrelatedinstructions
-A编译,把汇编命令变为机械代码Assemblesymbolicinstructionsintomachinecode
-N命名一个程序Nameaprogram
-W把一个已经命名的程序写进磁盘Writethenamedprogramontodisk
-L把程序装载进内存Loadthenamedprogrambackintomemory
1)让我们开始工作吧,例如:
显示BIOS的日期
(以下PROMPT>表示目录提示符:
一般为:
C:
\WINDOWS\COMMAND\)
PROMPT>DEBUG<按回车>
-DFFFF:
0006L8<按回车>(显示FFFFh,偏移地址6h,长度8bytes)
在作者的电脑上这里显示为"1/10/96."
译者的电脑显示"FFFF:
0000372F-30362F3030007/06/00."相信作者的电脑里也是用这种格式显示的。
这里显示出来的是使用者BIOS的
日期,有兴趣的话可以重新开机看看,注意开机时的显示。
-Q<按回车>(退出DEBUG)
思考:
当只按DEBUG的时候,编辑的是什么?
为什么可以找到BIOS的日期?
(译者这里也不是很清楚所以请大家知道的也留言给斑竹,改正。
译
者认为可能是内存的真实物理地址。
)
2)在你的电脑的COMMANG.COM文件里搜寻"IBM"这几个字符
下面的"C:
\Win95\"是根据每不电脑不同的。
像译者的电脑里就是"C:
\WINDOWS"
PROMPT>DEBUGC:
\Win95\C<按回车>
-S0LFFFF"IBM"<按回车>(从0开始搜寻"IBM",搜寻FFFFh多个单元格)
-Q<按回车>(退出DEBUG)
以下是译者做的:
C:
\WINDOWS>DEBUGC:
\WINDOWS\COMMAND.COM
-S0LFFFF"IBM"
-S0LFFFF"COMMAND"
12A7:
008D
12A7:
04F7
12A7:
3870
12A7:
38BE
12A7:
38DD
-S0LFFFF"PATH"
12A7:
38AD
12A7:
CCB7
12A7:
CF55
-S0LFFFF"COMSPEC"
12A7:
38D4
12A7:
3A4D
12A7:
CCC4
-Q
C:
\WINDOWS>
(注意:
搜寻是要区分大小写的)
(你可以看到上面是没有找到"IBM"的,可以试一试"PATH","COMSPEC","COMMAND")
(注意:
这种方法用在查找加密资料和已被删除的资料等方面时是十分有用的)
返回目录
3)一位十六进制数的运算:
PROMPT>DEBUG<按回车>
-H91<按回车>(加减两个十六进制的数,9h+1h=Ah&9h-1h=8h)
结果是显示:
000A0008
-Q<按回车>(退出DEBUG)
C:
\WINDOWS>debug
-h91
000A0008
-q
C:
\WINDOWS>
返回目录
4)检查x86寄存器内容
PROMPT>DEBUG<按回车>
-R<按回车>(显示x86寄存器内容)
-Q<按回车>(退出DEBUG)
C:
\WINDOWS>debug
-R
AX=0000BX=0000CX=0000DX=0000SP=FFEEBP=0000SI=0000DI=0000
DS=127CES=127CSS=127CCS=127CIP=0100NVUPEIPLNZNAPONC
127C:
0100043CADDAL,3C
-Q
下面是对寄存器的简单介绍:
数据存储器
在本类中,一般讲的AH就是AX的前八位,AL就是AX的后八位,后面的以此类推。
AXAccumulator;作为累加器,所以它是算术运算的主要寄存器。
另外所有的I/O指令都使用这一寄存器与外部设备传送信息。
BXBaseregister;可以作为通用寄存器使用,此外在计算存储器地址时,它经常用作基地址寄存器。
CXCountingregister;可以作为通用寄存器使用,此外在循环(LOOP)和串处理指令中作隐含的计数器。
DXDataregister;可以作为通用寄存器使用,一般在作双字长运算时,把DX和AX组合在一起存放一个双字长数,DX用来存放高位字。
此外,
对某些I/O操作,DX可用来存放I/O的端口地址。
指针及变址寄存器
BPBasepointersregister;机制指针寄存器
SISourceindexregister;堆栈指针寄存器
DIDestinyindexregister;目的变址寄存器
SPBatterypointerregister;堆栈指针寄存器
段寄存器
CSCodesegmentregister;代码段寄存器,存放正在运行的程序指令
DSDatasegmentregister;数据段寄存器,存放当前运行程序所用的数据
SSBatterysegmentregister;堆栈段寄存器,定义了堆栈所在区域
ESExtrasegmentregister;附加段寄存器,存放附加的数据,是一个辅助性的数据区,
控制寄存器
IPNextinstructionpointerregister;指令指针寄存器,它用来存放代码段中的偏移地址,在程序运行的过程中,它始终指向下一条指令
的首地址,它与CS寄存器联用确定下一条指令的物理地址
FFlagregister;标志寄存器"NVUPEIPLNZNAPONC"就是了,也有人称之为PSWProgramStatusWold程序状态寄存器
(这里有一点必须讲明白的现在在,其实从奔腾开始这些寄存器(除了所有段寄存器,标志寄存器)都是32位的。
并且加多了两个16位段寄存器
FS,GS。
dos下面看到这些寄存器是16位的。
要看32位寄存器可以使用soft-ice。
对于FS,GS的作用我也不是很清楚,希望有高手指点,谢谢。
)
5)我们来编写我们的第一个用机械语言编写的程序-打印一个字符
(这里用机械语言的主要原因是考虑到有一些用户不懂汇编命令,现在就要让他有一个认识计算机程序实质是一些数字)
PROMPT>DEBUG<按回车>
-E100<按回车>(在偏移地址为100的地方输入机械指令程序)
B4<按空格>02<按空格>(在AX寄存器的前八位存入02)
B2<按空格>41<按空格>(在DX寄存器的后八位存入41h,41h就是大写A的ASCII码,身边有ASCII表的朋友可以对着表改改数字试一试)
CD<按空格>21<按空格>(当AH=02时这是DOS显示输出的中断号)
CD<按空格>20<按回车>(退出DOS)
-G<按回车>(程序运行,并在屏幕上显示出"A")
程序运行完以后你将看到"Programterminatednormally"(程序正常结束了).
-U100<按回车>(我们把它反汇编,就是把机械命令变为汇编语言指令)
107F:
0100B402MOVAH,02
:
0102B2MOVDL,41
:
0104CD21INT21
:
0106CD20INT