第 5 章 调试⚓︎
约 1262 个字 8 行代码 预计阅读时间 6 分钟
软件断点和硬件断点⚓︎
- 软件断点:通过改写指令首字节为
0CCh
来为该指令设置断点- 机器码
0CCh
对应指令int 3h
,当执行到该指令时,先调用对应的中断函数,从而使调试器获得控制权 - 此时屏幕上会显示当前寄存器的值以及将要执行的指令,并等待用户敲键
- 当用户输入单步执行命令后,调试器会恢复断点处指令的首字节,再单步执行该条指令
- 等该指令执行完后 CPU 会自动产生
int 1h
单步中断,并调用对应的中断函数,从而使调试器再次获得控制权 - 该函数接着重新改写断点处指令的首字节为
0CCh
,即恢复原来的断点,并显示当前寄存器值以及将要执行的指令,再等待用户敲键 - 软件断点不依赖 CPU 中的调试寄存器,因此断点数量任意
- 机器码
- 硬件断点:通过把指令首字节地址、变量地址写入调试寄存器来设置指令执行断点或变量读写断点
- 由于 CPU 中用来保存断点地址的调试寄存器仅有 4 个,因此硬件断点的数量最多只有 4 个(但 Bochs Enhanced Debugger 可以设置类似硬件断点的 16 个指令执行断点和 16 个变量读写断点)
- 硬件断点不会修改指令的首字节,也不会修改变量的值
- 由于硬件断点可以监控指令对变量的读写动作,所以它可以帮助我们找出如数组越界等靠软件断点难以发现的 bug
Turbo Debugger⚓︎
在使用 Turbo Debugger(以下简称 TD)的调试功能前,我们应预先将源程序(.asm)编译为可执行程序(.exe
# 法1
tasm /zi hello; # 参数 /zi 表示 full debug info
tlink /v hello; # 参数 /v 表示 include full symbolic debug information
# 法2
masm hello;
link hello;
- 法 1 用到了 Borland 公司的 Turbo Assembler 和 Turbo Link,在编译和链接的过程中会自动生成调试信息,比如变量名、标号名;并且在用 TD 调试时可以看到源代码,即可以进行源代码级的调试
- 注意参数
/zi
、/v
不能省略,否则调试效果和法 2 一样
- 注意参数
- 法 2 得到的可执行程序在 TD 中只能看到机器码和汇编代码,而无法看到源代码
通过以下命令进行调试:
下面是 TD 的界面:
-
刚打开 TD 时应该只有代码窗口(就是左上深蓝色的区域
) 。要想显示寄存器窗口(右侧 Regs)和数据窗口(底部 Dump) ,点击上方选项View
,在选项列表中找到Register
和Dump
,点击它们分别会弹出寄存器窗口和数据窗口 -
调整各窗口的大小
- 法 1:鼠标按住窗口右下角的位置并拖动即可调整大小
- 法 2:先按
Ctrl+F5
键选中窗口,然后按Shift+方向键
控制窗口变化方向,最后按回车键确定窗口大小
-
若想同时观察机器码和源代码,点击
View->CPU
,再按F5
放大窗口,如图所示(不知道为什么我这边的代码好松散) : -
如果用
masm
和link
得到可执行程序,那么 TD 界面应该是这样的: -
按
Tab
键可以顺时针切换到下一个子窗口,按Shift+Tab
键则按逆时针方向切换到下一个子窗口 - 当光标位于某个子窗口或菜单项时,按 F1 即可获得与该子窗口或菜单项相关的帮助信息
- 当光标位于代码窗时,可通过键盘输入一条指令来改写当前指令
- 当光标位于寄存器窗、堆栈窗或数据窗时,也可通过键盘输入来改变当前光标处的值(注意值要输入正确,正确格式见第 2 章)
-
在寄存器窗口中,默认只能看到 16 位寄存器。要想看到 32 位寄存器,在寄存器窗口处点击鼠标右键,然后选择
Registers 32-bit
(或者直接按快捷键Ctrl+R
) ,这样就能看到 32 位寄存器了 -
TD 常用快捷键如下:
快捷键 | 含义 |
---|---|
Ctrl+F2 |
重新开始跟踪 (program reset) |
F2 |
设置断点 (breakpoint),断点所在行用红色高亮标出 |
F4 |
运行到光标处 (run to cursor) |
F7 |
跟踪进入 (trace into),相当于 DEBUG 的T 命令 |
F8 |
步过 (step over) |
F9 |
运行程序 (run) |
Ctrl+G |
设置代码窗、堆栈窗、数据窗的起始地址,G 代表 go(常用操作是在数据窗查找ds:0 ) |
Ctrl+O |
在代码窗显示cs:ip 指向的指令,O 表示 original |
Alt+F5 |
观察用户屏幕即查看当前程序的输入输出窗口 |
Alt+X |
退出 TD |
DEBUG⚓︎
S-ICE⚓︎
特点:
- 全屏幕调试
- 源代码级调试
- 即使弹出
- 硬件断点
- 由于本身运行在保护模式下,因此不能挑食保护程序用户程序
Bochs⚓︎
评论区
如果大家有什么问题或想法,欢迎在下方留言~