最近参加三个一学习活动,学到了十七章,由于之前的实验都是在Windows系统下进行的,非常顺利,但这次实验让我吃了鳖,花了两天时间才找到一个不是特别令人满意的解决方案。所以打算记录在本博客,涨涨教训。
首先,阐述一下实验背景和环境,学习汇编语言的环境大多都是Windows或Liunx系统下,使用Dosbox0.74以及汇编语言三件套(masm,link,debug)环境,的确,一般程序只需要这种环境就可以编写大多数程序了,但基于保护模式的操作系统的运行机制和DOS的实模式却有着很大的区别,比如中断向量表的加载.
我们先整理一下书上关于操作系统启动时的内容(16位系统):
开机后,CPU自动进入到FFFF:0单元处执行,此处有一条跳转指令,CPU执行该指令后,转去执行BIOS中的硬件系统检测和初始化程序。
初始化程序将建立BIOS所支持的中断向量,即将BIOS提供的中断例程的入口地址登记在中断向量表中。
硬件系统检测和初始化完成后,调用 int 19h 进行操作系统的引导。
如果设为从软盘启动操作系统,则int 19h将主要完成以下工作。
(1)控制0号软驱,读取软盘0道0面1扇区的内容到0:7c00;
(2)将CS:IP指向0:7c00.
软盘的0道0面1扇区中装有操作系统引导程序。int 19h将其装到 0:7c00处后,设置CPU从0:7c00开始执行此处的引导程序,操作系统被激活,控制计算机。
如果0号软驱中没有软盘,或发生软盘I/O错误,则int 19h将主要完成以下工作。
(1) 读取硬盘C的0道0面1扇区的内容到0:7c00;
(2) 将CS:IP指向0:7c00
以上就是《汇编语言》中关于电脑开机时的动作的描述,当只是一段简短的描述,但从中可以看到中断向量在开机时将会被登记到中断向量表。在所有内中断中,除法溢出中断是最经典的,因为它是登记在中断向量表中的第一个中断例程,在第十二章的示例中,我们就见识到了发生除法溢出中断时将发生什么,但实际操作时,真正如此吗?
这里我将演示三个不同系统下的结果(Win10,Ubuntu,Dos)
在Win10下
在Ubuntu下:
在Dos下:
很明显,这里只有Dos系统才正确加载了除法溢出的中断例程,其余两个都没有正确加载除法溢出的中断例程,发生了死循环 (这里可能是操作系统的问题,也可能是DosBox的问题,因为在DOS系统中我使用的系统自带的DEBUG程序)
到这里了,可能还有些疑问,为什么有的中断例程没问题呢?我记得调用过int 10h移动过光标吧,是可以使用的啊,如果中断向量表没有正确加载,那int 10h应该也用不了啊?
对于这点,我也在Dosbox模拟的DOS和DOS系统中做过实验,如下:
首先,准备好一致的执行代码:
mov ah,2 ;置光标功能
mov bh,0 ;第0页显存
mov dh,.5 ;行号
mov di,12 ;列号
int 10
mov ax,4c00
int 21
;因为我使使用debug -a写的代码,所以默认是16进制
执行结果不用说,两边都正确执行了代码,移动了光标,但是对于int 10h的调用过程呢?
是有区别的,放图如下:
Dosbox:
DOS:
可以看到,DOS中能看到正确的程序指令,而Dosbox中只有???,执行后立即返回,所以我觉得这里Dosbox虽然得到了正确的执行结果,但没有给出执行过程,虽然我不太理解这里,但就DOS和Dosbox的区别可以察觉到这可能是保护模式和实模式之间的区别。DOS系统是工作在实模式下的,而Dosbox是工作在保护模式下的DOS系统模拟程序。
好了,开始主题了,在第17章,任务是使用 int 13h对磁盘进行读写,我已经在Windows和Liunx系统上试过了,是不可行的,只有在DOS系统中才能正确执行 int 13h
(我作死的试过直接朝80h(C盘,返回结果ah=00,但C盘并没有被损坏,系统也能正常启动,证明该指令并没有朝磁盘C写入数据)
所以,想做这个实验所如下几个需求:
1.需要制作一个虚拟软盘
2.需要虚拟机环境和DOS系统映像
目前主流的虚拟机有Oracle VM VirtualBox和VMware两款,前者是免费并开源的,后者是付费使用(可免费使用30天),我更偏向于前者,因为前者体积更小,启动速度更快,虽然功能和运行时性能略输于后者但在做做小实验和部署小项目的需求条件下,已经足够了。
使用Oracle VM VirtualBox作为虚拟机:
1.首先,得下载Bochs用于创建虚拟软盘,创建软盘的过程可参考:https://blog.csdn.net/sinzou1/article/details/5905813
创建的软盘作为实验软盘,即为用于读写的软盘
2.下载DOS系统映像,和安装其它操作系统一样,安装DOS也需要映像文件,只不过DOS系统比较小,一般装在软盘中
即可,所以在该网站中下载DOS软盘映像文件,地址:http://www.cn-dos.net/newdos/dosart32.htm
3.启动Oracle VM VirtualBox,创建DOS系统,在设置->系统中调整第一启动项为软盘,再将下载的压缩包解压,里面会存在DOS71_1.IMG的映像文件,另外一个映像是该系统的拓展,可以不用安装。
4 继续在该虚拟机的设置中添加软盘控制器,将系统映像文件添加进去,并且为该虚拟机添加一个虚拟硬盘(这里注意不能分配过大的空间,否则系统不认,分配百兆内即可),设置完毕后启动该虚拟机,将会进入DOS安装向导,一路回车安装即可。
5.安装成功后就可以将该映像文件取下来,将第一步的实验用的img文件放上去了,这里得注意,再次使用该DOS系统时请设置第一启动项为硬盘,因为系统已经安装到硬盘上不需要从软盘启动了
6.成功安装DOS后,再就是创建实验环境了,本次汇编实验需要使用Masm,Link,Debug,edit等工具,所以得把这些工具安装到虚拟机上才行,怎么做呢?我这里有两种方法
1.使用共享文件夹,把DOS需要的东西直接从主机复制过去即可(这个没试过)
2.在另外一个系统的虚拟机上创建虚拟硬盘,然后把需要的文件复制过去,再在DOS系统上设置该虚拟硬盘为第二主硬盘即可
注:DOS自带DEBUG,平时使用得DEBUG软件不适用于该系统,所以无需使用平时实验所用的debug.exe
PS:其实也可以直接将安装盘格式化为实验用软盘,反正一次性 = =,不过开始我没注意到,在Windows和Liunx下试了好久,才发现DOS是唯一的选择。
后记:之后发现在XP系统下有DOS子系统,可以直接Win+R运行Command命令进行DOS操作。