【汇编语言】在VMware中搭建FreeDOS环境运行经典汇编程序

📅 发布时间:2026/7/3 17:35:50 👁️ 浏览次数:
【汇编语言】在VMware中搭建FreeDOS环境运行经典汇编程序
1. 为什么我们需要一个“复古”的汇编开发环境如果你正在学习王爽老师的《汇编语言》或者对计算机底层原理、操作系统启动过程感兴趣那你大概率会遇到一个“时代错位”的难题书里讲的很多知识比如通过BIOS中断读写软盘、直接操作硬件端口在现代的Windows 10/11或者macOS上根本跑不起来。我自己就踩过这个坑在64位Windows 10的DosBox里折腾了好几天程序要么没反应要么返回值永远是错误码那种挫败感懂的都懂。这其实不是教材的问题也不是你学得不对而是技术发展的必然。现代操作系统运行在保护模式下为了安全和稳定严格禁止应用程序直接操作硬件。而DOSDisk Operating System是一个运行在实模式下的操作系统程序可以“为所欲为”直接读写内存、调用BIOS、操作端口。要真正理解8086/8088 CPU的寻址方式、中断机制、硬件交互一个原汁原味的DOS环境几乎是不可替代的。所以我们的目标很明确在现代电脑上用虚拟机“复活”一个经典的DOS系统。我选择了VMware Workstation Player和FreeDOS这个组合。VMware Player是免费的对个人用户非常友好FreeDOS是开源的完全兼容经典的MS-DOS而且还在持续更新。搭建好这个环境后你写的汇编程序就能像30年前一样在“真实”的硬件上运行和调试了。这不仅仅是怀旧更是深入理解计算机工作原理的绝佳实践。2. 第一步准备好你的“时光机”——VMware与FreeDOS工欲善其事必先利其器。我们先来搞定两样核心工具虚拟机软件和DOS系统镜像。2.1 获取免费的VMware Workstation Player别被“虚拟机”这个词吓到你可以把它理解成一个超级逼真的“电脑模拟器”。我们在这个模拟器里安装DOS完全不会影响到你电脑本身的Windows或macOS系统。访问官网打开浏览器搜索“VMware Workstation Player下载”或者直接访问VMware官网。找到“产品”或“下载”区域。选择免费版本VMware提供了功能强大的收费版Workstation Pro和完全免费的Player版。对于我们搭建学习环境来说Player版的功能绰绰有余。找到“VMware Workstation Player”的下载链接。下载安装选择对应你操作系统的版本比如Windows 64位下载那个大约500多MB的安装包。下载完成后双击运行安装过程基本就是一路“下一步”。有个“增强型键盘驱动程序”的选项如果你不涉及特别复杂的安全场景可以不勾选保持安装简洁。安装完成后桌面上会出现VMware Workstation Player的图标我们的“时光机”外壳就准备好了。2.2 下载开源的FreeDOS系统接下来是“时光机”的核心——操作系统。我们不用去找古老的MS-DOS安装盘直接用开源的FreeDOS。前往FreeDOS官网搜索“FreeDOS”进入其官方网站。在首页你应该能很容易找到“Download”或“Get FreeDOS”的按钮。选择“软盘版”官网提供了几种安装镜像。对于学习汇编我们不需要带图形界面或一大堆工具的全功能版。我强烈推荐下载“FreeDOS 1.3 Floppy Edition”。这个版本非常纯粹通过多张软盘镜像来安装整个过程能让你更清晰地理解早期计算机的安装逻辑而且压缩包只有20多MB下载飞快。解压并找到镜像文件下载后得到一个压缩包解压出来。你会看到几个文件夹名字是120m、144m、720k这代表了不同容量的软盘规格。为了方便我们选择容量最大的144m文件夹。进去后你会看到6个以.img结尾的文件比如x86BOOT.img、x86DSK01.img等。这些就是我们的“虚拟软盘”安装时需要按顺序“插入”虚拟机。3. 第二步手把手创建你的第一台DOS虚拟机有了工具和系统现在开始组装我们的“时光机”。打开刚刚安装好的VMware Workstation Player。3.1 创建新虚拟机与关键配置点击主界面上的“创建新虚拟机”。这时会弹出一个向导。安装来源选择这里有个关键点因为我们下载的是软盘镜像.img文件而不是常见的ISO光盘镜像所以不要选择“安装程序光盘映像文件”。我们应该选择“稍后安装操作系统”然后点击“下一步”。选择客户机操作系统在“客户机操作系统”里选择“其他”在“版本”下拉菜单中选择“MS-DOS”。没错虽然我们装的是FreeDOS但VMware把它归为MS-DOS兼容系统选这个就行。命名与位置给你的虚拟机起个名字比如“MyFreeDOS”。然后选择一个位置来存放这个虚拟机的所有文件建议放在一个剩余空间较大的磁盘分区。指定磁盘容量虚拟机硬盘大小默认2GB就完全足够了。为了管理方便我建议选择“将虚拟磁盘存储为单个文件”。核心步骤添加软盘驱动器在最终完成前先别急着点“完成”。点击“自定义硬件...”。在弹出的硬件设置窗口里点击左下角的“添加”按钮。在硬件类型列表中找到并选择“软盘驱动器”然后点击“完成”。这样我们就为虚拟机添加了一个虚拟软驱。3.2 配置软驱并开始安装添加完软驱后在硬件列表中找到它并选中。连接启动软盘在右侧勾选“启动时连接”。然后在“软盘映像文件”处点击“浏览”找到你刚才解压的144m文件夹选择第一个文件x86BOOT.img。这相当于把第一张启动软盘插进了虚拟机的软驱。完成并启动关闭硬件设置窗口回到主向导点击“完成”。现在你的第一台DOS虚拟机就创建好了。在VMware主界面选中它点击“开启此虚拟机”。虚拟机启动后会自动从软驱A启动屏幕上开始滚动FreeDOS的安装文本。整个过程都是文字界面你需要做的就是仔细看提示并在需要确认时输入“Y”代表Yes然后回车。当安装程序提示你插入下一张磁盘时安装就正式开始了。3.3 完成多张软盘的安装过程这才是最体现“复古”味道的一步。安装程序会依次要求你插入6张软盘。切换软盘当屏幕提示需要下一张盘时你需要将鼠标从虚拟机中移出来按CtrlAlt组合键。然后点击VMware菜单栏的“Player” - “管理” - “虚拟机设置”。更换镜像文件在设置窗口的硬件列表里再次选中“软盘驱动器”。在右侧点击“浏览”将当前的x86BOOT.img换成144m文件夹里的下一个文件比如x86DSK01.img。点击“确定”。继续安装回到虚拟机窗口按任意键安装程序就会读取这张新“软盘”的内容。重复这个过程直到换到x86DSK05.img。最后的“陷阱”当x86DSK05.img读取完毕后屏幕可能会提示“not bootable floppy”。别慌这是正常的。你需要再次打开虚拟机设置把软盘映像文件换回最开始的那张x86BOOT.img然后回到虚拟机按任意键。完成这最后一步FreeDOS系统就正式安装到你的虚拟硬盘里了。安装完成后系统会提示你移除所有软盘并重启。这时你可以在虚拟机设置里取消勾选软驱的“启动时连接”或者直接移除这个软盘驱动器以后启动就会直接从虚拟硬盘启动了。恭喜你一个纯粹的DOS世界已经构建完成4. 第三步在DOS虚拟机里编写和运行你的第一个汇编程序系统有了接下来就是重头戏让我们的汇编代码在这个“复古”环境里跑起来。这里会遇到一个现实问题怎么把我们在Windows下写好的.asm文件或者编译好的.exe文件弄进虚拟机里我试过网上说的各种共享文件夹、磁盘映射的方法在FreeDOS虚拟机里基本都行不通。最可靠、最复古的方法恰恰是最原汁原味的制作一张“程序软盘”。4.1 制作你的“程序搬运软盘”我们需要一个工具来创建和编辑软盘镜像文件。我推荐使用WinImage它非常小巧易用。创建空白镜像打开WinImage点击“文件”-“新建”。在弹出的格式选择中选择标准格式“1.44 MB”。放入你的“家当”现在你得到了一张空的1.44MB虚拟软盘。把你写好的汇编源文件比如hello.asm直接拖进WinImage的窗口。更重要的是你需要把汇编编译器MASM.EXE或TASM.EXE和链接器LINK.EXE也拖进去。为了方便调试务必再把DEBUG32.EXE也放进去。注意在FreeDOS里要用DEBUG32.EXE用普通的DEBUG.EXE可能会报版本错误。保存镜像点击“文件”-“保存”给文件起个名字比如myprog.flp。关键点来了保存类型要选择“All files (.)”然后在文件名里手动输入后缀.flp。FreeDOS对.img和.flp格式的识别最好。4.2 在虚拟机中加载并运行程序现在把这张“软盘”插入你的DOS虚拟机。添加第二个软驱关闭虚拟机电源进入“虚拟机设置”。再次点击“添加”选择“软盘驱动器”。这样虚拟机就有了两个软驱A和B。将新软驱的映像文件指向你刚做好的myprog.flp并确保勾选“启动时连接”。启动并切换盘符启动虚拟机进入FreeDOS。默认你会处在A盘系统盘的根目录。输入B:然后回车就切换到了B盘也就是你刚插入的“程序软盘”。查看文件输入dir回车你应该能看到hello.asm、masm.exe、link.exe和debug32.exe这几个文件。编译、链接、运行经典的DOS命令行操作来了编译masm hello;注意分号表示使用默认选项不再提问链接link hello;运行直接输入hello回车。如果一切顺利你就能在屏幕上看到程序输出的结果了那种在“真实”DOS环境下成功运行自己汇编程序的成就感是在现代模拟器里无法比拟的。4.3 使用DEBUG32进行调试调试是学习汇编不可或缺的一环。在B盘下输入debug32 hello.exe回车就进入了调试界面。你可以使用r查看寄存器u反汇编代码t单步执行d查看内存数据。这些命令和王爽书里讲的debug命令几乎一样让你能清晰地看到每一条指令执行后CPU寄存器、内存和标志位的变化对理解程序运行机制有巨大帮助。5. 深入探索在DOS实模式下操作“硬件”搭建这个环境终极目的就是为了实践那些在现代系统上被禁止的操作。这里我分享两个最经典的实验也是我当初学习时的重点和难点。5.1 实验一通过BIOS中断读写“软盘”在DOS实模式下我们可以通过int 13h中断来访问磁盘。下面的程序片段演示了如何读取软盘A驱动器号0的第一个扇区到内存中。assume cs:code data segment buffer db 512 dup(0) ; 准备512字节的缓冲区 data ends code segment start: mov ax, data mov es, ax ; ES:BX 指向数据缓冲区 mov bx, offset buffer mov ah, 02h ; 功能号读扇区 mov al, 1 ; 要读取的扇区数 mov ch, 0 ; 柱面号 mov cl, 1 ; 扇区号从1开始 mov dh, 0 ; 磁头号 mov dl, 0 ; 驱动器号 (0 软盘A) int 13h ; 调用BIOS磁盘服务 ; 检查是否成功 (CF0表示成功) jc read_error ; 读取成功数据已在buffer中 ; ... 处理数据的代码 ... read_error: ; 处理错误的代码 ... mov ax, 4c00h int 21h code ends end start关键点与踩坑经验驱动器号DL寄存器指定驱动器。00h和01h通常代表软盘A和B。对于虚拟机中的软盘通常就是0。只能读不能写这是我踩过的一个大坑。在VMware的FreeDOS虚拟机里使用int 13h的写扇区功能AH03h向软盘镜像写入数据有时会失败。这很可能是因为VMware出于安全考虑默认将软盘镜像设置为只读或者FreeDOS本身对磁盘写入有更严格的限制。一个变通方法是在创建软盘镜像时确保其在宿主机Windows有写入权限并且在虚拟机设置中不要勾选“只读”。扇区、柱面、磁头这是古老的CHS寻址方式。对于1.44MB软盘它有80个柱面0-792个磁头0-1每个磁道18个扇区1-18。总共80218*512字节 ≈ 1.44MB。5.2 实验二直接操作硬盘端口除了BIOS中断汇编语言更底层的魅力在于可以直接通过in和out指令与硬件端口对话。下面是一段尝试通过硬盘端口1F0h-1F7h读取数据的代码框架。read_sector_by_port: ; 假设要读取硬盘0主盘的某个LBA扇区 push ax push dx push cx ; 设置要读取的扇区数 (端口 1F2h) mov al, 1 mov dx, 01F2h out dx, al ; 设置LBA地址的低24位 (端口 1F3h, 1F4h, 1F5h) mov al, 0 ; LBA 7-0 mov dx, 01F3h out dx, al mov al, 0 ; LBA 15-8 mov dx, 01F4h out dx, al mov al, 0 ; LBA 23-16 mov dx, 01F5h out dx, al ; 设置设备和LBA高4位 (端口 1F6h) ; 高4位: 1110 表示LBA模式主盘 mov al, 11100000b mov dx, 01F6h out dx, al ; 发送读命令 (端口 1F7h) mov al, 20h mov dx, 01F7h out dx, al ; 等待硬盘准备就绪 (检查端口1F7h的状态位) .wait_ready: in al, dx and al, 10001000b ; 检查BSY位和DRDY位 cmp al, 00001000b ; DRDY1且BSY0 jne .wait_ready ; 从数据端口(1F0h)读取512字节数据 mov cx, 256 ; 512字节 / 2 (每次读一个字) mov dx, 01F0h mov di, buffer_offset ; 假设ES:DI指向缓冲区 .read_loop: in ax, dx stosw ; 存储到ES:[DI]并递增DI loop .read_loop pop cx pop dx pop ax ret重要提醒与经验 这段代码在VMware的FreeDOS虚拟机里很可能无法成功执行。原因在于现代虚拟机呈现给Guest OS即FreeDOS的硬盘控制器已经是高度虚拟化的、符合现代标准的设备如SATA或SCSI控制器而不再是古老的IDE控制器。因此向1F0h等传统IDE端口发送命令虚拟机可能无法正确响应甚至直接忽略。这个实验的意义在于理解原理。它展示了在没有操作系统帮助的情况下程序如何以最原始的方式与硬件通信。虽然在这个特定环境里可能不成功但这份对端口I/O、状态轮询的理解是学习驱动开发、嵌入式系统乃至操作系统内核的宝贵基础。你可以尝试在更古老的虚拟机软件如Bochs它专门模拟老硬件或者真正的老机器上验证这段代码。6. 环境搭建的实用技巧与避坑指南根据我自己的折腾经验这里总结几个能让你的复古编程之旅更顺畅的小技巧。技巧一高效的文件交换每次都制作软盘镜像太麻烦。一个更高效的方法是在Windows下用你喜欢的编辑器比如VS Code写汇编代码然后用一个批处理脚本自动调用MASM和LINK进行编译链接生成.exe文件。最后只需要把这个最终的.exe文件拖进WinImage打开的软盘镜像里保存即可。这样在虚拟机里只需要运行这一个文件。技巧二配置方便的调试环境把常用的调试命令写成脚本。比如在DEBUG32里你可以用-命令来执行一个脚本文件。你可以创建一个文本文件debug_script.txt里面写上u 100 g然后在DEBUG32里用debug32 hello.exe debug_script.txt来启动并自动执行反汇编和运行到断点的命令。技巧三虚拟机性能与兼容性内存给FreeDOS分配16MB或32MB内存就足够了分配太多反而可能引发一些兼容性问题。显示模式FreeDOS默认是文本模式。如果你想尝试图形编程比如直接写显存0xB8000做彩色字符或者用0xA0000做VGA图形需要在虚拟机设置里将显卡类型设置为“VGA”而不是“自动检测”。网络除非你需要从DOS访问网络资源比如下载文件否则完全可以不安装虚拟网卡让系统更纯粹。最大的坑心态调整学习汇编和操作底层硬件一定会遇到各种“莫名其妙”的失败。程序没反应、虚拟机报错、结果不符合预期这些都是常态。我当初为了一个磁盘读写功能在各种环境和配置里折腾了整整五天。重要的是把每一次失败都当成学习的机会去查手册理解每个寄存器的含义每条指令的作用每个端口的状态。当你最终在黑色的DOS屏幕上看到自己程序输出的字符或者成功读取到指定扇区的数据时那种穿透层层抽象、直接触摸到计算机脉搏的快乐是学习高级语言很难体会到的。这个由VMware和FreeDOS搭建起来的小小“时间胶囊”不仅仅是一个运行旧程序的工具。它是一个实验室让你可以安全地、可控地实践计算机科学中最基础、最核心的概念。从CPU寄存器、内存寻址到中断机制、硬件I/O书本上抽象的知识在这里变得触手可及。希望这份详细的指南能帮你顺利搭建起这个迷人的复古环境开启你的底层探索之旅。