现在的位置: 首页 > 综合 > 正文

DEBUG的基本知识

2013年09月17日 ⁄ 综合 ⁄ 共 6158字 ⁄ 字号 评论关闭

DEBUG是基于命令行的16位调试器,可作为16位汇编语言程序的调试工具,但不支持32位指令。

一.进入DEBUG

DEBUG对应的可执行文件为debug.exe。启动DEBUG的命令格式为:

    DEBUG[<可执行文件路径名>[<参数表>]]

其中,<可执行文件路径名>是要调试的可执行文件名(.exe或.com文件),扩展名不能省略。<参数表>是被调试程序所需的命令行参数。例如,键入命令

    DEBUG demo.exe

将进入DEBUG,同时将指定的程序demo.exe装入内存,以便调试。

若启动DEBUG时未给出文件名,则仅运行DEBUG。需要时,可用N和L命令装入被调试程序。

进入DEBUG后,出现提示符“-”。若启动DEBUG时给出文件名,则BX:CX包含被调试文件的字节数。在DEBUG提示符下,可使用DEBUG命令。

二.DEBUG命令格式

DEBUG的每个命令都是一个字母,后跟一个或多个参数。下面对DEBUG命令作几点说明。

·字母不分大小写。

·只使用16进制数,且不能带后缀H。

·以空格或逗号作为命令各项之间的分隔符。分隔符只在两个数值之间是必须的。

·可以用Ctrl-C或Ctrl-Break终止命令的执行。

·若输入的命令有语法错误,则提示“Error”,并用“^”指出错误位置。

三.DEBUG命令的参数

在DEBUG中,许多命令的参数是〈地址〉和〈地址范围〉。〈地址〉的格式包括下列两种:

·〈段地址〉:〈偏移地址〉;

·〈偏移地址〉。

其中,〈段地址〉可以是数值或段寄存器,〈偏移地址〉是数值。若未指定〈段地址〉,则采用命令的缺省值。与数据有关的命令D、E、C和F等,缺省段地址为DS的值;与代码有关的命令A、U、G、T和P等,缺省段地址为CS的值。例如:

2000:1000;段地址为2000H,偏移地址为1000H

DS:2000  ;段地址为DS的值,偏移地址为200H

200       ;段地址为所在命令的缺省值(CS或DS),偏移地址为200H

〈地址范围〉用来表示一个内存区域,包括下列两种格式:

·〈开始地址〉〈结束地址〉;

·〈开始地址〉L〈长度〉。

其中,〈结束地址〉不能带段地址,〈长度〉表示字节数,且指定的地址范围不跨段。例如,内存区域2000:1000H到2000:1010H可表示为

2000:1000 1010

2000:1000 L 11

.DEBUG命令

在DEBUG提示符下,使用帮助命令“?”,可以显示DEBUG命令列表。在众多DEBUG命令中,较常用的命令是U、D、E、R、G、T、P和Q。

1.内存显示命令(Dump Command)

D命令用来显示内存单元的值,包括下列两种格式:

(1)D[<地址>]

显示由指定地址开始的若干内存单元值。对于80列显示模式,显示128个字节。如果未指定参数,则按一个D命令的结束地址开始显示。若前面未用过D命令,则缺省从CS:IP开始显示。

(2)D<地址范围>

该命令显示由<地址范围>指定的所有内存单元的值。

执行D命令后,屏幕左边显示的是内存地址,中间是从该地址开始的若干字节值(十六进制),右边是每个字节对应的ASCII字符,其中,“.”表示不可打印字符。

若只给出偏移地址,则使用DS当前值作为段地址。例如:

D 2000:100               ;显示从2000:0100H开始的内存单元值

D 100                    ;显示从DS:100H开始的内存单元值

D CS:100                 ;显示从CS:100H开始的内存单元值

D                        ;显示从CS:IP开始的内存单元的值

2.内存修改命令E(Enter Command)

E命令用来设置指定内存单元的值,包括下列两种格式:

(1)E<地址>;

(2)E<地址><字节表>。

若只给出偏移地址,则使用DS当前值作为段地址。

第一种格式以交互方式逐个修改连续的内存单元。键入该命令后,DEBUG显示指定地址及相应内存单元的值,等待用户修改。此时,可以采用下列操作:

·输入一个新的值;

·键入空格跳到下一个地址单元;

·输入“_”返回上一个地址单元;

·按回车键结束E命令。

第二种格式用<字节表>来修改从指定地址开始的内存区域。DEBUG将这些值依次写入开始于指定地址的连续内存单元。其中,<字节表>是以空格或逗号分隔的若干十六进制字节或字符串。例如:

E 0 1'123'0A             ;将内存单元DS:0--DS:4的值设置为01H、31H、32H、33H、0AH

注意:E命令后必须指定内存地址

3.寄存器命令R(Register Command)

R命令用来显示和修改寄存器的值,包括以下两种格式。

(1)R

显示所有寄存器和8个标志位的值,并反汇编CS:IP所指的指令。

(2)R<寄存器名>

显示指定寄存器的值,并等待用户键入新的值,按回车键结束R命令。其中,<寄存器名>只能是8086的16位寄存器AX、BX、CX、DX、SP、BP、SI、DI、DS、ES、SS、CS、IP与F(标志寄存器)。

显示的8个标志位的符号分别为(0/1):OF=NV/OV,DF=UP/DN,IF=DI/EI,SF=PL/NG,ZF=NZ/ZR,AF=NA/AC,PF=PO/PE,CF=NC/CY。例如,命令

    R F

将显示8个标志位的值,然后等待用户修改。只要输入这些符号就可以设置对应标志位的值,键入符号的个数与顺序可以任意。

4.汇编命令A(Assemble Command)

命令的格式为:

  A[<地址>]

该命令的功能是将用户输入的汇编语言指令汇编为机器代码,存入指定地址开始的内存单元。

若只给出偏移地址,则使用CS当前值作为段地址。若未指定地址,则从一个A命令的最后一个单元开始;若前面未用过A命令,则缺省为CS:IP。

当执行A命令时,DEBUG等待用户输入指令序列。输入每条指令后回车,再直接按回车键结束A命令。DEBUG将输入指令序列的机器码存入指定地址开始的内存单元中。

使用A命令时,要注意以下几点。

·远返回的助记符为RETF。

·除了汇编语言指令外,还可以使用伪指定DB和DW,将字节或字送入相应的内存单元。然而,DB和DW后不能使用“?”、表达式或DUP子句等。

·不能使用符号地址。

·为了区分立即数与内存操作数,地址必须放在方括号([])中。例如:

    MOV  AX,1234           ;立即数送AX

    MOV  AX,[1234]         ;内存单元的值数送AX

·段超越前缀要在相关指令前或单独一行输入。例如,指令

    MOV  AX,ES:[100H]

在DEBUG中的正确形式为:

    ES:MOV  AX,[100]

或者

    ES:

    MOV     AX,[100]

5.反汇编指令U(Unassemble Command)

U命令用来将二进制代码反汇编为汇编语言的符号指令,包括下列两种格式。

(1)U[<地址>]

从指定地址开始,反汇编若干字节。对于80列模式,反汇编32个字节(为了保证最后一条指令的完整性,可能会多于32个字节)。若未指定地址,则从上一个U命令的最后一个单元开始;若前面未用过U命令,则缺省为CS:IP。

(2)U[<地址范围>]

对指定范围的内存区进行反汇编。若只给出偏移地址,则使用CS当前值作为段地址。

执行U命令后,屏幕左边显示的是内存地址,中间是机器代码,右边是对应的汇编语言指令。

6.运行命令G(Go Command)

G命令的格式为:

     G[=<地址>][<断点地址1><断点地址2>···<断点地址10>]

其中,等号“=”后的<地址>指出程序执行的饿起始地址,如未指定,则缺省为CS:IP。指定的断点最多为10个,也可以没有。若只给出偏移地址,则使用CS当前值作为段地址。

G命令从指定地址开始执行内存中的程序,直到程序结束或遇到指定的任一断点时停止执行。若遇到断点,则显示所有寄存器和标志位的当前值以及要执行的下一条指令;若程序正常结束,则显示“Program terminated normally”。

说明:

·断点地址的次序是任意的。设置多个断点的好处在于当被调试程序有多条可能的执行路径时,使其不管沿哪个路径执行,都有可能在断点处停下来,以便检查程序的执行情况。

·断点一经设定,DEBUG用一条INT3指令取代断点处指令的操作码。当程序执行到一个断点地址时,立即停止,然后恢复所有断点处的指令,并取消全部断点,返回DEBUG。如果设置的断点在G命令的执行过程中均未遇到,则程序执行完毕,不会恢复断点处的指令。

·一旦程序执行完毕,若想再次执行,必须重新装入。

·对于G以及下面介绍的T与P命令,等号“=”后的<地址>所指单元,必须是有效的8086指令代码,否则,会产生预想不到的结果。

7.跟踪命令T(Trace Command)

T命令的格式为:

    T [=<地址>][<指令条数>]

其中,等号“=”后的<地址>指出程序执行的起始地址,如未指定,则缺省为CS:IP。若只给出偏移地址,则使用CS当前值作为段地址。

T命令从指定地址开始单步执行,执行的指令数有<指令条数>决定。每条指令执行后,都要显示所有寄存器和标志位的值以及下一条指令。若未给出<指令条数>,则缺省为1。

T命令执行时,若遇到CALL或INT指令,会跟踪进入相应过程或中断服务程序内部。对于带重复前缀(如REP)的指令,每次重复执行算一步。

8.继续命令P(Proceed Command)

P命令的格式为:

   P [=<地址>][<指令条数>]

P命令类似于T命令,但将CALL、INT或带重复前缀(如REP)指令的执行当作一步,不会跟踪进入相应过程或中断服务程序内部。

9.退出命令Q(Quit Command)

Q命令的格式为:

    Q

使用此命令可退出DEBUG。

10.内存比较命令C(Compare Command)

C命令用来比较两个内存块的值,格式如下:

    C<地址范围><地址>

其中,<地址范围>指出第一个内存块,<地址>指出第二个内存块的起始地址。比较的字节数由<地址范围>确定。若只给出偏移地址,则使用DS当前值作为段地址。

C命令依次比较两个内存块的每个字节。若两块相等,则不输出任何信息;若发现有不相等的字节,则显示出它们的地址和值。屏幕从左到右的依次是:第一个内存块地址与相应的值、第二个内存块的值及其地址。例如:

    C 2000:0 100 80                 ;比较内存块2000:0H--2000:100H与DS:80H--DS:180H

    C 2000:0 L 20 3000:0            ;比较内存块2000:0H--2000:1FH与3000:0H--3000:1FH    

11.内存填充命令F(Fill Command)

F命令的格式为:

   F<地址范围><字节表>

用此命令可将<字节表>中的字节写入<地址范围>所指定的内存区域。若只给出偏移地址,则使用DS当前值作为段地址。

若<字节表>中的字节数超过<地址范围>的字节数,则忽略多余的字节;若<字节表>中的字节数少,则重复使用这些数据,直到填满指定的<地址范围>为止。例如:

    F 2000:0 7 0          ;将2000:0000H--2000:0007H的8个字节均置为0

    F 0 7 1 2 3           ;将DS:0000H--DS:0007H的8个字节依次置为1、2、3、1、2、3、1、2

12.内存传送命令M(Move Command)

M命令用来将一个内存区的数据(或代码)复制到另一个内存区。格式如下:

    M<地址范围><地址>

其中,<地址范围>指出要复制的源内存块,<地址>作为目的内存块的起始地址,复制的字节数由<地址范围>确定。若只给出偏移地址,则使用DS当前值作为段地址。

例如:

M 2000:0 100 80       ;复制内存块2000:0H--2000:100H的值到DS:80H--DS:180H

M 2000:0 L 20 3000:0  ;复制内存块2000:0H--2000:1FH的值到3000:0H--3000:1FH

如果源块与目的块重叠,DEBUG也能正确处理。

13.搜索命令S(Search Command)

S命令用来在指定的内存区域内搜索特定字节串。格式如下:

    S<地址范围><字节表>

若只给出偏移地址,则使用DS当前值作为段地址。若未找到所需的字节串,则不显示任何信息;否则,显示其每次出现的地址。

14.十六进制数计算命令H(Hex Command)

H命令的格式为:

    H<数值1><数值2>

计算两个十六进制(16位)的和与差。

15.文件命名命令N(Name Command)

N命令的格式为:

    N[驱动器][路径]文件名[.扩展名]

此命令将指定的文件路径名存入DEBUG的文件控制块FCB中,以便后面用L或W命令把文件装入或存盘。<参数表>给出可执行文件运行时的命令行参数。例如,下列命令

DEBUG        ;启动DEBUG

N Filename

L

相当于

DEBUG Filename

16.装入命令L(Load Command)

L命令用来将一个文件或磁盘指定扇区的内容装入内存,包括下列两种格式。

(1)L[<地址>]

将已用N命令的文件装入到指定内存单元,并将BX:CX设置为装入文件的字节数。对于可执行文件.EXE或.COM,通常不指定装入内存,由DEBUG分配,装入后自动设置CS:IP,一般IP为0(.EXE文件)或100H(.COM文件)。若指定地址,则可执行文件的装入地址必须是CS:100H。

(2)L<地址><驱动器号><起始逻辑扇区号><扇区数>

将磁盘的若干扇区(最多80H)装入到指定的内存地址。若只给出偏移地址,则使用CS当前值作为段地址。其中,0表示A盘,1表示B盘,2表示C盘,依此类推。例如,将C盘引导扇区(逻辑扇区号为0)的内容装入到内存地址为CS:0,然后查看,可用下列命令:

L 0 2 0 1

D CS:0

17.写盘命令W(Write Command)

W命令包括两种格式。

(1)W[<地址>]

将指定地址开始的BX:CX个字节写入已由N命令命名的文件中。若只给出偏移地址,则使用CS当前值作为段地址。若未指定地址,则缺省为CS:100H。

注意,在执行W命令前,必须正确设置BX和CX的值。另外,不能写入.EXE文件,因为.EXE文件必须以特定的格式才能写入,DEBUG不支持这种写入方式。

(2)W<地址><驱动器号><起始逻辑扇区号><扇区数>

将指定内存地址的数据写入磁盘的若干扇区(最多80H个)中。若只给出偏移地址,则使用CS当前值作为段地址。各参数的含义同L命令。

第二种格式的W命令直接将数据写入指定扇区,使用时一定要小心,否则会破坏磁盘上的文件系统乃至引导扇区。

18.端口输入命令I(Input Command)

I命令的格式为:

    I<端口地址>

此命令从指定的I/O端口读入一个字节并显示。

19.端口输出命令O(Output Command)

O命令的格式为:

    O<端口地址><字节>

用于输出一个字节到指定的I/O端口。

抱歉!评论已关闭.