项目 | 描述 |
---|---|
搜索引擎 | Bing、Google |
AI 大模型 | 文心一言、通义千问、讯飞星火认知大模型、ChatGPT |
PHP 手册 | PHP Manual |
1947
年的某一天,计算机科学家 Grace Hopper
在 Harvard Mark II
计算机的维护工作中发现了一个发现了一只 夹在继电器中的飞蛾
。这只昆虫导致了计算机的故障,后来人们将这种问题称为 bug
。
Bug
这个术语被广泛接收,用于描述计算机程序中的 错误
。当程序出现意外行为时,程序员通常会说他们需要对程序进行 Debugging
,以查找和修复问题。
Debug
是一个在 MS-DOS
和一些 Windows
系统中提供的命令行工具,用于 诊断程序在运行时产生的错误、异常或意外行为
,并据此采取措施来解决问题,以确保程序能够按照预期的方式运行。在早期的 MS-DOS
和 Windows
系统中,Debug
是一个非常有用的工具,尤其是对于 底层(系统级编程)
程序员来说。
随着时间的推移和技术的发展,debug
的实用性逐渐降低,到目前已经没有什么人在使用了。具体原因整理如下:
项目 | 描述 |
---|---|
技术进步 | 现代计算机和现代操作系统功能更加丰富和复杂,使得 Debug 这样的工具变得不那么适用。现代的调试工具,如 Visual Studio 、GDB 和其他 IDE 中的调试工具,提供了更为高级和强大的功能 。 |
64 位架构 | 现代计算机普遍采用 64 及 32 位架构,Debug 在这类计算机中运行需要一个 16 位架构的模拟环境 。 |
安全性考虑 | Debug 允许 直接访问和修改系统的底层硬件(内存,CPU 等) ,这可能导致安全隐患。 |
从 Windows 7 64位版本
开始,Windows 系统中就不再包含 debug
应用程序了。
Debug
是一个 16
位应用程序。在 Windows 7
及此前的 32 位
操作系统中能够运行Debug
应用程序,是因为这些系统内置了一个叫做 Windows on Windows(WoW)
的 16 位子系统
来支持 16位
的应用程序。但在 64 位Windows
中,这个16位子系统被移除,因此 Debug 不能在 64 位 Windows
上运行。
学习 16 位
汇编的过程中,Debug
仍然是必不可少的。其理由整理如下:
项目 | 描述 |
---|---|
简单直观 | Debug 提供了一个简单的环境,允许用户直接输入、执行、调试汇编代码。对于初学者来说,这可以 直观地看到指令是如何工作的 ,不需要复杂的设置或其他工具。 |
实时交互 | 使用debug ,你可以 实时地查看和修改 CPU 寄存器、内存和其他系统资源中的数据 ,这对于理解汇编语言和计算机的工作原理非常有帮助。 |
传统和历史 | 在很多早期的计算机科学和工程课程中,debug 是教学 16 位汇编的标准工具。虽然现在有更先进的工具和环境,但 debug 仍然被用作教育工具。。 |
DOSBox-X
是一个 开源的 x86 模拟器
,主要用于运行 早期操作系统 MS-DOS
中的应用程序。与原始的 DOSBox
相比,DOSBox-X
提供了 更多的特性并对原有缺陷进行了改进
,使其 更加适合用于模拟早期的 PC 环境
。
如果你希望在不支持 16 位应用程序(如 Debug)的操作系统中使用它们,那么你需要一个模拟器,而 DOSBox-X
就是一个很好的选择。
DOSBox-X 在其官网提供了不同的安装包,如果您需要使用到 DOSBox-X,请前往下载安装。
在 Debug 中,R
命令即 Register
的简写,该命令用于 查看或修改寄存器中的内容
。
注:
在 Debug 中,命令与寄存器名称等均是不区分大小写的
。就命令 R
而言,在 Debug 中使用 R
与 r
是没有区别的。
在 Debug 命令行
中,当你单纯地输入 R
或 r
并敲击回车键时,DEBUG 将显示所有 CPU 寄存器的当前值。具体而言,您将看到如下类似界面:
AX=0000 BX=0000 CX=0000 DX=0000 SP=FFEE BP=0000 SI=0000 DI=0000
DS=0DC0 ES=0DC0 SS=0DC0 CS=0DC0 IP=0100 NV UP EI PL NZ NA PO NC
0DC0:0100 0000 ADD [BX+SI],AL DS:0000=CD
其中
从左往右,从上到下,我们依次对命令 R
的输出内容进行讲解。
AX ~ BX
是一系列寄存器的名称即其保存的数据。NV ~ NC
则是标志寄存器的 一部分(16 位寄存器,但仅使用了其中的部分二进制位)
,用于 存储与程序执行相关的信息
。0DC0:0100
即 CS:IP
,用于指示 CPU 当前要读取并执行的指令
。0000
即 CS:IP
指向的内存空间 所存储数据的十六进制表示
。ADD [BX+SI],AL
即 CS:IP
指向的内存空间中的二进制数据的汇编语言表示。DS:0000=CD
????
当您在 Debug 命令行中输入命令 R
的同时 输入目标寄存器的名称
即可修改该寄存器所保存的值。对此,请参考如下界面(尝试修改通用寄存器中的数据
):
在输入修改寄存器的名称并敲击回车键后,Debug 将 输出被修改寄存器的当前值
并给出输入提示,要求您 输入被修改寄存器的结果值
。
我们尝试将 AX
寄存器中的当前值修改为 十六进制数 002F
,再通过 R
命令查看修改结果。
在 Debug 中,D 命令即 Dump
的简写,该命令用于 查看内存中的数据
。
当你在 Debug 中直接使用命令 D
时,该命令将显示内存中以 CS:IP
所为首的 128
字节内存空间。对此,请参考如下界面:
命令 D
的输出内容共由三部分内容组成,这三部分(从左至右
)分别是地址指示
、十六进制内容
及 ASCII 表示
。
二进制数据的十六进制表示
,每两个十六进制数值代表一个字节。这些十六进制数值以 8 字节
的 组块
显示,每两个组块之间用一个 短横线 -
分隔。每一个字节解码为 ASCII 字符的结果
。16
字节内存空间中的内容相对应,而地址指示则用于表示这 连续的 16 字节内存空间的起始字节所处的位置
。地址指示由 段地址
、:
及 偏移地址
三部分组成。在使用 D
命令的过程中,您还可以通过如下格式来指定起始内存空间的地址,Debug 将 显示以起始内存空间为首的 128 字节内存空间
。
D 起始内存空间的段地址:起始内存空间的偏移地址
举个栗子
当然,你还可以 仅指定起始内存空间的偏移地址(在任何需要内存空间地址的地方,段地址通常都是可以直接省略的✨)
,起始内存空间的段地址将自动从 DS
寄存器中获取。对此,请参考如下示例:
在使用 D
命令的过程中,在指定被查看内存空间的起始地址外,您 还可以指定被查看内存空间的结束地址
。指定被查看内存空间范围的命令格式为:
D 起始内存空间的段地址:起始内存空间的偏移地址 结束内存空间的偏移地址
举个栗子
起始内存空间的段地址可以被省略
,段地址被省略后,Debug
将自动使用 DS
寄存器中存储的段地址。对此,请参考如下示例:
在 Debug 中,A
命令即 Assemble
的简写,该命令用于 以汇编语言的形式在内存中写入机器指令
。
使用命令 A 时,你可以通过 给出地址来指示需要写入命令的起始内存空间
。在不指定地址的情况下,该命令默认在 CS:IP
所指向的内存空间中开始执行输入。
在使用命令 A 以汇编语言的形式在内存中写入机器指令时,若汇编语言存在语法错误,则写入操作将失败且 Debug 将提示(输入地址没有发生变化)你重新进行输入
。对此,请参考如下界面:
当你向内存输入命令完毕后,可以在 A
命令的输入提示界面下 直接敲击回车键结束输入
。
在结束输入后,尝试通过命令 D
查看内存空间中输入的内容。对此,请参考如下界面:
在 Debug 中,U
命令即 Unassemble
,该命令用于 将指定内存空间存储的机器指令翻译为汇编代码
。使用该命令时,若未指定内存空间地址,则使用 CS:IP
所存储的地址。
使用 D
仅能够查看存储在内存空间中的机器指令,有了 U
命令我们就能验证我们刚刚是否成功将汇编指令输入内存中了。
在 Debug 中,T
命令即 Trace
的简写,该命令将 允许您逐步执行程序的指令,以便查看程序在每一步的执行情况,从而提高发现问题的可能,有助于实现问题的解决
。
T
命令允许您指定需要被执行指令所处的内存地址,默认情况下,T
命令将使用由 CS:IP
提供的地址。
在此前我们通过 A
命令已经向内存中输入了如下指令:
MOV AX, 100
ADD AX, BX
其中:
MOV AX, 100
表示将寄存器 AX
中的值设置为 100
,而 ADD AX, BX
则表示将 AX + BX
的结果设置为 AX
的值。
我们尝试通过 T
命令来观察指令的执行。对此,请参考如下界面:
MOV AX, 100
ADD AX, BX
在 Debug 中,命令 E
即 Edit
,表示编辑操作。当你在 Debug 命令行中输入并执行命令 E
时,该命令通常会要求你指定一个 完整的内存地址或偏移地
址,在指定 需要修改值的内存空间的首地址
后即可修改内存中的内容。
在 Debug 命令行中输入 E
及 需要修改值的内存空间的首地址
后,Debug 将给出 被修改内存空间的现有值
并提示您输入十六进制值以对其进行修改。在您修改完当前字节大小的内存空间中的内容后,输入空格键进行下一字节空间值的修改
,要 结束
对内存空间逐字节式的修改仅需要 敲击回车键
即可。对此,请参考如下示例:
注:
在敲击回车键结束对内存空间进行逐字节式的修改时,存在两种可能的情况:
该值将输入对应的内存空间中
,随后修改过程立即终止。0000
,修改过程将立即终止。在 Debug 命令行中,输入命令 E
及 需要修改值的内存空间的首地址
后,在其后您可以 添加多个对内存空间进行修改的结果值
,多个结果值之间 以空格分隔
。在输入完毕后,敲击回车键执行对内存空间的修改并立即终止修改过程。对此,请参考如下界面: