什么是Debug
Debug是DOS、Windows都提供的实模式(8086方式)程序的调试工具。使用它,可以查看CPU各种寄存器中的内容、内存的情况和在及其码级跟踪程序的运行。
Debug的使用
- R命令查看、改变CPU寄存器的内容;
- D命令查看内存中的内容;
- E命令改写内存中的内容;
- U命令将内存中的机器指令翻译成汇编指令;
- T命令执行一条机器指令;
- A命令以汇编指令的格式在内存中写入一条及其指令。
指令详解
R命令:
-r
AX=0000 BX=0000 CX=0000 DX=0000 SP=FFEE BP=0000 SI=0000 DI=0000
DS=138C ES=138C SS=138C CS=138C IP=0100 NV UP EI PL NZ NA PO NC
138C:0100 0000 ADD [BX+SI],AL DS:0000=CD
即查看当前寄存器内容。同时R命令还可以修改寄存器的值,
-r ax
AX 0000
:
可以在:
后面添加需要改变的值,即可修改通用寄存器的值,如
-r ax
AX 0000
:1111
-r
AX=1111 BX=0000 CX=0000 DX=0000 SP=FFEE BP=0000 SI=0000 DI=0000
DS=138C ES=138C SS=138C CS=138C IP=0100 NV UP EI PL NZ NA PO NC
138C:0100 0000 ADD [BX+SI],AL DS:0000=CD
同理,R命令也可以修改段寄存器CX,
-r CS
CS 138C
:1400
-r ip
IP 0100
:1111
-r
AX=0000 BX=0000 CX=0000 DX=0000 SP=FFEE BP=0000 SI=0000 DI=0000
DS=138C ES=138C SS=138C CS=1400 IP=1111 NV UP EI PL NZ NA PO NC
138C:0100 0000 ADD [BX+SI],AL DS:0000=CD
通过这个方法可以用来改变Debug程序的指针。
然后可以通过T命令来执行该指针区间内的指令,可以用D命令来查看当前指针所在内存区间。
但是在本例中,内存为空,使用T命令也不会对命令进行执行,我们可以通过A命令来在此内存空间中添加需要添加的命令。
例如在138C:011F添加代码,
-a
138C:0100 mov ax, 4e20
138C:0103 add ax, 1416
138C:0106 mov bx, 2000
138C:0109 add ax, bx
138C:010B add bx, ax
138C:010D add ax, bx
138C:010F mov ax, 001A
138C:0112 mov bx, 0026
138C:0115 add al, bl
138C:0117 add ah, bl
138C:0119 add bh, al
138C:011B mov ah, 0
138C:011D add al, bl
138C:011F add al, 9c
138C:0121
PS: 注意IP偏移地址的增加,在机器码中,例如
mov ax, 4E20H
的机器码为b8 20 4e
,这时偏移地址增加3,而mov bx, ax
的及其码为89 c3
,偏移地址增加2。
这时通过D命令查看相对应的地址区间,就能查看到你输入代码的机器码及ascii码。
-d 138c:0100
138c:0100 B8 20 4E 05 16 14 BB 00-20 01 D8 89 C3 01 D8 (ASCII 码)
...
使用U命令可以机器指令翻译为汇编指令。
-u 138c:0100
138C:0100 mov ax, 4e20
138C:0103 add ax, 1416
138C:0106 mov bx, 2000
138C:0109 add ax, bx
138C:010B add bx, ax
138C:010D add ax, bx
138C:010F mov ax, 001A
138C:0112 mov bx, 0026
138C:0115 add al, bl
138C:0117 add ah, bl
138C:0119 add bh, al
138C:011B mov ah, 0
138C:011D add al, bl
138C:011F add al, 9c
之后可以用T命令对上面代码进行逐行实现。每实现一条指令,对应IP都会发生改变。
-t
...(-r结果输出)
138C:0100 B8204E MOV AX,4E20
-t
...
139C:0103 051614 ADD Bx,2000
...
另外,还有一点需要注意的是,例如我想查询从FFF00H到FFFFFH区间内的信息,
-d fff0:0 ff
输出为(仅显示最后一行结果):
FFF0:00F0 EA 8A 99 00 F0 30 31 2F-31 39 2F 30 39 20 FC FF .....01/19/09 ..
这时前面展示的是该部分内存的信息地址,即从FFF0开始到00FF结束,中间为16位的代码,右侧是对应的ASC码。这时时间01、19、09是从第5位开始的(因为前面从0开始计数),也就是说16进制第5位30对应着ASC码的0。
这时如果我们想改写这个部分的信息,
-e ffff:05
FFFF:0005 30.48
-e ffff:06
FFFF:0006 31.23
意思为将FFFF:0005的30改写为48
, 下行代码类似。
但是有时会出现改写不了的情况,因为有一些信息如果输入ROM储存器,刻录在主板上,是不能修改的,如本例中一般情况下就无法修改。一般只能修改RAM数据。
-e b810:0 ...
为往现存里写信息,写的内容会直接显示在显示屏上。