这可能是最详细的 Windows Debug 详解 了

admin | 世界杯足球赛事

Debug概览

Debug是什么?

debug是Windows 16位或者32位机器上的一款调试工具。也就是说,在WindowsXP及以前的机器上都有debug,直接Win+X debug就可以调出;在之后的32位机也有;但是在之后的64位机器上不存在,即使有,也无法运行。不必尝试到底能不能运行,绝对不能相似的,微软的masm也无法在64位版本的系统上运行。可以通过安装dosbox来虚拟一个DOS环境或者使用WindowsXP(虚拟机即可)的方式来使用debug和masm。

debug的作用是什么?如何打开debug?

顾名思义 - 用来调试的工具。debug有极为丰富的命令支持,灵活、高效。debug的调试不同于IDE的调试 - 虽然都支持下断点的方式,但是debug能够直接查看CPU寄存器的内容,甚至能够在程序运行过程中修改自身代码 - 这是IDE望尘莫及的。打开debug的方式:Win + X呼出运行窗口,输入cmd,然后输入debug回车就行了。进入debug后,命令提示符会变成“-”,如下图。 但是一般来说不使用系统的debug进行实验以防止无意中损坏系统,一般来说使用单独分离出来的debug进行实验,以获得更高的安全性和更完整的功能体验。Debug下载链接在文末,与masm同打包 调用时在cmd中cd到存放debug.exe的文件夹,输入debug并回车就可以了。或者在当前文件夹编写一个bat,内容为字母cmd,撒谎及运行可以达到同样的效果。

使用DEbug时你必须知道的几点

0.所有数据都是10进制,除非有别的进制的符号修饰(如50h)

1.range 表示范围,不同指令默认段有所不同。均可以适用类似 CS:0100L2的形式表示范围

2.不能使用符号常量和符号地址.(就是说不能用变量和指针)

3.不能使用绝大部分伪指令,但两个最常用的伪指令 DB 和 DW 能被使用,用于直接把字节和字数据置入相应存储单元。如: DB 1,2,3,4,“ABCD” DW 1234,5678

Debug用法

参数一览表

命令含义用法Aassemble在内存中直接编写代码CCompare比较内存DDump查看内存内容EEnter修改内存内容FFull填充内存GGo执行代码HHexarithmetic以16进制进行数学运算IInput从某个端口输入一个16进制并显示Lload把文件或者绝对扇区内容读入内存Mmove数据传递(不同于汇编的move)Nname为读写磁盘文件定义文件名Ooutput把指定字节发送到制定端口Qquit结束debug程序RRegister寄存器命令SSearch按照list清单查找内存range范围Ttrack追踪命令UUNassemble反汇编内存中的指令Wwrite把调试过的信息写到磁盘上?Help获取帮助信息,即现实所有支持的命令

详解

0.启动Debug的参数

启动形式:Debug [完整路径][文件名][.exe][exe的参数1][exe的参数2]

其中,方括号内的内容为可选值。若载入了一个文件(注意,不一定是exe,也有可能是转储文件),则载入的位置是CS指向的位置,偏移量为0

如果输入文件名 filename,那么 DEBUG 就把所指定的文件装入内存,然后可以输入命令来修改、显示或执行指定文件的内容。如果不输入文件名 filename,那么或使用当前存储器的内容进行工作,或使用命名命令 Name 和装入命令 Load 把需要的文件或者准确的磁盘扇区装入存储器中,然后可以输入命令来修改、显示或执行存储器的内容。

1.汇编指令A(assemble)

作用:键入汇编指令,并把它们汇编成机器代码,相继存放在从指定地址开始的存储区中。形式:A[address] (A与addr有无空格均可) , A [基址寄存器:][偏移] (有无空格均可)

汇编指令有以下两种格式:

a ;从上次停下的地方继续输入汇编指令(上次a指令停下的地方)

a 开始地址 ;从起始位置开始编写汇编代码(举例:A CS:1100 ,即为从cs:1100的地方开始编写汇编代码)

2.比较指令C(compare)

作用:比较两个数据块的内容

格式: C range addr , 其中range为第一个数据块的起始地址加长度(用以构成数据块),如果不写段寄存器,默认DS,第二个只写目标地址,不写段寄存器默认DS

如果找到不相等的字节,则用下列形式显示地址和内容: addr1 byte1 byte2 addr2 此处,前一半(即 addr1 byte1)说明 range 内不相等单元的位置和内容,后面的一半指的是在 address 中找到的不相等的内容和位置。

举例:

C 100L20 200 把 DS:100 开始的存储器的 32 个字节同从 DS:200 开始的 32 个字节进行比较。

C表示比较指令,100表示起始地址,没有写段所以默认DS

L表示段长度,20是十六进制,换下来是32字节

3.显示内存指令D(Dump)

作用:显示存储器内容(16进制)格式:D [addr] 或 D [range] , 有无空格均可。详细:

D DS:1100 ;从DS:1100开始显示D ;从上次停下的位置开始显示D 0100 ; 没有段寄存器,默认DSD [addr]L[size] ;从addr处开始显示size(16进制)个字节的数据,addr含义同1 - 3D [start_addr] [end_addr] ;从start_addr 显示到end_addr

4.修改内存指令E(enter)

作用:修改内存的值

形式:E addr [list]

不存在list时:显示addr的内容,并等待输入一个16进制数以替换之数据段默认DS

存在list时:使用list的内容填充addr之后list长度的内存的内容

eg:E DS:1000 f3 ‘xyz’ d8 ;使用f3 x y z d8 五个字节的内容替换DS:1000 到 DS:1004的内容

例如: E address 现在可以开始下列操作:  输入一个或两个十六进制值的字符去替换字节的内容,然后采取下面操作之一。  按空格步进到下个地址,并显示其内容。如果希望改变其内容就采取上述第一条操作。  输入连字符“—”退回到前一个地址,并显示其内容。如果希望改变其内容则采取上述第一条操作。  为了退回一个以上的字节且不改变当前字节,应输入另一个连字符。  为了结束 E 命令,按 ENTER 键。 例如: E cs:100 可以得到如下显示内容: 04BA:0100 EB._ 为了把 04BA:0100 内容由 EBH 改变成 41H,则输入 41: 04BA:0100 EB.41 为了查看下三个单元的内容,按三次空格,屏幕显示出: 04BA:0100 EB.41 10.00.BC._ 为了把当前单元(04BA:0103)由 BCH 改成 42H,应输入 42: 04BA:0100 EB.41 10.00.BC.42 如果要退回并把 10H 改成 6FH,则按两次连字符和输入置换的字节之后,屏幕上显示: 04BA:0100 EB.41 10.00.BC.42 04BA:0102 00._ 04BA:0101 10.6F 按 ENTER 键结束输入命令,将会看到提示符为连字符“—”。

5.内存填充指令F(Fill)

用清单中的内容填充range范围内存形式: F range list说明:如果清单中包含的字节数小于地址范围,则重复地使用该清单,直到把所指定范围内的存储器单元填满为止。如果清单中包含的字节数大于地址范围,就忽略不计超过的部分。 例如: F4BA:100 L 5 F3‘XYZ’8D 用指定的 5 个字节填写到内存的 04BA:100 到 04BA:104 单元中。注意,存储清单字符是 ASCII 字符码,因此 100—104 单元中为 F3 58 59 5A 8D。

6.执行命令G(Go)

作用:执行正在调试的程序。当达到所指定的断点地址处时,就停止执行,并显示寄存器、标志位以及下一条要执行的指令。断点在Track部分。格式:G[=addr][断点1][断点2][断点n]…不指定=addr参数时,从CS:IP开始执行

7.十六进制运算指令H (Hexarithmetic)

作用:先把两个十六进制的值相加,然后第一个值减去第二个值。在一行上显示和与差。

格式:格式:H value value

例如: H 0F 8 17 07 000F 和 0008 的 16 进制和是 0017,而其差是 0007

8.输入指令I(Input)

从指定的端口输入并显示

格式:I portnum

例如:

- I 2F8

6B 显示由 02F8 端口读入的一个十六进制字节数(6BH)。

9.载入指令L(load)

作用:把制定的文件或绝对扇区装入内存。

形式1:L [addr][driver][起始扇区][载入的扇区数量]

例如: L 4BA:100 1 OF 6D 从驱动器 B 的盘上装入数据,并把数据存放在以 4BA:100 开始的内存中。从相对扇区 0FH

驱动器以 1 2 3等区分

形式2:L 或者 L [addr] ;载入已经由N命令指定的文件。默认CS:100 文件需在当前文件夹下

N file_test

L ;载入到CS:100

L CS:1000 ;载入到指定的内存位置 CS:1000

说明:用单个 Load 命令可装入的最大扇区数是80H。如果出现读盘错,则 DEBUG 显示出错信息。

10.传送指令M(move)

作用:复制指定内存块的内容到另一内存块

形式:M range addr ;复制range的内容到addrrange内存块内容不变

例如: M CS:100 110 500 把 CS:100 到 CS:110 的 17 个字节的数据,传送到以 DS:500 开始的内存区中。

11.命名指令N(name)

作用:为读写磁盘文件定义文件名格式:N [name1][name2….]说明:如果在无文件说明时启动 DEBUG,在用 L 命令装入文件之前,必须使用 Name 命令。

12.输出指令O(output)

作用:向端口发送数据

格式:O portNum byte

例如:为了把字节值 4F 发送到输出端口 2F8,输入: O 2F8 4F

13.退出命令Q(quit)

说明:Q 命令不保存内存中正工作的文件,需要时可用 Write 命令保存文件。

14.寄存器命令R(Register)

用途:

显示并修改一个寄存器的值显示全部寄存器、标志位、以及将被执行的下条指令。 显示 8 个标志位状态,并带有修改它们之中任一个或全部的选择格式:R [regname]

其一:显示单个寄存器 有效寄存器是:AX、BX、CX、DX、SP、BP、SI、DI、DS、ES、SS、CS 和 IP。

R AX 系统显示如下: AX F1E4 :_ 现在可以采用下列两个操作中的某一个: 按 ENTER 键保留未修改的内容。 输入 1—4 字符的十六进制值来修改 AX 寄存器的内容,例如 FFFH。 AX F1F4 :FFF_ 现在按ENTER键把AX寄存器内容改变成0FFFH。

其二:显示所有的寄存器和标志位

其二:显示所有的寄存器和标志位 为了显示所有寄存器的内容和标志位(还有下条要执行的指令),输入: R 则系统可能显示如下: AX=0E00 BX=00FF CX=0007 DX=01FF SP=039D BP=0000 SI=005C DI=0000 DS=04BA ES=04BA SS=04BA CS=04BA IP=011A NV UP DI NG NZ AC PE NC 04BA:01lA CD21 1NT 21 头4行显示寄存器十六进制内容和8个标志位状态。最后一行指出下一条要执行的指令地址和它的16进制机器码以及反汇编形式,这是当前CS:IP指向的指令。

③显示标志位有8个标志位,每位用2个字母表示是置“1”状态还是清除状态,详细说明见下表:

标志位名称Set(置位)clear(清除)溢出OVNV方向(减、加)DNUP中断允许DIDI负号(正负)NZPL零(是否)ZRNZ辅助进位ACNA奇偶PEPO进位CYNC

为了显示所有的标志位,输入命令: R F 如果所有标志位处于置1状态,就显示: OV DN EI NGZR AC PE CY

15.检索命令S(Search)

作用:按照给出的内容在一定范围内检索

形式:S range list

说明:以显示被查找到的匹配字符所在的地址来指明全部的匹配。显示没有地址的提示符 “—”,表示未找到任何匹配字符。

例如:要想从 CS:100 到 CS:110 地址范围内检索 41H,那么输入: S CS:100 110 41 如果找到两个匹配,则显示也许是: 04BA:0104 04BA:010D

16.跟踪命令T(Trace)

用途:从 CS:IP 或者=address(如果指定的话)单元中的指令开始单步执行一条或多条指令。这里的=号必须输入。用 value 指定跟踪多条指令。每条指令执行后,显示所有寄存器的内容、标志位的状态以及下一条要执行的指令。 形式: T [=addr][value]

例如,输入命令: T 如果 IP 寄存器内容为 011A,而该地址指向的指令是 MOV AH,0EH,这可能显示: AX=0E00 BX=00FF CX=0007 DX=01FF SP=039D BP=0000 SI=005C D1=0000 DS=04BA ES=04BA SS=04BA CS=04BA IP=011C NV UP DI NG NZ NC PE NC 04BA:01lC CD21 INT 21 这是执行 011A 中指令之后显示的结果,并且指出下条要执行的指令是 04BA:011C 单元中的 INT 21。

17.反汇编指令U(UNassemble)

作用:把内存中的机器码转换成汇编语句,并显示指令的地址、机器码以及汇 编语句形式:

U [range] , 用于反汇编不带指定地址的指令,或反汇编从指定地址开始的指令U [addr] , 用于反汇编从addr开始的指令。反汇编多少由显示方式而定。用 40 列显示时,一次把 16 个字节反汇编;用 80 列显示时,一次把 32 个字节反汇编。,

18.文件转储指令W(Write)

用途:把调试过的信息写到磁盘上。

形式:

1.从指定地址开始把信息写到绝对磁盘扇区上,W address drive sector sector 从指定的开始相对扇区(第一个 sector)开始写数据,并且连续写,直到写完所要求的扇区数(第二个 sector)为止。这种方式以磁盘扇区的多少为限制,而不是内存内容的多少

例如,命令: W 1FD 1 100 A 把从 CS:01FD 单元开始的数据写到驱动器 B 的软盘中,由相对扇区 100H(256)开始连续写 0AH(10)个扇区。

2.内存内容转储到文件。 W addr 此时,写命令把文件写到磁盘上,把从CS:100或由参数 address 指定的单元开始的文件按文件说明 filespec 写到磁盘上。此文件的文件说明被格式化在 CS:5C 文件控制块中。当启动 DEBUG 时指定文件说明,或者使用 N 命令,采用这两种方法都可满足这个条件。

另外,必须把寄存器 BX 和 CX 置成被写的字节数目,它们可能已由 DEBUG 或 Load 命令设置过,也可能被修改过。必须确保 BX 和 CX 寄存器包含正确的值。 不确定对第一种方式是否是必须的

Debug注意事项

可能与之前那个有点重复。这个更详细。

DEBUG支持基本的8086/8088汇编语言语法,DEBUG下的汇编语言有下面一些特点和规则: ① 数值都是十六进制数,并且不加尾缀“H”。 ② 不能使用符号常量和符号地址。 ③ 不能使用绝大部分伪指令,但两个最常用的伪指令 DB 和 DW 能被使用,用于直接把字节和字数据置入相应存储单元。如: DB 1,2,3,4,“ABCD” DW 1234,5678 ④ 可以使用属性操作符“PTR”对 DEBUG 不能明确类型的操作数进行说明。如:INC BYTE PTR [BX]。 ⑤ DEBUG 的 A 命令汇编程序能根据转移目标地址的距离自动地汇编出短、近或远的转移 或调用指令。当然,这也能由“SHORT”、“NEAR PTR”或”FAR PTR”对转移目标地址 进行说明来实现。 ⑥ 远返回指令的助记符在 DEBUG 中为 RETF。 ⑦ 指令前缀助记符必须在相关的指令之前输入,也可以分别放在不同的行。 ⑧ 串操作指令只能用其字节型或字型的助记符形式,如:MOVSB、CMPSW 等。 ⑨ 可以使用段超越前缀助记符 CS:、DS:、ES:和 SS:。如: DS: MOV AL,[BP]