手把手调试指南用Debug玩转你的第一个MASM汇编程序附常用命令清单当你第一次看到DOSBox黑底绿字的界面时那种既熟悉又陌生的感觉可能会让你想起老式计算机的复古魅力。但真正让人头疼的是当你的第一个MASM汇编程序编译通过却运行异常时面对古老的Debug工具那种无从下手的茫然感。别担心这篇文章就是为你准备的——我们将把Debug工具当作你的时光显微镜带你深入8086处理器的内部世界。想象一下Debug就像是一台可以暂停时间的机器让你能够观察每条指令执行时CPU内部发生的每一个细微变化。这比现代IDE的调试器更加原始但也更加透明和直接。下面我们就从一个预设了典型错误的示例程序开始一步步揭开Debug的神秘面纱。1. 调试前的准备工作搭建你的考古实验室在开始调试之前确保你已经完成了以下准备工作已安装DOSBox 0.74-3或更高版本已配置好MASM汇编环境有一个可以编译通过的.asm源文件生成了对应的.exe可执行文件这里我们使用一个故意设置了错误的示例程序error.asmdatas segment message db Debug is fun!,0ah,0dh,$ datas ends stacks segment dw 128 dup(?) stacks ends codes segment assume cs:codes, ds:datas, ss:stacks start: mov ax, stacks ; 错误应该加载datas段地址 mov ds, ax mov dx, offset message mov ah, 09h int 21h mov ax, 4c00h int 21h codes ends end start这个程序故意将数据段地址加载错误导致运行时无法正确显示字符串。我们将用Debug来找出并修复这个问题。2. Debug基础你的第一个调试会话启动调试会话非常简单在DOSBox中运行debug error.exe你会看到一个简洁的提示符-这就是Debug的交互界面。让我们先熟悉几个最基础但至关重要的命令2.1 查看和修改寄存器R命令输入r命令你会看到类似如下的输出AX0000 BX0000 CX0042 DX0000 SP0000 BP0000 SI0000 DI0000 DS0B3F ES0B3F SS0B4F CS0B4F IP0100 NV UP EI PL NZ NA PO NC这些寄存器值中有几个特别值得关注CS:IP指向下一条要执行的指令DS数据段寄存器SS:SP堆栈指针要修改某个寄存器的值可以使用r 寄存器名例如r ax AX 0000 :1234 ; 将AX修改为1234h2.2 反汇编代码U命令u命令可以将机器码反汇编为汇编指令。不带参数时它会从当前CS:IP开始反汇编u 0B4F:0100 8CC8 MOV AX,CS 0B4F:0102 8ED8 MOV DS,AX 0B4F:0104 BA0000 MOV DX,0000 0B4F:0107 B409 MOV AH,09 0B4F:0109 CD21 INT 21 0B4F:010B B8004C MOV AX,4C00 0B4F:010E CD21 INT 21你可以指定反汇编的起始和结束地址u 100 10e2.3 单步执行T命令t命令是调试过程中最常用的命令之一它执行一条指令并显示所有寄存器的状态。让我们尝试执行前几条指令t AX0B4F BX0000 CX0042 DX0000 SP0000 BP0000 SI0000 DI0000 DS0B3F ES0B3F SS0B4F CS0B4F IP0102 NV UP EI PL NZ NA PO NC 0B4F:0102 8ED8 MOV DS,AX继续按t执行下一条指令观察DS寄存器的变化。3. 实战调试定位并修复错误现在让我们用Debug来找出我们示例程序中的错误。按照以下步骤操作启动调试会话debug error.exe使用u命令查看反汇编代码找到程序入口使用t命令单步执行重点关注DS寄存器的变化当执行到MOV DX,0000时使用d ds:0查看数据段内容你会注意到数据段中并没有我们预期的字符串。这是因为我们错误地将堆栈段地址加载到了DS寄存器。让我们修复这个问题使用q退出当前调试会话修改源代码将MOV AX,STACKS改为MOV AX,DATAS重新编译链接程序再次启动调试会话验证修复4. Debug高级技巧内存查看与修改4.1 查看内存D命令d命令可以显示内存内容。基本语法是d [段地址]:[偏移地址] [长度]例如要查看数据段的前32个字节d ds:0 20输出会显示16进制和ASCII两种形式0B3F:0000 44 65 62 75 67 20 69 73-20 66 75 6E 21 0A 0D 24 Debug is fun!..$ 0B3F:0010 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................4.2 修改内存E命令e命令可以修改内存内容。例如要修改DS:0000处的字节e ds:0 0B3F:0000 44.41 ; 将第一个字节从44h改为41h(A)你也可以直接输入一串值e ds:10 41 42 43 44 ; 在DS:0010处写入A,B,C,D5. Debug命令速查表下表总结了Debug中最常用的命令及其功能命令语法功能描述反汇编U [起始地址] [结束地址]将机器码反汇编为汇编指令单步执行T [指令数]执行一条或多条指令运行G [起始地址] [断点地址]运行程序直到断点寄存器R [寄存器名]显示或修改寄存器查看内存D [地址] [长度]显示内存内容修改内存E 地址 [值列表]修改内存内容汇编A [地址]输入汇编指令退出Q退出Debug6. 调试实战一个完整的调试过程让我们通过一个完整的例子来巩固所学知识。假设我们有如下程序sum.asmdatas segment num1 dw 1234h num2 dw 5678h result dw ? datas ends codes segment assume cs:codes, ds:datas start: mov ax, datas mov ds, ax mov ax, num1 add ax, num2 mov result, ax mov ax, 4c00h int 21h codes ends end start调试步骤编译链接程序masm sum.asmlink sum.obj启动调试debug sum.exe反汇编查看代码u设置断点在加法指令后g 10e(假设加法指令在10e)查看结果d ds:4(result位于数据段偏移4处)验证结果r查看AX寄存器的值通过这样的实践你会逐渐熟悉Debug的工作方式并能够快速定位汇编程序中的各种问题。记住调试是一门实践性很强的技能多动手尝试不同的命令和技巧你会很快掌握这门考古艺术的精髓。