我在旧书中研究了DOS的x86汇编编程,在关于中断的讨论中,我看到了13h。这本书说我可以用它来格式化一个驱动器。但不幸的是,在我的书中没有提供关于如何做到这一点的更多信息。
我变得非常好奇,并试图将它用于自己,但它不起作用。如何使用16位x86汇编在驱动器A:中格式化软盘?这样做很简单吗?我使用TASM编译和链接,并在MS-DOS中运行。
除了使用int 13h
之外,还有其他方法吗?
答案 0 :(得分:8)
int 13h
是执行此操作的合适方法,但您实际上使用它来调用ROM BIOS服务,而不是调用DOS服务。我不认为DOS提供任何格式化磁盘的服务。应用程序通常只使用OS提供的服务进行高级读/写操作,将FAT的低级操作留给操作系统。
具体而言,int 13h
,服务05h
格式化磁盘轨道。 (当您调用中断时,服务编号会进入AH
寄存器。)请注意,此服务会格式化单轨,而不是整个磁盘。您必须多次调用此服务才能格式化整个磁盘。关于这一点的好处是,它允许您为每个轨道指定不同的特征 - 甚至是轨道上的每个扇区(一些老式的复制保护方案通过创建具有古怪格式的轨道来使用它)。
服务05h
的参数与其他每个磁盘读/写服务的参数基本相同,只是您不需要指定扇区号(通常在CL
中传递),因为你不能格式化个别部门。这是软盘服务所需参数的列表:
DL
DH
CH
CL
(不用于格式!)AL
ES:BX
如果中断返回并且进位标志(CF
)清零,则不会发生错误,AH
寄存器将包含0.如果设置了CF
,则发生错误, AH
寄存器包含错误代码。
用Peter Norton的话说,来自新程序员的IBM PC和PS / 2指南:
软盘轨道上的每个扇区都有4个与之关联的描述性字节。通过创建一个4字节组的表并将表的地址传递给寄存器对
ES:BX
,可以为要格式化的每个扇区指定这4个字节。格式化磁盘磁道时,4字节组会立即写入磁盘中磁道的各个扇区前面。与磁盘上扇区相关联的4字节数据称为地址标记,并由磁盘控制器用于在读取,写入和验证操作期间识别各个扇区。 4个字节称为圆柱体C,头部为H,记录(或扇区编号)为R,每扇区字节数为N(也称为尺寸代码)。当正在读取或写入扇区时,软盘控制器在软盘轨道中搜索扇区的ID,其中必要部分是R,记录或扇区号。此地址标记中实际上不需要气缸和磁头参数,因为读/写磁头机械定位在适当的轨道上,并且电子选择侧面,但它们作为安全检查进行记录和测试。
尺码(N)可以采用以下四种标准值中的任何一种:
N | Sector Size (bytes) | Sector Size (KB) –––––|–––––––––––––––––––––|––––––––––––––––– 0 | 128 | 1/8 1 | 256 | 1/4 2 | 512 | 1/2 3 | 1024 | 1
正常设置是代码2(512字节)。
格式化软盘轨道的完整过程相当复杂,涉及的不仅仅是调用服务05h
。您需要执行以下操作:
致电服务17h
以设置要格式化的软盘类型。 (这只需要在开始操作之前完成一次。)
致电服务18h
以设置格式的媒体类型。
按照上面引文中描述的方式为要格式化的曲目创建地址标记表。每个扇区的表格中必须有一个4字节的条目。
最后,致电服务05h
以格式化曲目。
或者,通过调用服务04h
进行跟进,以验证格式化过程。这将验证可以找到和读取扇区,以及循环冗余校验(CRC)是否正确。 DOS的format.com
执行此操作以在格式化之后验证每个轨道,但磁盘驱动器通常足够可靠,以至于不需要验证。
所有这些磁盘I / O服务都使用与上面列出的相同的参数,但是,与服务05h
一样,其中一些可能会被忽略。在线搜索中断指南以获取更多详细信息。例如,here is a complete list of ROM BIOS disk I/O services。并且here is another。 Peter Norton的上述指南也非常出色,如果你能找到一个旧版本,就像maybe Amazon那样?
(请注意,格式化硬盘的情况略有不同,对于PS / 2中的ESDI驱动器,您必须使用完全不同的服务进行格式化 - 1Ah
。)
更新:事实证明,可能有一个DOS API可以执行此操作。不幸的是,我不知道它确实让事情变得更加简单。关键是使用IOCTL。
IOCTL API由DOS定义,但它实际上是由设备驱动程序实现/处理的,这意味着支持由驱动程序供应商和版本而不是DOS版本决定。如果你正在使用VM环境,它应该支持这个,但我还没有真正测试过它。
DOS函数44h
是设备I / O控件(IOCTL),因此在调用AH
(DOS中断)之前将44h
设置为INT 21h
。
要格式化,您需要IOCTL用于块设备。块IOCTL函数至少需要DOS 3.2或更高版本(有些版本需要甚至更高版本)。它们不仅允许一次访问整个轨道,还支持格式化功能。他们使用子功能0Dh
进行访问,因此您需要将AL
设置为0Dh
。
将这些放在一起,您只需将AX
设置为440Dh
并致电INT 21h
即可。格式函数的次要代码为42h
,位于CL
。
总之,用于格式化逻辑驱动器上的轨道的DOS块IOCTL函数将被调用如下:
AX
== 440Dh
CL
== 42h
CH
== 08h
(阻止设备类别)BX
==驱动器号码(0 =默认值,1 = A:,2 = B:等等)DS:DX
== IoctlFmtVrfyTrackRec
结构的地址,表示要格式化的头部和柱面编号如果函数返回时设置了进位标志,则AX
包含错误代码。
不幸的是,除了this page之外,我无法在线找到IoctlFmtVrfyTrackRec
的任何文档。这些东西早于网络,很少上传到那里。 :-(你真的需要一本像Advanced MS-DOS Programming这样的书,我也没有这本书的副本。
我 设法出现this document on Scribd,声称是使用IOCTL格式的实现,由Pierre Desloover编写。我还没有测试过它。