如何使用 Debug





5.00/5 (5投票s)
如何使用调试。
引言
如果你想编写汇编代码,你需要一个这样的环境。有很多方法。最原始的方法必须是 Debug (debug.com),你可以在任何包含 MS-DOS 的机器上找到它。在 Debug 中编写代码可能会非常困难、令人沮丧且耗时。但它也有一些非常令人满意的一面,比如让你更接近处理器,而且因为 Debug 存在并且在我们身边,我们也能看到它到底在做什么。
现在,我们要看看如何使用 debug。集中注意力!
使用 Debug
这是我们向 debug 发送命令的地方。我们输入像 a, n, l, d, t, g 这样的字母来指示 debug 编写程序、保存、加载等等。我们来分别介绍它们。
要开始编写代码,我们输入 ' a ',意思是 ' assemble '(汇编),然后按回车。
写完一行后,我们按两次回车,得到以下结果
要运行程序,我们输入 ' g ',意思是 ' go '(运行),然后按回车。程序开始运行,并在第一个断点处结束。(否则,使用 int 3 (断点) 或 int 20 (返回 DOS) 指令,否则计算机将锁定。如果你想保存程序,int 3 不足以防止计算机锁定。这时要使用 Int 20。并且你必须注意 DS。程序完成后,DS 应该具有之前的值。所以你应该使用 'push ds' 和 'pop ds'。)
要从 debug 环境返回 DOS,输入 'q' 然后 quit(退出)。
现在,我们来写一个简单的程序——一个将两个数字相加的程序。我们将使用 AX 和 BX 寄存器,总和将存储在 AX 中。(AX=AX+BX)
让我解释一下这里做了什么。我用“«”代替“按回车”。
- C:\> debug «
-a « ; 开始编写代码
mov ax,03 « ; 将 AX 设置为 03,AX 将为 03
mov bx,04 « ; 将 BX 设置为 03,AX 将为 04
add ax,bx ; 将 AX 与 BX 相加,总和在 AX 中
int 3 ; 断点
«
-g « ; 运行,即转到 0100,因为 IP 是 0100 (IP=Instruction Pointer,执行 IP 指向地址处的代码)
结果在 'g «' 之后由 debug 直接显示。所以,我们看到总和 07 存储在 AX 中。
我们可以使用 't' 来单步跟踪,查看程序一步一步地做了什么,也就是说,我们可以跟踪寄存器的值。但此时,跟踪的使用将不起作用。事实上,甚至 'g' 也不会运行程序。这仅仅是因为 IP 的值。看看它。它是 0108。但我们的程序从 0100 开始。所以 IP 的值应该改为 0100。我们通过 'r' 来做到这一点。如果你输入 'r' 然后按回车,你会看到寄存器的值。如果你想给寄存器赋一个值,你输入 ' r ax' 或 'r bx' 或 'r ip' 或任何你想设置的寄存器名,然后按回车。
现在看看 IP 的新值。所以,如果你输入 go,处理器就会执行 0100 位置的代码,也就是这里的 mov ax,03,并且会增加 IP 的值,直到发生断点。
如何保存程序
到目前为止,我们使用了 a, g, t, r, q 指令,并编写了一个简单的程序。现在,让我们看看如何保存程序。你将看到它与任何其他程序的普通保存任务有多么奇怪和不同。
现在假设我们在这里。保存这个程序有三个步骤。
- 输入 'n' 和程序名,例如 -n first.com
现在是关键。我们应该指定要保存多少字节。所以,我们必须给 CX 寄存器传递一个值。 - 输入 r cx 然后按回车。然后输入你要保存的字节数。实际上,输入程序开始地址和结束地址之间的差值。在这个例子中,0109-0100=9 字节。更实际地说,查看最后一个地址并取其低字节。如果地址的高字节是 01,那将足够了。
- 最后输入 'w',程序就会被保存。现在,让我们来看看。
这里给 CX 寄存器传递值和命名程序的顺序并不重要。事实上,有时你甚至不需要指定 CX 的值。因为你知道它有一个合适的值。例如,如果你返回 DOS 然后再次进入 debug,CX 的值不会改变。在讲完如何加载程序后,我会向你展示这一点。但还有一件事我们需要注意。IP 的值。这里应该是 0100,因为它是保存过程的起点。例如,如果我们尝试在运行程序后保存它,IP 的值将是 0109,我们会收到一个消息,比如 'writing 40009 bytes',也许我们会认为我们已经保存了它,但实际上我们无法稍后加载程序。
.
你看到了保存了多少字节。让我们尝试加载它。
它没有成功。
在这里我犯了一个错误。我试图用我之前没有提到过的东西来解释。在我告诉你如何加载程序之前,我用它来表达一些东西。抱歉。我不认为这里会是一个大麻烦。因为这是一个很容易弄清楚的阶段。但在课程中可能会有很多这类问题,所以要小心。让我们回到我们的主题。
如何加载程序
有两种方法。一种是我们上面看到的,输入 debug 和程序名,然后按回车。然后输入 'u' (unassemble,反汇编) 来查看代码。
你看,通过 ' u ',debug 向我们显示带操作码的代码。所以,例如,我们可以很容易地说 B8 是 mov ax,... 的操作码。
第二种加载程序的方法是使用 'l' (load,加载)。让我们看看如何。
我们输入 'n' 和要加载的文件名。然后我们只输入 ' l '。程序就会被加载。如果想看代码,可以使用 u。
所以,我想讲一个有趣的点来结束。假设我们想把 ' ADD AX,BX' 这行替换成 'SUB AX,BX'。你看到了那行的地址。是 0106。
为了能清楚地向你展示,我退出了 debug 并再次进入。然后我加载了 first.com。但我没有使用 u (unassemble),以免弄乱环境。我知道在 106 行的这个位置有一个 ADD AX,BX。所以,要替换它,我们输入 a 106 然后按回车。然后第 106 行出现在我们面前,是空的。我们输入我们计划输入的内容,然后按两次回车。就这样,它被改变了。
这里还有另一个我之前提到过的关于 CX 状态的有趣点。你在这里看到我没有给 CX 赋一个值。但是编写成功完成了,因为我知道 CX 的值。是我在加载程序时指定的 9,并且在此过程中它从未改变过。我用这个让我的很多朋友感到惊讶。:)
历史
- 2009年6月30日:首次发布