【问题标题】:How to format a floppy diskette in DOS using 16-bit assembly?如何在 DOS 中使用 16 位汇编格式化软盘?
【发布时间】:2017-01-05 16:10:18
【问题描述】:

我在我的旧书中学习 DOS 的 x86 汇编编程,在关于中断的讨论中,我看到了 13h 那个。书上说我可以用它来格式化驱动器。但不幸的是,我的书中没有提供更多关于如何做到这一点的信息。

我变得很好奇,并试图自己使用它,但它不起作用。如何使用 16 位 x86 程序集格式化驱动器 A: 中的软盘?做起来简单吗?我用TASM编译链接,在MS-DOS下运行。

也许除了使用int 13h之外还有其他方法?

【问题讨论】:

  • 为帮助防止问题被关闭,请编辑您编写并尝试过但不起作用的代码。
  • 已修复,谢谢。 @Joshua 我确实想学习汇编,我喜欢编程。
  • @MendaxRox:从一个更简单的问题开始。任何语言都很难格式化软盘。
  • 这里的格式化有点含糊:你的意思是低级格式化还是只想在软盘上写一个FS?
  • @MendaxRox 哈哈……那个时代几乎没有这样的作品。通常所有与硬件设计相关的东西都融入到软件设计中(以使控制器/API 方面的事情保持简单),如果您考虑硬件设计本身,那么许多“他们为什么这样做”将是显而易见的,但是当你只看到 SW 方面时,它往往处于反逻辑的边缘。 (正确地)假设,在代码方面解决任何不幸的复杂性会比添加更多的电线/芯片/存储单元更容易+更便宜。在其他机器上,您必须打开/关闭电机并计算 R/W 的时间。 :)

标签: assembly x86 dos x86-16 floppy


【解决方案1】:

int 13h 是执行此操作的适当方式,但您实际上不是调用 DOS 服务,而是使用它来调用 ROM BIOS 服务。我不认为 DOS 提供任何格式化磁盘的服务。应用程序通常将这种对 FAT 的低级操作留给操作系统,只使用操作系统提供的服务来执行高级读/写操作。

具体来说,int 13h, service 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。您需要执行以下操作:

  1. 致电服务17h 设置要格式化的软盘类型。 (这只需在开始操作之前完成一次。)

  2. 调用服务18h设置格式的媒体类型。

  3. 按照上面引用中描述的方式,为要格式化的轨道创建一个地址标记表。每个扇区的表中必须有一个 4 字节的条目。

  4. 最后,调用service05h格式化音轨。

  5. 或者,通过调用服务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 的版本决定。如果你使用的是虚拟机环境,它应该支持这个,但我还没有实际测试过。

DOS 函数 44h 是设备 I/O 控制 (IOCTL),因此您在调用 INT 21h(DOS 中断)之前将 AH 设置为 44h

要格式化,您需要 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,它声称是由 Pierre Desloover 编写的使用 IOCTL 的格式实现。我没有测试过。

【讨论】:

  • 在 Internet 上的某个地方我可以找到格式化软盘的程序示例吗?我是大会的新手,我阅读了所有内容,但我听不懂:(。而且英语不是我的第一语言,所以它更难。谢谢......
  • 我用谷歌浏览了一下,但没有看到任何预先编写的代码示例。应该是非常简单的代码,在寄存器中设置参数并调用中断。棘手的部分是摆桌子。我目前没有时间编写代码,也没有可以测试它的虚拟机。
  • 我从 MS-DOS 查看了 format.com 的来源。如何在不使用单个中断的情况下格式化 HD 和软盘? :o
  • 我相信 format.com 实际上委托给较低级别​​的 API 来完成工作。至少,这就是它在 DOS 2 中的工作方式(当然,按照 DOS 标准,它甚至不是现代的),但这是我见过的唯一一个源代码(MS 几年前发布它供公众查看)。我没有拆解任何更新的版本来查看发生了什么变化。在 DOS 2 中,format.com 调用由 OEM 系统供应商提供的功能。我猜这在后来的版本中发生了变化,因为微软对源代码进行了更严格的控制。我打赌那里的某个地方有中断......
  • 这里是Ralph Brown's Interrupt List。这是他多年来收集的一个非常庞大的函数列表。你可能需要它。
猜你喜欢
  • 2017-05-18
  • 2017-05-17
  • 1970-01-01
  • 2012-07-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多