Debug的使用

什么是Debug

DebugDosWindows提供的实模式(8086方式)程序的调试工具,可以使用它来查看CPU各种寄存器中的内容、内存的情况和在机器码级跟踪程序的运行。

但是debug命令在64位操作系统下是不能使用的。在cmd中输入debug,会提示:不是内部或外部命令,也不是运行的程序或批处理文件。

使用DOSBox在Win7_64下搭建汇编环境

DEBUG.EXEEDIT.COMMASM.EXELINK.EXE等汇编工具,一般在32位的Windows操作系统下有自带,但是在64位操作系统下并没有提供,并且将32位系统下的汇编工具拷贝到64位系统下并不能使用,为了解决这个问题,使用DOSBox工具来使用它们。

下载DOSBox,然后安装即可。准备DEBUG.EXEEDIT.COMMASM.EXELINK.EXE等汇编工具。

DOSBox安装完成后,打开发现它的提示符为Z:\>,这是DOSBox里的虚拟盘,为了使用我需要更改到我自己的盘符,但是如果采用和cmd下的方式直接切换盘符,会提示我需要挂载的信息。

比如我要将G:\AssemblyTools作为我的汇编测试目录,那么需要执行mount G G:\AssemblyTools命令,G盘符也就虚拟成了本机的G:\AssemblyTools目录,将DEBUG.EXE等一系列汇编工具拷贝至该目录下。当我在DOSBox下切换到G盘下时,实际上就是切换到了G:\AssemblyTools下,因此也就可以直接使用汇编工具了。

Debug功能

  • DebugR命令查看、改变CPU寄存器的内容。
  • DebugD命令查看内存中的内容。
  • DebugE命令改变内存中的内容。
  • DebugU命令将内存中的机器指令翻译成汇编指令。
  • DebugT命令执行一条机器指令。
  • DebugA命令以汇编指令的格式在内存中写入一条机器指令。

查看和改变CPU寄存器的内容

使用R命令查看寄存器的内容,注意CSIP的值,CS=073FHIP=0100H,也就是说内存073FH:0100H处的指令为CPU当前要读取并执行的指令。在所有寄存器的下方,Debug还列出了CS:IP所指向的内存单元处所存放的机器码,并将它翻译成汇编指令。 Alt text

还可以使用R命令来改变寄存器中的内容,比如AX中的值,可用R命令后加寄存器名来进行,输入r ax后按Enter键,将出现:作为输入提示,在后面输入要写入的数据后按Enter键,即完成了对AX寄存器内容的修改。

Alt text

查看内存中的内容

使用D命令,可以查看内存中的内容,如果我想知道内存FFFF0H处的内容,可以使用d 段地址:偏移地址的格式来查看。

Alt text

要查看内存FFFF0处的内容,首先将这个地址表示为段地址:偏移地址的格式,使用d 段地址:偏移地址的格式,Debug将列出指定内存单元开始的128个内存单元的内容。

Debug将输出3部分内容。

  • 中间是从指定地址开始的128个内存单元的内容,用十六进制的格式输出,每行的输出从16的整数倍的地址开始,最多输出16个单元的内容。可以看到,内存FFFFH:0000H单元中的内容是EA,内存FFFFH:0010H单元中的内容为60。每行中间有一个-,它将每行的输出分为两个部分,分别是前8个单元和后8个单元。
  • 左边是每行的起始地址。
  • 右边是每个内存单元中的数据对应的可显示的ASCII码字符。如果没有对于的ASCII字符,使用.来代替。

改变内存中的内容

可以使用E命令来改变内存中的内容,比如,要将内存1000H:0000H1000H:0009H单元中的内容分别写为0123456789,可以使用e 起始地址 数据 数据...的格式进行修改。

Alt text

也可以采用提问的方式一个一个地改写内存中的内容。输入e 1000:0,按Enter键,Debug显示起始地址1000:0和第一单元的原始内容00,然后光标停在.的后面提示输入想要写入的数据,此时有两个选择,一是输入数据,然后按空格键,即用刚才输入的数据替换内存单元的内容,二是不输入数据,直接按空格,即不改写当前内存单元。所有改写输入完毕后按Enter,结束操作。

Alt text

也可以向内存中写入字符串。比如,用E命令从内存1000H:0000H开始写入:整数1、字符串a+b、整数2、字符串tinylcyAlt text

至于向内存中写入机器码,因为机器码也是数据,当然也可以用E命令将机器码写入内存,比如我要从内存1000H:0000H单元开始写入这样一段机器码。

b80100     mov ax,0001
b90200     mov cx,0002
01c8       add ax,cx

E命令向从1000H:0000H开始的内存单元中写入了8个字节的机器码。然后使用D命令查看内存1000H:0000H1000H:001FH中的数据。

Alt text

使用U命令查看写入的或内存中原有的机器码所对应的汇编指令,比如使用U命令将从1000H:0000H开始的内存单元中的内容翻译成汇编指令,并显示出来。

Alt text

U命令的显示输出可以分为3部分,每一条机器指令的地址、机器指令、机器指令所对应的汇编指令。

  • 1000H:0000H处存放的是写入的机器码b8 01 00所组成的机器指令,对应的汇编指令是mov ax,0001
  • 1000H:0003H处存放的是写入的机器码b9 02 00所组成的机器指令,对应的汇编指令是mov cx,0002
  • 1000H:0006H处存放的是写入的机器码01 c8所组成的机器指令,对应的汇编指令是add ax,cx

由此,可以再次感受到内存中的数据和代码没有任何区别,关键在于如何解释。

使用DebugT命令来执行写入的机器码,T命令可以执行一条或多条指令。如果仅仅是简单的使用T命令,执行的是CS:IP指向的指令。查看当前的寄存器状态,可以看到CS=073FHIP=0100H,指向内存073FH:0100H。若要使用T命令控制CPU执行1000H:0000H单元的指令,需要先让CS:IP指向1000H:0000H,因此,使用R命令修改CSIP中的内容,使得CS:IP先指向1000H:0000H

Alt text

完成上述步骤之后,就可以使用T命令执行刚才写入的指令了。指令T命令之后,CPU执行CS:IP指向的指令,那么1000H:0000H处的指令b8 01 00(mov ax, 0001)得到执行。注意,指令执行后,AX中的内容被修改为1IP改变为IP+3(因为mov ax, 0001的指令长度为3字节),CS:IP指向下一跳指令,继续使用T命令执行下面的指令。最终AX中的内容为3CX中的内容为2

Alt text

使用E命令可以直接向内存中写入机器指令,但是这样做不方便。为此,Debug提供了A命令,可以直接以汇编的形式写入指令。

Alt text

首先使用A命令,以汇编语言向从1000H:0000H开始的内存单元中写入了几条指令,然后用D命令查看内存中的内容。可以看到Debug将这些汇编指令翻译成对应的机器指令,将它们的机器码存入内存。接着,可以使用T命令执行内存中的这段机器码。

总结

  • 查看、修改CPU中寄存器的内容:R命令。
  • 查看内存中的内容:D命令。
  • 修改内存中的内容:E命令(可以写入数据、指令,在内存中,它们实际上没有区别)。
  • 将内存中的机器指令解释为汇编指令:U命令。
  • 执行CS:IP指向的内存单元处的指令:T命令。
  • 以汇编指令的形式向内存中写入指令:A命令。

参考