使用 DOSBox 和 Debug 命令调试汇编程序
1月 24, 2021
正在看王爽的《汇编语言》,因为我在 Mac M1 环境,按书上做汇编实验的话,搜索了一圈发现 DOSBox 应该可以满足我的需要,它是一个跨平台的可以运行 MS-DOS 的模拟器。
DOSBox #
这个模拟器应该是被一些老玩家拿来玩上世纪 80 年代的 DOS 游戏了,就像美剧少年谢尔顿里面那样的。
Debug #
介绍 https://en.wikipedia.org/wiki/Debug_(command)
下载地址
使用手册:
MS-DOS Debug Commands | CMD | PARAM |
---|---|---|
assemble | A | [address] |
compare | C | range address |
dump | D | [range] |
enter | E | address [list] |
fill | F | range list |
go | G | [=address] [addresses] |
hex | H | value1 value2 |
input | I | port |
load | L | [address] [drive] [firstsector] [number] |
move | M | range address |
name | N | [pathname] [arglist] |
output | O | port byte |
proceed | P | [=address] [number] |
quit | Q | |
register | R | [register] |
search | S | range list |
trace | T | [=address] [number] |
unassemble | U | [range] |
write | W | [address] [drive] [firstsector] [number] |
微软的 MS-DOS 项目里的 DEBUG.COM
文件对应的就是 Debug 程序,它是一个 .COM
类型文件。
.COM
文件也被称为 DOS 命令文件,一个 COM 文件的内容进行编码的二进制格式,可容纳高达 64 KB 的代码。这些 COM 文件也被归类为可执行文件,但不像 EXE 文件,没有连接到一个 COM 文件的元数据信息或文件头。一个的内容 .COM
文件通常包括使用内置的 DOS 资源来执行某些操作的指令或命令。这些指令和命令通过 Windows 命令提示符的正常进行。这些内容 .COM 文件可以查看和使用在其他文本编辑程序 Microsoft 记事本编辑。
MASM #
是微软公司为 x86 微处理器家族开发的汇编开发环境。
https://zh.wikipedia.org/zh/MASM
下载地址
- https://docs.microsoft.com/en-us/cpp/assembler/masm/masm-for-x64-ml64-exe 有最新的介绍,但是没有下载连接
- http://www2.hawaii.edu/~pager/312/masm%20615%20downloading.htm 三方机构提供的 6.15 版本
- https://github.com/microsoft/MS-DOS 只有更早期的 1.0 版本
现在寻找能运行的 Debug、MASM 程序,整体感觉是在考古。
注意有一个 MASM32(https://www.masm32.com/)下载链接已 404,MASM32 并非是指 Microsoft 的 MASM 宏汇编器。MASM32 是一个由个人开发的包含了不同版本工具组建的汇编开发工具包。
NASM #
后来发现在 Mac 上还有另一款编译器来调试汇编程序,就是 NASM。它也是一款基于英特尔 x86 架构的汇编与反汇编工具。它可以用来编写16位、32位(IA-32)和64位(x86-64)的程序。 NASM 被认为是 Linux 平台上最受欢迎的汇编工具之一。
直接在 Mac 上编写汇编指令还是挺危险的,因为实验性的代码里指定的内存地址是真实的内存地址,最好还是在虚拟机里面运行,所以还是回到了 DOSBox,NASM 先搁置不细看了。
编译 #
编译的作用是将汇编程序转化成包含机器代码的目标文件。
使用 masm
命令进行编译,由 1.ass
生成 1.obj
。
下面是 1.ass
assume cs:codesg
codesg segment
mov ax, 0123H
mov bx, 0456H
add ax, bx
add ax, ax
mov ax, 4c00H
int 21H
codesg ends
end
链接 #
只有目标文件还不够,我们还需要链接器完成以下几个任务:
- 当源程序很大时,编译器可以可以将文件分别编译成目标文件,然后还需要通过链接器将它们连接到一起,生成一个可执行文件。
- 如果程序调用了某个库文件中的子程序,需要将这个库文件和该程序生成的目标文件连接到一起,生成一个可执行文件。
- 存有机器码的目标文件还不能直接运行,链接器会将目标文件处理成可执行文件。
使用 link
程序进行链接,由 1.obj
生成可执行文件 1.exe
。
装载 #
1.exe
是一个硬盘上的文件,需要运行的话必须要被放入内存中,这个过程叫做“装载”。
可以通过 debug 1.exe
进行单步调试。
程序加载后,寄存器 DS 中存放着程序所在内存区的段地址,这个内存区的偏移地址为 0,则程序所在的内存区的地址为 DS:0
。同时,内存区的前 256 个字节存放的是 PSP(程序段前缀),是 DOS 用来和程序进程通信的,从 256 字节处向后的空间存放的是程序。