迈向 MS-DOS 7 下的系统编程的第一步/精选中断处理程序
第 8 章。精选中断处理程序
在某些情况下,需要中断 CPU 的正常操作顺序,以响应紧急请求。中断可以由硬件和软件发起。CPU 在发生意外错误(异常)时会调用中断。其他硬件设备通过中断控制器线路 IRQ 00 – IRQ 15 发送其中断请求。程序使用 INT 命令 (7.03-28) 引起“软件”中断。在任何情况下,中断都会导致执行特定的中断处理程序子程序,该子程序执行请求的操作。
大量的中断处理程序从计算机开机开始就永久地存在于计算机内存中。这些处理程序可以看作是标准子程序库。编程工作的有效性很大程度上取决于您在使用此库方面的技能。
中断处理程序的入口点地址存储在中断表中。CPU 的实模式和保护模式使用不同的中断表。
保护模式中断表填充了 8 字节描述符,指定中断处理程序和 API 服务的访问权限和入口点地址。中断处理程序的选择、其排列以及中断表在内存中的放置是任意的,由该程序或该操作系统控制,该程序或该操作系统在保护模式下控制计算机的运行。
相反,实模式中断表是严格制度化的。在所有 AT 兼容计算机中,它占据相同的内存区域,从 0000:0000h 到 0000:03FFh。它不是由描述符填充,而是由中断处理程序入口点的 4 字节地址填充。特定 BIOS 功能的统一地址放置构成了软件兼容性的基础。后一种特性定义了实模式中断表的重要作用,并引起了我们对其的特殊兴趣。
将 CPU 切换到保护模式后,实模式中断表会完好无损地保留,并且仍然可以访问。实模式中断处理程序可能需要用于特定的主板硬件和执行 DOS 功能,这些功能由“DOS 盒”中的程序调用。在执行实模式中断处理程序期间,保护模式操作系统将 CPU 切换回实模式。由于这些隐藏的操作,"DOS 盒"内的 DOS 程序的执行速度要比实模式下慢得多。
实模式中断表中任何所需地址的偏移量由中断号乘以 4 自动计算得出。每个地址都是一个双字指针,应该以相反的顺序解释:第四和第三个字节构成段地址,第二个和第一个字节构成入口点偏移量。例如,转储 59 F8 00 F0 对应于处理程序的入口点地址 F000:F859h。
任何中断请求都意味着提交的地址指向处理程序可执行代码的入口点。但是,也有一些例外:实模式中断表中的偏移量 0074h、0078h、007Ch、0104h、010Ch、0118h 指向不可执行的数据表 (A.12-1)。相应的编号 1Dh、1Eh、1Fh、41h、43h、46h 不能用于枚举中断。
中断表部分由 BIOS 填充,通常填充到 INT 1C。MS-DOS 7 的核心添加了自己的指针(最著名的是 INT 20 - INT 2E),后来几乎每个驱动程序都设置了指向其自身处理程序的双字 (dword) 指针。在每一步,任何先前加载的指针都可能被替换;有些指针被覆盖了两次以上。因此,中断可能会被新的处理程序拦截。大多数情况下,中断拦截是为了提供对新功能的条件访问,否则会将调用重新定向到以前的处理程序。对于大部分中断,无法确定它们的处理程序是属于 BIOS 还是 DOS 还是其他程序:这可能取决于您 PC 中的特定配置设置。
由于中断处理取决于 PC 的 BIOS,并且可能由软件更改,因此 MS-DOS 7 无法保证其永远严格定义。在几乎任何中断调用之后,都需要检查结果的有效性。然而,存在大量 API 函数,为了兼容性原因而保持完好无损,并且几乎可以肯定会在 MS-DOS 7 下的任何 PC 中遇到。本章下面介绍了调用此类函数的选定中断调用。
8.01 由 PC 的 BIOS 加载的中断处理程序 (INT 00 – INT 1C)
[edit | edit source]8.01-01 INT 00 – 除以零错误
[edit | edit source]如果在执行 DIV (7.03-21) 或 IDIV (7.03-24) 命令后商溢出结果寄存器,则 CPU 会生成对 INT 00h 处理程序的调用。默认的 INT 00 处理程序会终止当前程序的执行,显示一条消息:“您的程序导致了除法溢出错误…”,并将控制权转移到 DOS。
注 1:如果由 CPU 发起对 INT 00 处理程序的调用,则 CPU 会在堆栈中留下一个返回地址,该地址不是指向下一个命令,而是指向导致溢出的除法命令。
8.01-02 INT 01 – 单步中断
[edit | edit source]如果标志寄存器中的陷阱标志 TF (A.11-4) 被设置,则 CPU 会在执行每个命令后调用 INT 01 处理程序。此功能用于逐行跟踪程序的执行。此外,从 80386 开始的现代 CPU 具有内部调试寄存器 (A.11-5),每次 CPU 访问预定义的内存区域或预定义的端口时,都会调用 INT 01 处理程序。INT 01 处理程序也可能由未公开的代码 F1h 调用。
PC 的 BIOS 系统没有安装 INT 01 处理程序的地址,而是安装了对 IRET 命令 (7.03-30) 的引用,该命令只是将 CPU 返回到下一个命令的执行。
调试工具必须在中断表中用它们自己的处理程序的地址替换此引用,以便将控制权转移到启动程序测试执行的进程(例如,到调试器 DEBUG.EXE)。
注 1:陷阱标志 TF 在执行每个命令后被清除,但其原始状态(即在被清除之前的状态)会在 INT 01 处理程序被调用时与返回地址一起保存在堆栈中。因此,INT 01 处理程序的代码本身是在 TF 标志被清除的情况下执行的,但最终的处理程序命令 IRET 会从堆栈中恢复 TF 标志的原始状态。
注 2:在调用 INT 01 处理程序时保存在堆栈中的返回地址通常指向程序测试中的下一个命令。但是,当调试寄存器调用 INT 01 处理程序时,返回地址只指向满足预定义条件的命令。调试寄存器 DR6 (A.11-5) 中的标志可以用来区分 INT 01 调用的原因。
INT 02 处理程序的调用是由发送到 NMI(不可屏蔽中断)CPU 引脚的信号引起的。与其他硬件中断不同,通过 NMI 引脚的调用不能被 CLI 命令(7.03-12)或中断控制器中的掩码阻塞。INT 02 处理程序具有特殊任务:它响应紧急事故,例如内存故障。对于大多数此类事故,INT 02 处理程序会显示错误消息并停止进一步执行,使 CPU 停止运行。在许多 PC 中,发送到 NMI 引脚的信号会通知即将发生的电源故障的第一个症状。在这种情况下,INT 02 处理程序会采取紧急措施,旨在防止数据丢失,然后将控制权返回给被中断的进程:如果警报被证明是错误的,并且电源故障实际上没有发生,则该进程有机会恢复。
- 笔记
- 如果通过 OUT 命令(7.03-66)将一个第 7 位设置为 1 的字节发送到 CMOS 内存端口 70h,则可以暂时阻止对 CPU 的 NMI 引脚的调用。此操作意味着随后向端口 71h 发送另一个字节。[注释 A.14-1 的注释 1] 阻塞对 CMOS 内存访问期间的 NMI 请求可以防止 CMOS 数据失真。
当机器指令中第一个字节的位置遇到代码 CCh(7.03-28)时,处理器会生成对 INT 03 处理程序的调用。代码 CCh 通常由调试实用程序插入,以便在所需点(断点)停止被测程序的执行。特别是,调试器 DEBUG.EXE 就是通过这种方式设置断点的。
PC 的 BIOS 系统安装对 IRET 命令(7.03-30)的引用,而不是 INT 03 处理程序的地址,IRET 命令只是将 CPU 返回到下一个命令的执行。调试实用程序必须在中断表中将此引用替换为其自身处理程序的地址,该处理程序将用于处理 INT 03 调用。
与迫使立即响应溢出错误的中断 INT 00 不同,中断 INT 04 允许通过 INTO 命令(7.03-29)延迟响应溢出。遇到 INTO 命令的代码 CEh 时,处理器会检查溢出标志 OF 的状态:如果它没有被清除,则会调用 INT 04 处理程序。默认的 INT 04 处理程序只是将控制权返回给调用程序。每个程序都有机会用自己的 INT 04 处理程序替换默认的 INT 04 处理程序,从而为溢出错误提供所需的响应。
由于 IBM 和 Intel 的技术决策相互矛盾,INT 05 实模式处理程序被赋予了两个不同的任务。
在 IBM 兼容的 PC 中,BIOS 安装了中断 INT 05 处理程序,它将活动屏幕页面发送到打印机。打印过程由用户的 Shift-PrtSc 键击启动。INT 09 处理程序(8.01-09)识别此键组合后,会调用 IBM 的 INT 05 处理程序。后者会在 BIOS 数据区(A.12-1)中地址 0000:0500h 处检查打印机状态字节。打印机状态字节的状态具有以下含义:
- 00h – 打印机连接到 LPT1 端口并已准备就绪;
- 01h – 打印机繁忙,之前的任务尚未完成;
- FFh – 前一个对打印机的请求已失败。
如果状态字节处于 00h 状态,则活动屏幕页面将被发送到 LPT1 端口并被打印。
从 i80286 开始的英特尔处理器,如果 BOUND 机器指令(代码 62h)检测到边界违规,就会调用 INT 05 处理程序。显然,INT 05 处理程序的这一任务必须完全不同。
DEBUG.EXE “不认识” BOUND 命令,因此在第 7 章中没有描述它。为了避免在实模式下使用 BOUND 命令引起的冲突,相关程序必须安装自己的中断处理程序,这些处理程序能够处理调用源歧义问题。这个问题在保护模式下并不存在,因为保护模式的中断表重新排列,因此 INT 05 调用不再承担屏幕页面打印任务。
注释 1:原始的 INT 05 处理程序通常被另一个处理程序替换,该处理程序由视频卡提供,并由 PrtSc 键调用(8.01-66)。
注释 2:如果 BOUND 命令触发了对 INT 05 处理程序的调用,那么 CPU 在堆栈中留下的返回地址不是下一个命令的地址,而是 BOUND 命令本身的地址。此类调用不应指向 IRET 命令,因为 PC 将陷入无限的调用和返回循环中。
CPU 会以调用 INT 06 处理程序的方式响应对无效代码执行尝试,特别是对
- 处理器在实模式下工作时的保护模式命令;
- 对不写入内存的命令应用 LOCK 前缀;
- 为仅接受内存操作数的命令指定寄存器;
- CPU 无法识别的命令代码。
由于对 INT 06 处理程序的调用是由任何“未知”机器代码触发的,因此 INT 06 处理程序有时用于在配备有旧式 CPU 的 PC 上模拟现代 CPU 的命令。但默认的 INT 06 处理程序只是将控制权返回给调用程序中的下一个命令。
如果在控制寄存器 CR0(A.11-4)中其位 02h(“协处理器仿真”)被设置,CPU 会调用 INT 07 处理程序以响应尝试执行 ESC 命令(7.03-22)或任何协处理器的命令(7.04)。可以故意设置位 02h 以调用处理程序,该处理程序模拟协处理器的功能。一些 BIOS 系统会在那些没有配备算术协处理器的 PC 中自动执行此操作。
现代 PC 拥有集成在主 CPU 中的算术协处理器,因此不需要仿真协处理器的功能。因此,INT 07 处理程序可以承担另一个任务:对算术协处理器中未屏蔽的异常进行登记时采取适当的措施。为此,如果在控制寄存器 CR0(A.11-4)中位 01h 和 03h 都被设置,则 WAIT 前缀(7.02-05)可能会触发对 INT 07 处理程序的调用。为了忽略 WAIT 前缀,CR0 寄存器中的位 01h 应该被清除。
任何 INT 07 任务的实现都意味着加载相应的处理程序。默认的 INT 07 处理程序只是将控制权返回给调用程序中的下一个命令。
当 CPU 处于实模式时,INT 08 – INT 0F 中断处理程序组会响应通过 IRQ 0 – IRQ 7 线从各种设备发送到第一个中断控制器的请求。一些 IRQ 线有专门的硬件源,列在以下表格的第四列中,但其他 IRQ 线可以自由地接收来自任何设备的请求,这些设备已调整为通过这些线之一发送请求,并且受加载了对应中断处理程序的驱动程序的支持。
除了响应外部 IRQ 请求外,同一 INT 08 – INT 0F 组中的一些中断处理程序也可以由 CPU 调用,以处理某些特定的错误(异常)。这些异常可能会在实模式下引起对 INT 08 – INT 0F 处理程序的调用,在以下表格的注释中进行了描述。中断控制器不记录由 CPU 生成的中断调用。如果通过 OUT 命令(7.03-66)将字节 0Ah 发送到中断控制器的端口 20h,那么通过同一个端口 20h,IN 命令(7.03-26)将能够读取一个字节,该字节表示通过每个 IRQ 线接收了一个请求,通过设置对应位的 TRUE 状态来表示,这些位在以下表格的第三列中指定。对应位的清除状态表明该特定中断是由 CPU 启动的。
如果中断处理程序的调用是由异常引起的,那么 CPU 在堆栈中留下的返回地址不是下一个命令的地址,而是当前命令的地址,该命令引起了异常调用。这使得有机会重复操作,如果异常的原因可以消除,但是另一方面,这种调用不应该指向 IRET 命令,因为 PC 会陷入无限循环的调用和返回中。如果中断处理程序无法纠正这种情况,则必须通过终止执行或纠正堆栈中的返回偏移来阻止重复操作。除此之外,当处理程序执行其工作时,必须阻止通过中断控制器接收并发中断请求。这可以通过 OUT 命令(7.03-66)来完成,将一个掩码字节发送到端口 21h,该字节具有与并发 IRQ 线对应的位的 TRUE 状态,如以下表格的第三列所示。
中断 | 线 | 掩码 | 请求来源 | 注释 |
---|---|---|---|---|
INT 08 | IRQ 0 | 位 0 | 系统定时器 | 注释 *1 |
INT 09 | IRQ 1 | 位 1 | 键盘控制器 | 注释 *2 |
INT 0A | IRQ 2 | 位 2 | 第二个中断控制器 | 注释 *3 |
INT 0B | IRQ 3 | 位 3 | 注释 *4 | |
INT 0C | IRQ 4 | 位 4 | 串行端口 COM 1 | 注释 *5 |
INT 0D | IRQ 5 | 位 5 | 注释 *6 | |
INT 0E | IRQ 6 | 位 6 | 软盘驱动器控制器 | 注释 *7 |
INT 0F | IRQ 7 | 位 7 | 并行端口 LPT 1 |
注释 1: 对 INT 08 处理程序的调用每秒定期进行 18.2 次,以维持时间计数。反过来,INT 08 处理程序调用 INT 1C(8.01-96),为应用程序提供了拦截后者的机会。INT 08 处理程序也可以在发生“双重故障”异常的情况下由 CPU 调用,这通常会导致重新启动。
注释 2: INT 09 处理程序感知每个按键,控制键盘缓冲区并准备代码,如附录 A.02-1 中所示,并通过 INT 16 向应用程序呈现。但 INT 09 处理程序只对文章 1.01 中列出的几个键组合进行明确的立即操作。
注释 3: 第二个中断控制器通过线路 IRQ 8 – IRQ 15 接受中断请求,并引起对 INT 70 – INT 77 处理程序(8.03-75)的调用。
注释 4: IRQ 3 线中断请求的最可能来源是第二个串行端口 COM 2(如果存在)。
注释 5: INT 0C 处理程序也可以在发生“堆栈溢出”异常的情况下由 CPU 调用,此时堆栈超过其预定义的限制。
注释 6: INT 0D 处理程序可以在发生段限制违规异常的情况下由 CPU 调用,即尝试访问超出预定义段限制的代码或数据。
注释 7: 对 INT 0E 处理程序的调用可能是由 CPU 在响应尝试访问“关闭”内存页面(那些在 CPU 的 TLB 缓冲区中找不到的页面)时发起的。
注释 8: 将外部请求 IRQ 0 – IRQ 7 映射到对 INT 08 – INT 0F 处理程序的调用可以通过重新编程中断控制器来更改,以便外部请求不会调用那些旨在处理 CPU 异常的处理程序。这种重新编程通常在准备将 CPU 切换到保护模式的过程中进行,与为保护模式形成新的中断表相协调。
8.01-10 INT 10\AH=00h – 设置视频模式
[edit | edit source]准备:AH = 00h AL – 要设置的视频模式代码(A.10-1) 返回:AL 内容可能被更改
注释 1: 此函数将所有视频卡(包括现代视频卡)切换到与过时的 VGA 视频卡兼容的视频模式。现代 SVGA 视频模式应通过函数 INT 10\AX=4F02h 设置。
注释 2: 当前视频模式的代码写入 BIOS 数据区(A.10-6)地址 0040:0049h。
注释 3: 与鼠标指向设备参数切换相协调的视频模式切换可以由鼠标驱动程序执行,该驱动程序通过中断 INT 33\AX=0028h 调用。
注释 4: 视频模式的切换会导致屏幕变黑(变暗),持续时间长达 2 秒,视觉感知不舒服。因此,应避免过度切换视频模式。为了清除屏幕,应优先调用 INT 10\AH=06h(8.01-15)。
8.01-11 INT 10\AH=01h – 文本视频模式下的光标大小
[edit | edit source]准备:AH = 01h CH – 位 7, 6, 5: – 清零 – 位 0–4: – 光标最上面的行号 CL – 位 7, 6, 5: – 清零 – 位 0–4 – 光标最下面的行号
注释 1: 行是从上到下在当前字体高度内计数。光标最上面的行号和最下面的行号的当前数字写入 BIOS 数据区(A.10-6)地址 0040:0060h。当前字体高度可以通过调用 INT 10\AX=1130h 处理程序来确定,也可以直接从 0040:0085h 内存单元读取。
注释 2: 将 CH 寄存器中的位 5 设置为 TRUE 状态会使光标不可见。
8.01-12 INT 10\AH=02h – 设置光标位置
[edit | edit source]准备:AH = 02h BH – 屏幕页号(INT 10\AH=05h 的注释 1 和 2) DH – 行号(从 00h 开始计数 – 最上面的行) DL – 列号(从 00h 开始计数 – 最左边的列)
注释 1: 光标位置是为每个屏幕页面单独定义的。
注释 2: 最多 8 个屏幕页的光标坐标对写入 BIOS 数据区,从地址 0040:0050h 开始(A.10-6)。
8.01-13 INT 10\AH=03h – 确定光标的大小和位置
[edit | edit source]准备:AH = 03h BH – 屏幕页号(INT 10\AH=05h 的注释 1 和 2) 返回:CH – 光标大小最上面的行号 CL – 光标大小最下面的行号 DH – 行号(从 00h 开始计数 – 最上面的行) DL – 列号(从 00h 开始计数 – 最左边的列)
注释 1: 一些 BIOS 版本在 AX 寄存器中返回零。
8.01-14 INT 10\AH=05h – 选择活动屏幕页面
[edit | edit source]准备:AH = 05h AL – 请求的屏幕页号
注释 1: 如果请求的页号大于当前视频模式允许的最大页号,则 INT 10\AH=0Fh 函数将不会确认选择。VGA 视频模式允许的最大页号在 INT 10\AX=1B00h 函数(A.10-2,偏移 29h)返回的表格中显示,对于 SVGA 视频模式,则在 INT 10\AX=4F01h 函数(A.10-7,偏移 1Dh)返回的表格中显示。
注释 2: 屏幕页面从 00h 开始编号,因此允许的最大页号比屏幕页面的总数少 1。最流行的文本视频模式 03h 提供 4 个屏幕页面,编号从 00h 到 03h。
注释 3: 与鼠标光标切换到同一页面相协调的屏幕页面的选择可以由鼠标驱动程序执行,该驱动程序通过中断 INT 33\AX=001Dh(8.03-47)调用。
8.01-15 INT 10\AH=06h–07h – 在屏幕窗口上滚动
[edit | edit source]术语“滚动”表示在整个屏幕或“窗口”内上下移动显示的内容,即构成整个屏幕一部分的矩形区域。从“窗口”边框下方出现的行没有内容,只是用规定的颜色填充。给定 AL = 00h,滚动过程可以清除并用统一的颜色填充整个矩形“窗口”或整个屏幕。
准备: AH – 滚动方向: = 06h – 向上滚动, = 07h – 向下滚动 AL – 滚动行数(或 00h – 清空整个窗口) BH – 填充新行的颜色:位 0–3: – 清空为零,位 4–7: – 表 A.10-5 第 1 列中的颜色代码。 CH – 行, CL – 窗口左上角的列 DH – 行, DL – 窗口右下角的列
注意 1:滚动过程仅适用于文本视频模式。
注意 2:滚动过程仅影响活动屏幕页,其他屏幕页保持不变。
注意 3:从滚动过程返回后,某些 BIOS 版本可能会更改 BP 或 DS 寄存器的内容。
准备: AH = 08h BH – 屏幕页码(INT 10\AH=05h 的注释 1 和 2) 返回: AH – 颜色字节,如表 A.10-5 所示(仅在文本视频模式下) AL – 读取字符的 ASCII 代码
注意 1:在图形视频模式下,仅以白色前景像素绘制的字符才能正确识别。如果字符无法识别,则返回 AL = 00h。
准备: AH = 09h AL – 要显示的字符的 ASCII 代码 BH – 屏幕页码(INT 10\AH=05h 的注释 1 和 2) BL – 颜色字节,如附录 A.10-5 所示。 CX – 写入字符的重复次数
注意 1:所有符号都显示,包括 0Dh(CR)、0Ah(LF)、08h(BS)和其他特殊符号,这些符号在附录 A.02-8 中提到。
注意 2:在颜色少于 256 色的图形视频模式下,如果 BL 寄存器中第 7 位的 TRUE 状态被设置,则通过 XOR 逻辑运算将指定的字符写入视频内存。
注意 3:在图形视频模式下,CX 寄存器中指定的重复次数不得超过当前光标位置右侧同一行中的字符位置数。
注意 4:INT 10\AH=0Ah 处理程序以相同的方式显示字符,但会忽略 BL 中的颜色字节。显示的字符将与所有先前的屏幕内容具有相同的颜色。
注意 5:显示操作不会移动光标位置,并且不依赖于 CX 寄存器中指定的重复次数。
注意 6:对于 256 色图形视频模式(例如,在视频模式 13h 中),BH 寄存器必须指定背景颜色字节,而 BL 寄存器必须指定前景颜色字节。
对于图形视频模式,此函数定义背景颜色,但对于文本视频模式,它定义边框颜色。 准备: AH = 0Bh BX – 位 3–15: – 清空为零 – 位 2、1、0: – 对应于红色、绿色和蓝色颜色
注意 1:许多现代 LCD 显示器要么无法正确显示屏幕边框,要么根本不显示。
准备: AH = 0Ch AL – 像素的颜色字节(A.10-5) BH – 屏幕页码(INT 10\AH=05h 的注释 1 和 2) CX – 像素的列号 DX – 像素的行号
注意 1:点绘制功能仅适用于图形视频模式。
注意 2:在颜色少于 256 色的图形视频模式下,如果 AL 寄存器中第 7 位的 TRUE 状态被设置,则通过 XOR 逻辑运算将点写入视频内存。
注意 3:如果活动视频模式仅支持一个屏幕页,则会忽略 BH 的内容。
注意 4:INT 10\AH=0Ch 函数适合绘制线条,但它对于填充屏幕区域来说太慢。为了达到后一种目的,应该优先考虑更快的直接写入视频内存 (8.01-39)。
准备: AH = 0Dh BH – 屏幕页码(INT 10\AH=05h 的注释 1 和 2) CX – 像素的列号 DX – 像素的行号 返回: AL – 颜色字节(A.10-5)
注意 1:INT 10\AH=0Dh 函数仅适用于图形视频模式。
注意 2:如果活动视频模式仅支持一个页面,则会忽略 BH 的内容。
INT 10\AH=0Eh 函数在当前光标位置显示一个字符,然后将光标移至下一个字符单元格。如果当前行没有可用空间,则光标将被转移到下一行的开头。
准备: AH = 0Eh AL – 要显示的字符的 ASCII 代码 BH – 屏幕页码(INT 10\AH=05h 的注释 1 和 2) BL – 前景颜色(仅在图形视频模式下)
注意 1:附录 A.02-8 中列出的特殊代码,包括 07h (BEL) 和 08h (BS),不会显示,而是作为命令执行。
注意 2:在文本视频模式下,显示的字符将继承为前一个字符单元格指定的颜色。
准备: AH = 0Fh 返回: AH – 一行或一列中的字符列数 AL – 当前视频模式的代码 (A.10-1) BH – 活动屏幕页码(INT 10\AH=05h 的注释 1 和 2)
注意 1:如果视频模式的代码最初以其第 7 位设置为 TRUE 状态(屏幕未清除)指定,则返回的代码的第 7 位也将设置为 TRUE 状态。
注意 2:INT 10\AH=0Fh 函数无法正确确定 SVGA 视频模式的代码:对于文本 SVGA 视频模式,它返回 AL=07h (单色视频模式) 或 AL=03h (彩色视频模式)。
在文本视频模式下,颜色字节 (A.10-5) 中的第 7 位可以定义闪烁或背景强度:它取决于控制位的状态,该状态可以通过 INT 10\AX=1003h 函数更改。
准备: AX = 1003h BX – 操作类型: = 0000h – 启用背景强度控制; = 0001h – 启用前景闪烁控制。
注意 1:控制位的状态由 BIOS 数据区域 (A.10-6) 中地址 0040:0065h 处的字节中的第 5 位表示,也由 INT 10\AX=1B00h 函数返回的数据块 (A.10-2) 中偏移量 2Dh 处的字节中的第 5 位表示。
INT 10\AX=1010h 函数将主颜色(红色、绿色和蓝色)的所需部分强度(从 00h 到 3Fh)写入 DAC 的某个寄存器中。部分强度的组合将产生该颜色色调,该色调应由此特定 DAC 的寄存器定义。
准备: AX = 1010h BX – 目标 DAC 的寄存器号 CH – 绿色颜色的部分强度 CL – 蓝色颜色的部分强度 DH – 红色颜色的部分强度
注意 1:所有 DAC 的寄存器都可用于写入,但并非所有寄存器都处于活动状态:这取决于当前的视频模式。特别是,16 色视频模式中的背景颜色调色板由 DAC 的寄存器 0000h–0007h 定义。
INT 10\AX=1015h 函数读取存储在 DAC 的某个寄存器中的主颜色(红色、绿色和蓝色)的部分强度。这些部分强度的组合将产生由此特定 DAC 寄存器定义的颜色色调。
准备: AX = 1015h BX – 目标 DAC 的寄存器号
返回: AX 寄存器中的值可能会被更改; CH – 绿色颜色的部分强度; CL – 蓝色颜色的部分强度; DH – 红色颜色的部分强度。
准备:AX = 1018h BL – 要设置的新掩码
注意 1:在掩码中,位 0-2 控制背景的蓝色、绿色和红色。位 3-5 对前景色做同样的事情。位 6 和 7 的状态无关紧要。颜色掩码的正常状态由字节 FFh 表示:所有颜色都打开。
注意 2:CLS 命令(3.05)不会将颜色掩码重置为其正常状态。
准备:AX = 1100h BH – 每个字符图案的字节数 BL – 目标内存块的标识符(见 8.01-28 的注意 1) CX – 要加载或替换的字符图案数量 DX – 加载的偏移量,从目标内存块的开头开始计算 ES:BP – 指向要加载的图案表的指针
注意 1:隐含的是整个字体表包含 FFh 个字符图案。
注意 2:字符图案中的每个字节代表一行屏幕,因此图案中的字节数(BH 寄存器的值)与字体高度中的屏幕行数相同。
注意 3:此函数设置与加载的字体相对应的文本视频模式,但不会清除视频缓冲区。
注意 4:如果要加载多个字体,则 DISPLAY.SYS 驱动程序 (5.02-02) 必须事先准备好相同数量的字符生成器内存块。否则,只能使用一个标识符为 00h 的默认内存块。
注意 5:INT 10\AX=1110 函数也为文本视频模式加载字体,并接受相同的规格,但会重新计算视频控制器的当前状态。在调用 INT 10\AX=1110 之前,必须使用活动视频页 00h 设置文本视频模式。
INT 10\AX=1103 函数将字符生成器切换到另一个字体,该字体必须事先加载到字符生成器的某个内存块中。EGA 兼容和 VGA 兼容视频卡中的字符生成器能够同时保持两个内存块活动,从而有机会显示两种字体的字符。每个字符的字体选择取决于颜色字节(A.10-5)中的位 3,该字节由字符显示函数(特别是 INT 10\AH=09h 和 INT 10\AH=0Eh 函数)接受,这些函数从 BL 寄存器接受颜色字节。
准备:AX = 1103h BL – 所选内存块的标识符(见下面的注意 1)
注意 1:字符生成器内存块的标识符是一个字节,有两个专用字段。一个字段由位 4、1、0 表示。另一个字段由位 5、3、2 表示。在每个字段中,应该写入内存块的编号(从 0 到 7)。此内存块中的字体必须已加载。如果两个字段中的内存块编号相等,则将寻址一个字体,然后颜色字节(A.10-5)中的位 3 将定义强度。特别是,在 EGA 兼容视频卡中,最多允许 4 种字体,它们的内存块可以通过标识符 00h、05h、0Ah、0Fh 寻址。
注意 2:同时保持两个字体活动的能力由静态功能表(A.10-3)中的第 9 个字节的值指示。该表的地址由 INT 10\AX=1B00h 函数报告。
注意 3:为了同时激活两个字体,标识符字节的两个字段中应该存储不同的内存块编号。颜色字节中位 3 被清除的字符将从内存块中选择,该内存块的编号存储在标识符的第一个字段(位 4、1、0)中。颜色字节中位 3 被设置的字符将从内存块中选择,该内存块的编号存储在标识符的第二个字段(位 5、3、2)中。
INT 10\AX=1104 函数将 BIOS 的默认 8x16 字体(代表美国代码页 CP437)加载到字符生成器的内存块中。同时设置文本视频模式 03h,因为它的格式 (80x25) 对应于 8x16 字体。
准备:AX = 1104h BL – 所选内存块的标识符(见 8.01-28 的注意 1)
注意 1:INT 10\AX=1114 函数也为文本视频模式 03h 加载 BIOS 的标准 8x16 字体,并接受相同的规格,但会重新计算视频控制器的当前状态。在调用 INT 10\AX=1114 之前,必须使用活动视频页 00h 设置视频模式 03h。
注意 2:如果要加载多个字体,则 DISPLAY.SYS 驱动程序 (5.02-02) 必须事先准备好相同数量的字符生成器内存块。否则,只能使用一个标识符为 00h 的默认内存块。
注意 3:8x8 和 8x14 CP437 字体也可以从 BIOS 的只读内存中加载。8x8 字体通过 INT 10\AX=1102h 和 INT 10\AX=1112h 函数以类似的方式加载。单色 8x14 字体通过 INT 10\AX=1101h 和 INT 10\AX=1111h 函数以类似的方式加载。调用 INT 10\AX=1111h 和 INT 10\AX=1112h 函数会导致重新计算视频控制器的当前状态,并且必须在设置适当的文本视频模式之前进行。
准备:AX = 1121h BL – 字符行数规格:= 01h – 14 行,= 02h – 25 行,= 03h – 43 行,= 00h – 行数由 DL 寄存器定义。CX – 每个字符图案的字节数 DL – 行数,如果 BL = 00h(否则忽略 DL) ES:BP – 指向要加载的字符图案表的指针
注意 1:调用 INT 10\AX=1121h 函数必须紧接在设置(或重置)图形视频模式之前。
注意 2:图形视频模式的字体不需要准备字符生成器的内存块。相反,必须将指向已加载字体的指针写入中断表的地址 0000:010Ch。这个指针有时被称为向量 INT 43。
注意 3:BIOS 的 8x8 默认字体的字符 80h-FFh 的用户定义图案可以通过 INT 10\AX=1120h 以类似的方式加载。由于此字体的格式已知,因此 BL、CX 和 DL 寄存器的值将被忽略,并且字体表将具有固定长度 400h。必须将指向已加载字体的指针写入中断表的地址 0000:007Ch。这个指针有时被称为向量 INT 1F。
INT 10\AX=1124h 函数加载 BIOS 的标准 8x16 字体,代表图形视频模式的美国代码页 CP437。指向该字体的指针将写入中断表的地址 0000:010Ch。这个指针有时被称为向量 INT 43。
准备:AX = 1124h
注意 1:调用 INT 10\AX=1124h 函数必须紧接在设置(或重置)图形视频模式之前。
注意 2:来自 BIOS 的只读内存的 8x14 字体可以通过 INT 10\AX=1122h 函数以类似的方式加载。
注意 3:来自 BIOS 的只读内存的双点 8x8 字体可以通过 INT 10\AX=1123h 函数以类似的方式加载。
准备:AX = 1130h BH – 请求的指向字体表的指针:= 00h – 指向 8x8 图形字体(从 0000:007Ch)= 01h – 指向当前图形字体(从 0000:010Ch)= 02h – 指向 BIOS 的 8x14 文本字体 (CP437) = 03h – 指向 BIOS 的 8x8 字体,字符 00h-7Fh = 04h – 指向 BIOS 的 8x8 字体,字符 80h-FFh = 05h – 指向 BIOS 的备用 9x14 字体 = 06h – 指向 BIOS 的标准 8x16 文本字体 (CP437) = 07h – 指向 BIOS 的备用 9x16 字体
返回时:ES:BP – 指向请求的字体表的第一个字节 CX – 当前字体的每个字符的字节数 DL – 屏幕上当前字体的最高字符行
注意 1:CX 和 DL 寄存器中返回的数据与请求的字体无关,而是与当前显示在屏幕上的字体有关。
INT 10\AX=13h 函数显示一个字符字符串,该字符串可以以 ASCII 字节序列或文本视频模式下的视频内存字符串的形式指定,其中每个 ASCII 字节后面跟着一个颜色字节 (A.10-5)。在后一种情况下,BL 寄存器中的值会被忽略。
准备: AH = 13h AL – 位 7–2: – 清零 – 位 1 设置 – 具有交替 ASCII 和颜色字节的字符串 – 位 0 设置 – 沿显示的字符移动光标 BH – 屏幕页码(INT 10\AH=05h 的注释 1 和 2) BL – 颜色字节 (A.10-5),如果字符串仅包含 ASCII 码 CX – 要显示的字符串中的字符数 DH – 要开始显示的字符的行 DL – 要开始显示的字符的列 ES:BP – 指向要显示的字符串的第一个字节的指针
注释 1:附录 A.02-8 中列出的特殊代码 ASCII 不会显示,而是作为命令执行。
注释 2:如果字符字符串被定向到当前未激活的屏幕页,则某些过时的视频卡模型可能无法正确执行退格键 (BS) 和回车键 (CR) 特殊代码。
准备 | |||
AX | = | 1B00h | |
BX | = | 0000h | |
ES:DI | – | 指向 64 字节缓冲区的指针,用于数据表 | |
返回时 | |||
AL | = | 1Bh,如果此函数受 BIOS 支持 | |
ES:DI | – | 指向带有视频状态数据的表的第一个字节的指针。表的内容在附录 A.10-2 中描述。 |
INT 10\AX=4F00h 函数报告可用视频 BIOS 扩展和支持的视频模式。如果特定计算机中不存在视频 BIOS 扩展,则该计算机中的所有 INT 10\AX=4Fxxh 函数都不受支持。
准备: AX = 4F00h ES:DI – 指向 512 字节缓冲区的指针,用于数据表
返回时: AL = 4Fh – 任何其他值表示不存在 VBE AH = 00h – 成功终止,数据表已写入;= 01h – 写入表尝试失败;= 02h – 函数不受硬件配置支持;= 03h – 函数在当前视频模式下无效。ES:DI – 指向返回的 VBE 数据表的第一个字节的指针 (A.10-4)。
准备: AX = 4F01h CX – SVGA 视频模式代码 ES:DI – 指向 256 字节缓冲区的指针,用于数据表
返回时: AL = 4Fh – 任何其他值表示函数不受支持 AH = 00h – 成功终止 = 01h – 操作失败。ES:DI – 指向返回的视频模式数据表的指针 (A.10-7)。
准备: AX = 4F02h – 重新设置视频模式;= 4F03h – 获取当前视频模式代码 BX – 仅针对 AX = 4F02h:视频模式代码 (A.10-1),包括位 14 设置: – 启用线性帧缓冲区 位 15 设置: – 不要清除视频内存
返回时: AL = 4Fh – 任何其他值表示函数不受支持 AH – 终止代码,与 INT 10\AX=4F01h (8.01-36) 后相同 BX – 当前视频模式代码 (A.10-1),包括位 14 设置: – 启用线性帧缓冲区 位 15 设置: – 保留视频内存的内容
注释 1:如果通过中断 INT 33\AX=0028h 调用鼠标驱动程序,则可以执行与切换鼠标控制参数相协调的视频模式切换。
注释 2:显示设备不一定支持所有 SVGA 视频模式。在切换到任何视频模式之前,您必须知道您的显示设备是否支持此特定视频模式。
注释 3:视频模式切换会导致屏幕变黑(变暗)长达 2 秒,这对于视觉感知来说很不舒服。
准备: AX = 4F04h CX – 保存(或要保存)的配置的一部分: = 0001h – 视频硬件状态(CX 中的位 0 设置) = 0002h – BIOS 数据(CX 中的位 1 设置) = 0004h – 颜色寄存器和 DAC(CX 中的位 2 设置) = 0008h – SVGA 状态(CX 中的位 3 设置) = 000Fh – 整个视频配置(位 0–3 设置) DL – 子函数: = 00h – 确定用于保存视频模式的缓冲区大小 = 01h – 保存视频控制器的当前状态 = 02h – 恢复视频控制器的先前状态 ES:BX – 指向准备好的缓冲区的第一个字节的指针(仅针对子函数 01h 和 02h,对于子函数 02h,它必须用数据填充)。从子函数 DL = 00h 返回: BX – 需要的 64 字节内存块数 从子函数 DL = 01h 返回: ES:BX – 指向存储的视频模式数据的缓冲区的指针
在过时的计算机中,视频内存占据了地址空间区域 A000:0000–B000:FFFFh 的一部分。表 A.10-1 中显示了与 EGA 兼容和与 VGA 兼容的视频模式的地址空间活动区域。但是现代显卡是为 SVGA 视频模式设计的,这些模式需要更大的内存。整个专用地址空间区域对于 SVGA 视频模式来说太窄了。因此,SVGA BIOS 安排了滑动“窗口”,通过地址空间 A000:0000–B000:FFFFh 访问视频卡大内存的指定区域。
地址空间中滑动“窗口”的数量、大小和位置可能取决于视频卡和所选视频模式。特定视频卡和视频模式的这些数据可以在表 A.10-7 中找到,该表由函数 INT 10\AX=4F01h (8.01-36) 返回。最有可能的是,会安排一个或两个 64 千字节的“窗口”:“窗口 A”A000:0000h–A000:FFFFh 和“窗口 B”B000:0000h–B000:FFFFh。INT 10\AX=4F05h 函数报告视频内存到指定地址空间“窗口”的当前映射,并允许更改它。
准备: AX = 4F05h BH = 00h – 设置视频内存中映射区域的起始点 = 01h – 获取视频内存中映射区域的起始点 BL = 00h – 窗口“A”的请求 = 01h – 窗口“B”的请求 DX – 指向视频内存中映射区域的指针(仅针对 BH = 00h)
返回时: AL = 4Fh – 任何其他值表示函数不受支持 AH – 终止代码,与 INT 10\AX=4F01h (8.01-36) 后相同 DX – 指向视频内存中映射区域的指针(仅在 BH = 01h 后)
注释 1:视频内存中映射区域的位置以粒度单位表示。一个粒度单位的大小不是固定的,但它以千字节为单位给出,在表 A.10-7 中偏移量为 04h 的字中,由 INT 10\AX=4F01h 函数 (8.01-36) 返回。
注释 2:INT 10\AX=4F05h 函数也可以通过 CALL FAR 命令 (7.03-08) 调用,该命令的地址在表 A.10-7 中偏移量为 0Ch 的双字中给出。
注释 3:通过“窗口”发送到视频内存的数据的解释取决于表 A.10-7 中字节 1Bh 指定的模型类型。除此之外,某些模型类型允许解释的变体。例如,图形 EGA 模型实现了 3 种解释模式
- 模式 00h — 每个字节 8 个像素 — 用于根据位掩码和颜色掩码覆盖像素值;
- 模式 01h 用于从一个视频内存地址复制到另一个视频内存地址,只考虑地址;
- 模式 02h 用于用发送字节的 4 个最低有效位定义的颜色填充 8 个连续的像素。
表 A.14-1 的注释 3 和 4 中描述了一些更改模型类型和解释模式的机会。
INT 10\AX=4F06h 函数允许将显示行的逻辑长度设置为 2 的整数次幂或其倍数。因此,一些可承受的有效视频内存容量损失换来了坐标计算的简单性和速度的显著提高。此函数在文本视频模式和图形视频模式下同样适用。
准备:AX = 4F06h BL = 00h - 设置逻辑行像素长度 = 01h - 获取显示行的实际长度 = 02h - 设置逻辑行字节长度 = 03h - 获取显示行的最大长度 CX - 行长度(仅限于 BL=00h 和 BL=02h) 返回:AL = 4Fh - 任何其他值表示该功能不支持 AH - 终止代码,与 INT 10\AX=4F01h 后的代码相同 (8.01-36) BX - 逻辑行字节长度 CX - 逻辑行像素长度 DX - 指定长度的屏幕行的最大可用数量。
注意 1:实际行长度可能超过标称值,但不能超过特定显卡的最大值。如果请求的行长度小于当前视频模式的标称行长度,则实际行长度可能会取最接近的可接受值,不一定等于请求的行长度。
INT 10\AX=4F07h 函数可实现屏幕滚动,以及在可用视频内存空间内切换到其他屏幕页。此功能在文本和图形视频模式下同样适用。
准备:AX = 4F07h BX = 0000h - 立即设置显示部分的新起始位置 = 0001h - 获取显示部分的起始位置 = 0080h - 在场重绘间隔期间设置新的起始位置 CX - 一行中最左边的像素编号(对于 BX = 0001h 不需要) DX - 第一显示行的编号(对于 BX = 0001h 不需要)
返回:AL = 4Fh - 任何其他值表示该功能不支持 AH - 终止代码,与 INT 10\AX=4F01h 后的代码相同 (8.01-36) CX - 一行中最左边的像素编号(仅限于 BX = 0001h 后) DX - 第一显示行的编号(仅限于 BX = 0001h 后)。
准备:无
返回:AX - 设备列表字。解释见附录 A.11-1。
注意 1:在保护模式或 V86 模式下运行时,CPU 可能会在出现未对齐异常时为 INT 11 处理程序生成调用,即提供操作数地址不是操作数长度的倍数。仅在第三(最低)特权级别执行未对齐监控,如果标志寄存器中的位 12h 和控制寄存器 CR0 中的位 12h 都设置为 TRUE 状态(参见 A.11-4 的注意 6)。使用未对齐监控的程序必须在保护模式的中断表中拦截对 INT 11 处理程序的调用。
准备:无
返回:AX - 传统 RAM 的大小(以 KB 为单位)(参见注意 2 和 3)
注意 1:INT 12 处理程序从 BIOS 数据区 (A.01-1) 地址 0040:0013h 的字中读取传统 RAM 的大小。此外,RAM 大小存储在 CMOS RAM 单元 15h 和 16h 中(参见 A.14-1 的注意 1)。
注意 2:INT 12 处理程序不会报告 PC 的 RAM 超过 1 Mb 边界,但这些数据由函数 INT 15\AH=88h、INT15\AX=E801h 和 INT15\AX=E820h 报告。
注意 3:整个 RAM 大小包括未释放或无法访问的内存(16 位寻址)。INT 21\AH=48h 函数报告了可由 DOS 分配给程序的可用传统 RAM 的大小(参见 8.02-50 的注意 1)。
复位操作强制磁盘控制器用从指定磁盘驱动器参数表中读取的数据重新填充其内部寄存器 (A.08-2、A.13-1)。每次访问硬盘或软盘失败后都必须进行复位操作,只有在复位后才能重复访问尝试。
准备:AH = 00h - 应用于软盘控制器 = 0Dh - 应用于硬盘控制器 DL - 磁盘驱动器编号(参见注意 1) 返回:发生错误时,CF 标志被设置,AH 返回错误代码 (A.06-1)。CF 标志的清除状态表示成功终止。
注意 1:软盘驱动器的编号是从 0 开始的:00h - 第一个,01h - 第二个,依此类推。硬盘的编号从 80h 开始:80h - 第一个,81h - 第二个,依此类推。磁盘驱动器(物理磁盘)的编号与逻辑磁盘的字母名称无关:每个物理硬盘可能包含多个逻辑磁盘。
注意 2:如果两个磁盘驱动器连接到一个控制器,则复位操作会导致两个磁盘驱动器中的磁头移至零道(重新校准)。当不需要控制器的复位时,应通过调用 INT 13\AH=11h 函数启动重新校准(所有其他规范相同)。
准备:AX = 0100h DL - 磁盘驱动器编号(参见 8.01-44 的注意 1) 返回:AH - 状态代码 (A.06-1)
注意 1:一些过时的 BIOS 版本在 AL 中返回状态代码。
准备:AH = 02h AL - 要读取的扇区数量(参见注意 1) CH - 柱面(磁道)编号的低 8 位 CL - 位 0-5:起始扇区编号(从 1 到 63),- 位 6-7:柱面(磁道)编号的两位最高位 DH - 磁头编号(参见注意 2) DL - 磁盘驱动器编号(参见 8.01-44 的注意 1) ES:BX - 指向要读取数据的缓冲区的指针 返回:发生错误时,CF 标志被设置,AH 返回错误代码 (A.06-1)。CF 标志的清除状态表示成功终止。AL - 实际读取的扇区数量(参见注意 5) ES:BX - 指向已填充的缓冲区,该缓冲区包含从磁盘读取的数据。
注意 1:AL 寄存器中指定的扇区数量不能为零。一些过时的 BIOS 版本不允许 AL 中的值超过当前磁道上的剩余扇区数量(有关详细信息,请参见文章 4.22)。
注意 2:一些过时的 BIOS 版本仅接受 DH 中的 4 位最低位,因此最多只能指定 16 个磁头。带有数据块 A.13-1 中签名 A0h 的现代 BIOS 系统接受转换后的 CHS 参数,允许最多 256 个磁头。在任何情况下,INT 13\AH=08h 函数都会报告任何特定磁盘驱动器的最大参数值 (8.01-49)。
注意 3:当从软盘读取失败时,之后应重复至少两次读取尝试,并在每次下一次尝试之前对软盘控制器进行复位 (8.01-44)。
注意 4:在 Windows 操作系统下,禁止通过 INT 13 函数直接访问磁盘,除非使用 LOCK 操作对目标磁盘进行锁定以防止并发访问(参见 INT 21\AX=440Dh 的注意 2)。
注意 5:一些过时的 BIOS 版本不会在 AL 寄存器中返回实际读取的扇区数量。在发生读取错误(错误代码 AH = 11h)时,现代 BIOS 系统会在 AL 寄存器中返回已更正的数据块的长度。
注意 6:INT 13\AH=0Ah 函数(所有其他规范相同)会读取硬盘的扇区(s),以及包含 4 到 7 个字节的错误纠正代码的 22 字节“尾部”。INT 13\AH=0Ah 函数不会纠正错误,并在遇到第一个损坏的扇区后停止读取。
准备:AH = 03h AL - 要写入的扇区数量(必须非零)CH、CL、DH、DL - 与 INT 13\AH=02h (8.01-46) 相同 ES:BX - 指向要写入数据的缓冲区的指针 返回:发生错误时,CF 标志被设置,AH 返回错误代码 (A.06-1)。CF 标志的清除状态表示成功终止。AL - 实际写入的扇区数量
注 1:INT 13\AH=02h 函数的注 1-4 (8.01-46) 同样适用于 INT 13\AH=03h 函数。
注 2:可以使用 INT 13\AH=04h 函数 (所有其他规格相同) 验证写入的数据与缓冲区内容是否一致。
注 3:可以使用 INT 13\AH=0Bh 函数 (所有其他规格相同) 将带有 ECC (错误纠正码) 的扇区写入 HDD。
低级格式化只能应用于没有内在磁道结构的介质。因此,INT 13\AH=05h 函数可以应用于软盘,但不能应用于现代 HDD:它们的原始磁道结构可能会因低级格式化而损坏。
格式化参数表必须事先通过 INT 10\AH=18h 函数 (8.01-54) 在 PC 的内存中准备。对于过时的软盘类型,类似的表由 INT 10\AH=17h 函数准备。特别是,指向软盘格式化参数表的指针存储在 0000:0078h 内存单元 (A.08-2) 中。
准备:AH = 05h AL - 要格式化的扇区数量 CH - 磁道号 DH - 磁头号 DL - 磁盘驱动器号 (注 1 至 8.01-44) ES:BX - 指向数据缓冲区的指针,该缓冲区包含磁道中每个扇区的 4 个字节:第一个 - 磁道号,第二个 - 磁头号,第三个 - 扇区号,第四个 - 扇区大小 (00h、01h、02h、03h 分别对应于每扇区 128、256、512、1024 字节的大小)。
返回:发生错误时,CF 标志被设置,AH 返回错误代码 (A.06-1)。CF 标志的清除状态表示成功终止。
注 1:在 ES:DX 指向的数据块中,磁道和磁头的计数为从零开始,扇区的计数为从一开始。
注 2:扇区号、磁头号和磁道号的最大值应由 INT 13\AH=08h 函数 (8.01-49) 确定。虽然物理值可能不同,但返回的最大值反映了这些转换 (A.13-1),这些转换可能由特定计算机的 BIOS 系统应用于磁盘参数。
准备:AH = 08h DL - 磁盘驱动器号 (注 1 至 8.01-44)
返回:发生错误时,CF 标志被设置,AH 返回错误代码 (A.06-1)。CF 标志的清除状态表示成功终止,然后:BL - 驱动器类型 (仅限于可移动介质驱动器):= 01h - 360 kb 软盘驱动器,= 02h - 1.2 Mb 软盘驱动器,= 03h - 720 kb 软盘驱动器,= 04h - 1.44 Mb 软盘驱动器,= 06h - 2.88 Mb 软盘驱动器,= 10h - 任何其他类型的驱动器。CH - 最大柱面 (磁道) 号的 8 个最低有效位 CL - 位 0-5:最大扇区号 (从 1 到 63),- 位 6-7:最大柱面号的最高有效位 DH - 最大磁头号 DL - 同类型附加驱动器的数量 (注 2) ES:DI - 指向参数表的指针 A.08-2 (仅限于软盘驱动器返回)。
注 1:即使请求的驱动器不存在,也可能会返回成功终止状态 (AH = 00h)。为了确定返回数据的有效性,必须检查 CF 标志的状态和 DL 寄存器中返回的数字。
注 2:某些 BIOS 系统无法在 DL 寄存器中返回大于 2 的数字。应通过 INT 13\AH=15h 函数 (8.01-52) 单独检查是否存在更多驱动器的疑虑。
注 3:表 A.13-1 中偏移量为 03h 的字节中的签名 A0h 表示对于 HDD,INT 13\AH=08h 函数返回的不是物理 CHS 参数,而是转换后的 CHS 参数。在这种情况下,仅应在计算 INT 13\AH=02h - INT 13\AH=18h (8.01-46 - 8.01-54) 函数的请求值时考虑这些转换后的 CHS 参数。
准备:AH = 0Ch CH、CL、DH、DL - 与 INT 13\AH=02h (8.01-46) 相同
返回:发生错误时,CF 标志被设置,AH 返回错误代码 (A.06-1)。CF 标志的清除状态表示成功终止。
INT 13\AH=10h 函数返回的状态代码表示请求的 HDD 是否存在以及它是否已准备好执行下一个任务。
准备:AH = 10h DL - 驱动器号 (80h = 第一个 HDD,81h = 第二个 HDD,依此类推) 返回:AH - 状态字节 (表 A.06-1)。CF 标志的清除状态表示成功终止。CF 标志的设置状态表示错误。
准备:AH = 15h DL - 磁盘驱动器号 (注 1 至 8.01-44) 返回:发生错误时,CF 标志被设置,AH 返回错误代码 (A.06-1)。CF 标志的清除状态表示成功终止,然后:AH - 磁盘驱动器类型:= 00h - 请求的驱动器不存在;= 01h - 没有媒体变更线路支持的软盘驱动器;= 02h - 任何具有可移动媒体变更线路支持的驱动器 = 03h - 固定磁盘驱动器 (HDD)。CX:DX - 512 字节扇区的 4 字节数量 (仅限于 HDD 返回)。
注 1:具有可移动媒体的 HDD 可能被归类为类型 01h 或 02h。
注 2:INT 13\AH=15h 函数不依赖于存储的数据,它扫描控制器的总线以获取新的有效数据。
准备:AH = 16h DL - 磁盘驱动器号 (注 1 至 8.01-44) 返回:如果磁盘未发生更改,则 CF 标志被清除,AH = 00h;如果 CF 标志被设置,AH = 06h,则磁盘已发生更改;如果 CF 标志被设置,但 AH 具有任何其他值,则此值应根据表 A.06-1 解释为返回代码。
注 1:在向 INT 13\AH=16h 函数发送有关未知磁盘驱动器的请求之前,必须使用 INT 13\AH=15h 函数调查该磁盘驱动器是否支持媒体变更线路。
注 2:大多数磁盘驱动器型号中的媒体变更线路通过打开 (或关闭) 磁盘插槽盖来激活,即使磁盘变更事件实际上没有发生。
注 3:每个媒体变更事件只报告一次:调用 INT 13\AH=16h 函数后,媒体变更标志被清除到其原始状态。
注 4:扩展媒体变更函数 INT 13\AH=49h (具有相同的其他规格) 可应用于任何磁盘驱动器,包括物理编号为 80h 及更高的 CD 驱动器。应通过 INT 13\AH=41h 函数 (8.01-55) 确认 BIOS 对这些扩展功能的支持。
准备:AH = 18h CH、CL、DH、DL - 与 INT 13\AH=02h (8.01-46) 相同
返回:AH - 状态代码:= 00h - 请求的参数受支持;= 01h - 请求的功能不可用;= 0Ch - 当前磁盘类型不受支持或未知;= 80h - 驱动器中不存在可移动媒体。ES:DI - 指向软盘驱动器参数表的指针 A.08-2
注 1:INT 13\AH=18h 函数不会将返回的指向软盘驱动器参数表的指针写入内存地址 0000:0078h,也称为 INT 1E 向量 (A.12-1)。INT 1E 向量的准备被认为是调用者的责任。
注 2:当应用于 HDD 时,INT 13\AH=18h 函数返回 CF 标志设置和状态代码 AH = 01h。对于过时的 5.25" 软盘和 720 kb 软盘,应改为应用 INT 13\AH=17h 函数。
8.01-55 INT 13\AH=41h - INT 13 扩展检查
[edit | edit source]由于 INT 13 扩展,自 1997 年以来,现代计算机的许多常用功能已经实现,特别是从 CD-ROM 启动 PC 的可能性和对大型硬盘的 LBA寻址(参见 A.13-6 的注 4)。
准备:AH = 41h BX = 55AAh DL – 磁盘驱动器号(参见 8.01-44 的注 1)
返回:出错时,CF 标志被置位,AH 返回错误代码 (A.06-1)。CF 标志的清除状态表示成功终止,然后:AH – INT 13 扩展版本:= 01h – 版本 1.x,= 20h – 版本 2.0,= 21h – 版本 2.1。BX = AA55h 签名确认支持 INT 13 扩展 CX – API 子集字的位表示对函数的支持:位 0 – INT 13\AH=42h–44h,47h,48h;位 1 – INT 13\AH=45h,46h,48h,49h, INT 15\AH=52h;位 2 – INT 13\AH=48h,4Eh;位 3 – 扩展磁盘地址包支持(参见注 2)
注 1:AL 和 DH 寄存器中的数据在返回时可能会丢失。
注 2:所有版本的 INT 13 扩展都支持对容量高达 127 Gb 的磁盘进行 10 字节包寻址。除此之外,对 20 字节扩展磁盘地址包的支持能够实现超过 127 Gb 的寻址。10 字节和 20 字节地址包的结构如附录 A.13-4 所示。
8.01-56 INT 13\AH=42h – 扩展磁盘读取函数
[edit | edit source]准备:AH = 42h DL – 磁盘驱动器号(参见 8.01-44 的注 1)DS:SI – 指向磁盘地址包的指针 (A.13-4)
返回:发生错误时,CF 标志被设置,AH 返回错误代码 (A.06-1)。CF 标志的清除状态表示成功终止。
注 1:返回时,成功读取的数据块数量被写入磁盘地址包偏移量 02h 处的字中。
注 2:指向包含读取数据的缓冲区的指针由磁盘地址包偏移量 04h 处的双字表示。
注 3:轨迹寻道函数 INT 13\AH=47h 在之前使用相同的其他规范启动,允许 CPU 在磁盘驱动器将磁头移动到指定轨道时执行大量工作。适当地使用轨迹寻道函数使实际访问特定轨道变得更快。
8.01-57 INT 13\AH=43h – 扩展磁盘写入函数
[edit | edit source]准备:AH = 43h AL – 标志:= 00h – 跳过验证过程,= 02h – 验证写入的数据。DL – 磁盘驱动器号(参见 8.01-44 的注 1)DS:SI – 指向磁盘地址包的指针 (A.13-4)
返回:发生错误时,CF 标志被设置,AH 返回错误代码 (A.06-1)。CF 标志的清除状态表示成功终止。
注 1:指向要写入数据的缓冲区的指针由磁盘地址包偏移量 04h 处的双字表示。
注 2:返回时,成功写入(或成功验证)的数据块数量保存在磁盘地址包偏移量 02h 处的字中。
注 3:INT 13 扩展的版本 1.x 使用标志 AL = 01h 来验证写入的数据。如果请求验证,但不受支持,则 INT 13\AH=43h 函数返回标志 CF 被置位,AH = 01h(无效函数)。
注 4:可以通过 INT 13\AH=44h 单独启动验证;其他规范相同,除了 AL 中的值被忽略。
8.01-58 INT 13\AH=45h – 锁定/解锁驱动器
[edit | edit source]一些磁盘处理过程,被外部访问请求中断,可能会造成严重的数据丢失。典型的例子是碎片整理。在碎片整理进行时,必须阻止对目标磁盘的外部访问尝试。被阻止后,可移动磁盘无法从其驱动器中弹出。在多任务环境中阻止磁盘可以避免并发干预。允许最多 255 级嵌套过程,这些过程需要对磁盘进行独占访问。完成其工作后,每个这样的过程都必须使用解锁操作释放目标磁盘。
准备:AX – 子函数:= 4500h – 锁定驱动器中的介质:将锁定级别增加 1 = 4501h – 解锁介质:将锁定级别减少 1 = 4502h – 报告介质锁定级别 DL – 磁盘驱动器号(参见 8.01-44 的注 1)
返回:出错时,CF 标志被置位,AH 返回错误代码 (A.06-1)。CF 标志的清除状态表示成功终止,然后 AL – 介质锁定级别(= 00h 如果已解锁)
8.01-59 INT 13\AH=46h – 弹出可移动介质
[edit | edit source]准备:AX = 4600h DL – 磁盘驱动器号(参见 8.01-44 的注 1)返回:出错时,CF 标志被置位,AH 返回错误代码 (A.06-1)。CF 标志的清除状态表示成功终止。
注 1:在弹出之前,INT 13\AH=46h 处理程序调用 INT 15\AH=52h 函数,以确保当前指定介质未参与与缓存缓冲区或多任务环境中的其他程序进行数据传输。
8.01-60 INT 13\AH=48h – 请求驱动器的参数
[edit | edit source]准备:AH = 48h DL – 磁盘驱动器号(参见 8.01-44 的注 1)DS:SI – 指向数据缓冲区的指针。缓冲区中的第一个字必须声明其可用长度,不小于:001Ah – 对于 INT 13 扩展版本 1.x,001Eh – 对于 INT 13 扩展版本 2.x,0049h – 对于 INT 13 扩展版本 3.x。
返回:出错时,CF 标志被置位,AH 返回错误代码 (A.06-1)。CF 标志的清除状态表示成功终止,然后:DS:SI – 指向填充有数据表 A.13-2 的缓冲区的指针。
注 1:如果实际指定的长度对应于更旧的版本,则较新的版本会根据指定长度的格式截断返回的表。
8.01-61 INT 13\AX=4A00h – 从 CD 模拟驱动器
[edit | edit source]此函数安排一个虚拟逻辑磁盘,该磁盘从存储在光盘或 DVD 光盘中的磁盘映像中复制。准备:AX = 4A00h DS:SI – 指向启动规范包 A.15-1 的指针
返回:发生错误时,CF 标志被设置,AH 返回错误代码 (A.06-1)。CF 标志的清除状态表示成功终止。
注 1:INT 13\AX=4C00h 函数接受相同的其他规范(除了 AX),并执行相同的操作,但随后继续从安排的虚拟磁盘启动 PC。
8.01-62 INT 13\AH=4Bh – 驱动器模拟子函数
[edit | edit source]准备:AH = 4Bh AL – 子函数:= 00h – 终止磁盘模拟 = 01h – 获取模拟状态 DL – 模拟的磁盘号(参见 8.01-44 的注 1)DS:SI – 指向用于启动数据包的 13 字节缓冲区的指针
返回:出错时,CF 标志被置位,AH 返回错误代码 (A.06-1)。CF 标志的清除状态表示成功终止,然后:DS:SI – 指向填充有启动数据包 A.15-1 的缓冲区的指针。
注 1:给定 DL = 7Fh 后,子函数 AL = 00h 会终止所有当前模拟。
注 2:如果未执行模拟,则返回 CF 标志的清除状态。
8.01-63 INT 13\AH=4Dh – 读取光盘扇区
[edit | edit source]准备:AX = 4D00h DS:SI – 指向命令包的指针 (A.15-2)
返回:发生错误时,CF 标志被设置,AH 返回错误代码 (A.06-1)。CF 标志的清除状态表示成功终止。
注 1:返回的数据被写入准备好的缓冲区。指向此缓冲区的指针必须由命令包偏移量 02h 处的双字指定 (A.15-2)。
注 2:INT 13\AH=4Dh 函数最常用于读取光盘的引导目录。引导目录结构如表 A.15-3 所示。
8.01-64 INT 13\AH=4Eh – 控制驱动器的硬件
[edit | edit source]准备:AH = 4Eh AL - 子功能:= 00h - 启用预取(读取到驱动器缓冲区)= 01h - 禁用预取 = 02h - 设置最大 PIO 数据传输模式 = 03h - 设置 PIO 数据传输模式 0 = 04h - 设置默认 PIO 数据传输模式 = 05h - 启用 INT 13 DMA 最大模式 = 06h - 禁用 INT 13 DMA 数据传输 DL - 磁盘驱动器编号(注意 1 到 8.01-44)
返回:出错时 CF 标志被置位,AH 返回错误代码(A.06-1)。CF 标志清除表示成功终止,然后:AL = 00h - 命令只影响指定的驱动器 = 01h - 其他设备也受到影响(注意 2)
注意 1:DMA 和 PIO 数据传输模式是互斥的。选择 DMA 会禁用 PIO,选择 PIO 会禁用 DMA。
注意 2:数据传输模式的更改可能会影响连接到相同控制器的其他设备。
准备:AH = 00h AL - 数据传输参数:位 7–5:值从 000b 到 111b 分别对应于数据速率 110、150、300、600、1200、2400、4800、9600 比特每秒 位 4–3:00b 或 10b - 无奇偶校验,01b - 奇校验,11b - 偶校验。位 2:如果清除 - 1 个停止位,如果设置 - 2 个停止位。位 1–0:值从 00b 到 11b 分别对应于数据字长 5、6、7、8 位。DX - 串行端口号 (0000h–0003h) 返回:AH - 线路状态字节 (A.14-2) AL - 调制解调器的状态,如果它连接到请求的端口。
准备:AH = 01h AL - 要发送的字符 DX - 串行端口号 (0000h–0003h) 返回:AH - 线路状态字节 (A.14-2)
注意 1:传输错误由返回状态字节中位 7 的置位状态标记:这意味着等待响应的时间超过了预设的时间限制(超时)。
准备:AX = 0200h DX - 串行端口号 (0000h–0003h) 返回:AH - 线路状态字节 (A.14-2) AL - 接收到的字符,如果返回线路状态字节中位 7 清除。
准备:AX = 0300h DX - 串行端口号 (0000h–0003h) 返回:AH - 线路状态字节 (A.14-2) AL - 调制解调器的状态,如果它连接到请求的端口。
INT 15\AH=52h 函数报告驱动器当前是否正在进行数据传输。INT 15\AH=52h 函数特别由 INT 13\AH=46h 处理程序调用,以防止在数据传输过程未完成时弹出可移动介质。
准备:AH = 52h DL - 磁盘驱动器编号(注意 1 到 8.01-44) 返回:如果 CF 标志置位,则驱动器繁忙,AH 返回错误代码(A.06-1)。CF 标志清除表示请求的驱动器不繁忙。
注意 1:在应用 INT 15\AH=52h 函数之前,应通过调用 INT 13\AH=41h 检查 BIOS 是否支持此函数。
注意 2:默认情况下,BIOS 为 INT 15\AH=52h 安装一个虚拟处理程序,该处理程序始终返回 CF 标志清除。响应将反映驱动器流量的实际状态,当对 INT 15\AH=52h 函数的调用被磁盘缓存驱动程序安装的另一个处理程序拦截时。
当计算机开机时,其电源管理系统 (APM) 处于非活动状态。当 CPU 处于实模式时,可以通过调用 INT 15\AX=5301 函数来启动 APM 接口激活。
准备:AX = 5301h BX = 0000h(BIOS 的 APM 扩展标识符) 返回:出错时 CF 标志被置位,AH 返回错误代码(A.06-1)。CF 标志清除表示成功终止。
注意 1:INT 15\AX=5301h 函数强制 APM 系统模拟 APM 版本 1.0 的规范。为了执行未定义为 APM 版本 1.0 的操作,应通过 INT 15\AX=530Eh 函数(8.01-72)强制模拟较新的 APM 版本。
ATX 外形尺寸的计算机可以通过机器命令关闭,将电源块切换到待机模式。然后仅为那些使 PC 开机机会的模块供电。当然,电源块的待机模式必须由电源块本身和 PC 主板硬件支持。
准备:AX = 5307h BX = 0001h(所有 APM 控制设备的标识符)CX = 0003h(关闭请求代码) 返回:出错时 CF 标志被置位,AH 返回错误代码(A.06-1)。成功时,其余部分无关紧要。
注意 1:关闭操作由 APM 版本 1.2 的规范定义。如果 APM 系统模拟版本 1.0(注意 1 到 8.01-70),则应通过 INT 15\AX=530Eh 函数(8.01-72)解除关闭 PC 的机会。
注意 2:在过时的 AT 外形尺寸的计算机中,允许调用 INT 15\AX=5307h 函数,但会被忽略。
为了保持与操作系统的兼容性,较新的 APM 版本的规范规定了模拟以前 APM 版本的机会。那个要控制电源管理的程序或那个操作系统,可以请求模拟所需的 APM 版本。响应中,APM BIOS 模拟请求的或最近的可行 APM 版本,并返回该版本的编号。进一步的电源管理必须根据实际模拟的 APM 版本执行。
准备:AX = 530Eh BX = 0000h(BIOS 的 APM 扩展标识符)CX - 请求的 APM 版本模拟(注意 1) 返回:出错时 CF 标志被置位,AH 返回错误代码(A.06-1)。CF 标志清除表示成功终止,然后 AX - 实际模拟的 APM 版本(注意 1)。
注意 1:APM 版本号的整数部分和小数部分必须分别指定在 CX 寄存器的单独字节中。例如,对于版本 1.2 请求,应指定 CX = 0102h 值。返回的 AX 版本号符合相同的格式。
注意 2:版本模拟请求由 APM 版本 1.1 的规范定义。如果版本模拟请求返回错误代码 80h 或 86h,而 INT 15\AX=5301h(8.01-70)函数已成功终止,则表示这台计算机仅实现 APM 版本 1.0。
准备:AX – 子功能:= 8300h – 初始化延迟计数并让调用者继续执行 = 8301h – 停止计数会话(CX、DX、ES:BX 被忽略) = 8600h – 初始化延迟计数并挂起调用者进程直到延迟计数过期(AL 和 ES:BX 被忽略) CX – 32 位延迟的最显著 16 位(以微秒为单位) DX – 32 位延迟的最低显著 16 位(以微秒为单位) ES:BX – 指向标记字节的指针:当延迟计数过期时,其最显著的第 7 位被置位(注 3)。
返回时:CF 标志的清除状态表示成功终止。CF 标志在错误或计数会话尚未启动时被置位,然后 AH 寄存器返回错误代码(A.06-1)。
注 1:时间段最可能的解析度是 977 微秒。
注 2:一些过时的 BIOS 版本不支持子功能 8301h。
注 3:标记字节的默认地址为 0040:00A0h(A.12-1)。当延迟计数过期时,一些 BIOS 版本会将标记字节的值分配为 80h。
注 4:在 Windows 操作系统下,BIOS 定时器无法从“DOS 框”访问。
准备:AH = 84h DX – 子功能:= 0000h – 读取开关状态 = 0001h – 读取位置传感器的信号
返回时:出错时 CF 标志被置位,AH 返回错误代码(A.06-1)。CF 标志的清除状态表示成功终止,然后
- DX=0000h 子功能在 AL 寄存器的位 4–7 中返回开关状态;
- DX=0001h 子功能返回以下数据
AX – 第一个操纵杆的 X 坐标值
BX – 第一个操纵杆的 Y 坐标值
CX – 第二个操纵杆的 X 坐标值
DX – 第二个操纵杆的 Y 坐标值
注 1:位置传感器的典型电阻为 250 kOhm,坐标值的典型限制范围为 0000h–01A0h。
注 2:暗示操纵杆是通过游戏端口连接的。如果特定 PC 中没有游戏端口,则子功能 DX=0001h 返回零坐标值,子功能 DX=0000h 返回 AL=00h,相当于开关的断开状态。
INT 15\AH=85h 函数由 INT09 处理程序响应用户的 PrtScr 键击调用。暗示应该由显卡驱动程序安装 INT 15\AH=85h 函数的处理程序,以实现基于特定显卡的特定资源的增强 Print Screen 过程。但直到该特定处理程序未安装之前,BIOS 的虚拟处理程序只会将控制权返回给调用程序,就像其请求已得到满足一样。
准备:AH = 85h AL = 00h – 当按下 PrintScreen 键时启动过程 = 01h – 当释放 PrintScreen 键时启动过程 CF 标志必须事先被清除
返回时:出错时 CF 标志被置位,AH 返回错误代码(A.06-1)。CF 标志的清除状态和 AH = 00h 表示成功终止。
INT 15\AH=87h 函数在 16 Mb 地址空间内复制数据块。数据块的最大大小为 64 kb。复制是在保护模式下执行的,同时禁用外部中断,因此无需为保护模式准备中断表。但是需要 GDT 表,并且应该根据以下模板进行准备
- 保留描述符:00 00 00 00 00 00 00 00
- 保留描述符:00 00 00 00 00 00 00 00
- 源段描述符:ss ss aa aa aa 93 00 00
- 目标段描述符:ss ss dd dd dd 93 00 00
- 保留描述符:00 00 00 00 00 00 00 00
- 保留描述符:00 00 00 00 00 00 00 00
在显示的模板中,字母“a”表示源段的线性地址字段,字母“d”表示目标段的线性地址字段,字母“s”表示源段和目标段的大小字段。由于数据块的大小由 CX 寄存器中的双字节字数量指定,因此两个段的大小(以字节为单位)必须不小于 (2*CX) –1。在大小字段和地址字段中,第一个是最不显著字节;最显著字节是最后指定的。源段描述符和目标段描述符中的属性字节必须为 93h。描述符结构的更详细说明在附录 A.12-2 中给出。
最初填充为零的保留描述符将由 INT 15\AH=87h 处理程序填充数据,并在保护模式下使用。复制完成后,INT 15\AH=87h 处理程序将 CPU 切换回实模式并恢复原始状态,以继续执行调用程序的执行。
准备:AH = 87h CX – 要复制的字数,不超过 7FFFh ES:SI – 指向准备好的 GDT 表的第一个字节的指针
返回:发生错误时,CF 标志被设置,AH 返回错误代码 (A.06-1)。CF 标志的清除状态表示成功终止。
注 1:由于复制期间禁用外部中断,因此一些外部中断调用可能会被遗漏。如果通过 HIMEM.SYS 驱动程序(A.12-4)安排了超出常规内存的复制,则这种情况不会发生。
注 2:HIMEM.SYS 驱动程序会拦截 INT 15\AH=87h 调用,并不会直接访问原始 BIOS 的处理程序。但是,如果该区域由 /INT15 参数(5.04-01)保留,则程序可能会被允许通过 INT 15\AH=87h 调用访问扩展内存的有限区域。
准备:AH = 88h 返回时:出错时 CF 标志被置位,AH 返回错误代码(A.06-1)。CF 标志的清除状态表示成功终止,然后 AX – 超过 1024 kb 的扩展内存大小(以 KB 为单位)。
注 1:如果有效地址空间是间断的,则将报告其从 100000h(1024 kb)到第一个间隙的连续部分的大小。
注 2:INT 15\AH=88h 处理程序从 BIOS 的 CMOS 数据库的单元 30h 和 31h 读取扩展内存大小。
注 3:HIMEM.SYS 和 EMM386.EXE 驱动程序会拦截 INT 15\AH=88h 函数的默认 BIOS 处理程序。
注 4:有关超过 16 Mb 的扩展内存的信息可以通过 INT 15\AX=E801h\E881h(8.01-79)和 INT 15\AX=E820h(8.01-80)报告。
INT 15\AH=89h 处理程序将 CPU 切换到保护模式,并执行保护模式下运行的最紧急的准备工作,包括用段选择符填充段寄存器,并根据保护模式规范重新编程中断控制器。
为了确保调用程序在将 CPU 切换到保护模式后继续执行,应该事先准备保护模式的中断表(IDT)和全局描述符表(GDT)。IDT 填充了 8 字节描述符(“门”),指定了保护模式处理程序的地址和调用条件。IDT 表本身的大小和线性地址必须写入 GDT 表中的 IDT 段描述符。
为 INT 15\AH=89h 处理程序准备的 GDT 表包含 8 个描述符,每个描述符 8 字节长。GDT 表中描述符的排列必须与以下模板相对应
- 保留描述符:00 00 00 00 00 00 00 00
- GDT 段描述符:3F 00 aa aa aa 00 00 00
- IDT 段描述符:FF 03 aa aa aa F2 00 00
- DS 段描述符:ss ss aa aa aa 92 0s aa
- ES 段描述符:ss ss aa aa aa 92 0s aa
- SS: 段描述符 ss ss aa aa aa 92 0s aa
- CS: 段描述符 ss ss aa aa aa 9A 0s 00
- 保留描述符:00 00 00 00 00 00 00 00
在显示的模板中,字母“a”表示每个段的线性地址字段,字母“s”表示段大小字段。保留描述符必须填充为零。作为示例,模板显示属性字节的特定值,以及 GDT 和 IDT 段的特定大小。描述符结构的更详细说明在附录 A.12-2 中给出。
准备:AH = 89h BL – IRQ 0 的中断号(注 2) BH – IRQ 8 的中断号(注 2) ES:SI – 指向 GDT 表的第一个字节的指针
返回时:出错时 CF 标志被置位,AH 返回错误代码(A.06-1)。CF 标志的清除状态表示成功终止,然后 AH = 00h,段寄存器填充了段选择符,中断控制器被重新编程。BP 寄存器中的前一个值可能会被更改。
注 1:GDT 表中的 CS 段描述符必须只指定由实模式中的 CS 段地址定义的段。该条件确保在保护模式下,从调用 INT 15\AH=89h 处理程序的命令之后继续执行调用程序的执行。
注 2:分配给 BL 和 BH 寄存器的中断号必须是 8 的倍数(三位最不显著位必须被清除)。在 BL 寄存器中的值后面的中断号将被分配给请求线 IRQ 1 – IRQ 7。类似地,在 BH 寄存器中的值后面的中断号将被分配给请求线 IRQ 9 – IRQ F。选择重新编程的中断号的一个重要因素是,中断 00h–1Fh 可能由 CPU 的异常调用。
注 3:由于寻址格式已更改且中断控制器已重新编程,因此切换到保护模式后,对实模式中断处理程序的直接调用将被禁止。
准备: AX = E801h 或 AX = E881h 返回: 发生错误时,CF 标志被置位,AH 返回错误代码 (A.06-1)。CF 标志清零表示成功终止,此时 AX – 扩展内存大小(以 KB 为单位),位于 1 MB 到 16 MB 之间的地址空间区域。BX – 扩展内存大小(以 64 KB 块为单位),位于 16 MB 之上的地址空间区域。CX – 配置的内存大小(以 KB 为单位),位于 1 MB 到 16 MB 之间的地址空间区域。DX – 配置的内存大小(以 64 KB 块为单位),位于 16 MB 之上的地址空间区域。
注意 1: 如果成功终止后 AX = BX = 0000h,则应从寄存器 CX 和 DX 中读取扩展内存大小。
注意 2: 与 INT 15\AX=E801h 不同,INT 15\AX=E881h 处理程序能够返回超过 4 GB 的值。最高位数字保存在 32 位寄存器 EBX 和 EDX 的位 31-16 中。访问位 31-16 的方法(适用于实模式程序)在文章 7.02-06 中描述。
注意 3: INT 15\AX=E801h\E881h 函数不受 1995 年之前开发的旧版 BIOS 支持。
内存分配映射由一系列 20 字节的描述符组成,每个描述符对应一个独立的内存区域,用于特定目的。每个描述符以区域首字节的 8 字节地址开头,然后是该区域的 8 字节长度,最后 4 字节是该区域的分配代码(注意 1)。一次调用 INT 15\AX=E820h 函数返回一个描述符;因此需要多次调用该函数。对于第一次调用,应在 EBX 寄存器中准备零值 (00000000h)。第一次调用后,将返回一个非零 EBX 值,定义了下次调用的目标描述符。调用循环的终止以 EBX 寄存器中返回零值或 CF 标志被置位为标志。
准备: AX = E820h EBX – 内存分配映射中目标描述符的指针 ECX – ES:DI 缓冲区的大小,不小于 20 (=14h) 字节 EDX = 534D4150h – “SMAP” 签名 ES:DI – 为描述符准备的缓冲区的指针
返回: 发生错误时,CF 标志被置位,EAX 值不等于 534D4150h,AH 寄存器返回错误代码 (A.06-1)。CF 标志清零表示成功终止,此时 EAX = 534D4150h “SMAP” – “SMAP” 签名 EBX – 内存分配映射中下一个描述符的指针 ECX – 返回描述符在 ES:DI 缓冲区中的实际长度 ES:DI – 包含返回描述符的缓冲区的指针
注意 1: 分配代码应按如下方式解释:
- 01h – 分配给操作系统的内存;
- 02h – 由 BIOS 保留的内存(系统 ROM);
- 03h – ACPI 表区域(读取后可能释放);
- 04h – 用于系统目的的非易失性内存。
具有其他分配代码的内存区域应视为由 BIOS 系统保留。地址空间中不包括在内存分配映射中的区间不受硬件支持。
注意 2: 一些 BIOS 版本不忽略 EAX 寄存器中位 31-16 的内容,因此调用 INT 15\AX=E820h 函数需要将这些位清零(即 EAX = 0000E820h)。访问位 31-16 的方法(适用于实模式程序)在文章 7.02-06 中描述。
注意 3: 一些 BIOS 版本忽略 ECX 寄存器,并在每次调用 INT 15\AX=E820h 函数后返回 20 字节的数据。
注意 4: 如果特定计算机的 BIOS 不支持调用 INT 15\AX=E820h 函数,则应尝试调用 INT 15\AX=E801h (8.01-79)。如果此尝试也失败,则应调用 INT 15\AH=88h 函数 (8.01-77)。
准备: AX – 子函数: = 0300h – 设置默认重复速率和延迟值 = 0305h – 设置 BL 中给出的速率,设置 BH 中给出的延迟 = 0306h – 获取当前重复速率和延迟的 BL –(仅限于 AX=0305h):重复速率代码(注意 1) BH –(仅限于 AX=0305h):延迟代码(注意 2)
返回: BL – 当前重复速率的代码(注意 1) BH – 当前延迟的代码(注意 2) AH 内容可能被更改。
注意 1: 允许的重复速率代码从 00h 到 1Fh,对应于每秒 30 次到 2 次的重复速率。
注意 2: 允许的延迟代码从 00h 到 03h,对应于 0.25 秒到 1 秒的延迟。
准备: AH = 05h CH – 击键的扫描码(表 A.02-1) CL – 对应字符的 ASCII 码(表 A.02-1)
返回: AL – 错误代码 (A.06-1) AH 内容可能被更改。
注意 1: 旧版 BIOS 不支持此功能。
注意 2: 一些键的代码(例如 ENTER 键)插入键盘缓冲区后,会触发相应函数的执行。
注意 3: INT 16\AH=05h 函数不能用于插入“功能”键(SHIFT、CTRL、ALT)的代码。
INT 16\AH=10h 函数适用于最广泛的 101/108 键“增强型”键盘,但也响应其他键盘上兼容键的击键。INT 16\AH=10h 处理程序从键盘缓冲区中提取最顶端的键码,并将此代码放在 AX 寄存器中。如果此时键盘缓冲区为空,则 INT 16\AH=10h 处理程序开始等待用户的击键。
准备: AH = 10h
返回: AH – 击键的扫描码(表 A.02-1) AL – 对应字符的 ASCII 码(表 A.02-1)
注意 1: INT16\AH=20h 执行相同的操作,但能够响应一些特定于 122 键键盘的键。
注意 2: 在旧的计算机中,类似的任务由 INT16\AH=00h 函数执行。在现代计算机中,此函数仍然处于活动状态,但它会忽略在旧的 84 键键盘中不存在的键。
INT 16\AH=11h 函数适用于最广泛的 101/108 键“增强型”键盘,但也响应其他键盘上兼容键的击键。最顶端的键码不会从键盘缓冲区中提取,INT 16\AH=11h 处理程序只是将此代码复制到 AX 寄存器中,如果此时键盘缓冲区为空,它不会等待用户的击键。
准备: AH = 11h
返回: 如果 ZF 标志被置位为 ZR 状态,则键盘的缓冲区为空。如果 ZF 标志被清零为 NZ 状态,则:AH – 击键的扫描码(表 A.02-1) AL – 对应字符的 ASCII 码(表 A.02-1)
注意 1: INT16\AH=21h 执行相同的操作,但能够响应一些特定于 122 键键盘的键。
注意 2: 在旧的计算机中,类似的任务由 INT16\AH=01h 函数执行。在现代计算机中,此函数仍然处于活动状态,但它会忽略在旧的 84 键键盘中不存在的键。
INT 16\AH=12h 函数将保存在 BIOS 数据区域 (A.02-3) 中的地址 0040:0017h 的键盘状态字复制到 AX 寄存器中。
准备: AH = 12h
返回时:AX - 标志:位 0 置位:右 Shift 键被按下 位 1 置位:左 Shift 键被按下 位 2 置位:任何一个 CTRL 键(右或左)被按下 位 3 置位:任何一个 ALT 键(右或左)被按下 位 4 置位:Scroll Lock 开关打开 位 5 置位:Num Lock 开关打开 位 6 置位:Caps Lock 开关打开 位 7 置位:Insert 开关打开 位 8 置位:左 CTRL 键被按下 位 9 置位:左 ALT 键被按下 位 10 置位:右 CTRL 键被按下 位 11 置位:右 ALT 键被按下 位 12 置位:Scroll Lock 键被按下 位 13 置位:Num Lock 键被按下 位 14 置位:Caps Lock 键被按下 位 15 置位:SysRq (PrtScr) 键被按下(注 2)
注 1:在使用 84\86 键键盘的过时计算机中,INT 16\AH=02h 函数执行类似的任务。它只返回 AL 寄存器中位 7–0 的标志状态。在现代计算机中,此函数仍然有效,但它不返回那些在过时计算机中未注册的标志状态。
注 2:SysRq (PrtScr) 键的按下状态不会被注册,除非任何一个 ALT 键(左或右)也被按下。
8.01-86 INT 17\AH=00h - 向 LPT 端口发送字符
[edit | edit source]准备:AH = 00h AL - 要发送的字符的代码 DX - LPT 端口号:0000h–0002h 对应于 LPT1 – LPT3
返回时:AH - LPT 端口和打印机的状态 (A.14-3).
8.01-87 INT 17\AH=01h - 初始化打印机的端口
[edit | edit source]准备:AH = 01h DX - LPT 端口号:0000h–0002h 对应于 LPT1 – LPT3
返回时:AH - LPT 端口和打印机的状态 (A.14-3).
注 1:报告的状态可能不正确。INT 17\AH=0200h 函数在稍后一段时间内会报告更可靠的数据。
8.01-88 INT 17\AX=0200h - 获取 LPT 端口的状态
[edit | edit source]INT 17\AX=0200h 函数由传统的 LPT BIOS 和 EPP BIOS(增强型并行端口 BIOS)执行,但方式不同。过时的 PC 中没有 EPP BIOS,因此传统的 LPT BIOS 除了 AH 中的端口状态 (A.14-3) 之外什么也不报告。在现代 PC 中,如果 BX 寄存器中的准备值不是 5050h,则 INT 17\AX=0200h 调用可以定向到传统的 LPT BIOS 并产生相同的效果。但对于 BX=5050h 和 CH=45h 的 INT 17\AX=0200h 调用,EPP BIOS 会拦截这些调用,它返回其入口点的地址。对该入口点的 CALL FAR 命令 (7.03-08) 会调用 IEEE 1284 规范 (A.14-4) 规定的增强型 I/O 功能。
准备:AX = 0200h BX = 5050h,如果调用定向到 EPP BIOS CH = 45h,如果调用定向到 EPP BIOS DX - LPT 端口号:0000h–0002h 对应于 LPT1 – LPT3
返回时:AH - LPT 端口和打印机的状态 (A.14-3). 状态 AH = 03h 且 CF 标志设置为 CY 状态由 EPP BIOS 返回,如果它不支持请求的 LPT 端口。状态 AH = 00h 且 CF 标志清除为 NC 状态由 EPP BIOS 返回,如果它支持请求的 LPT 端口,然后:CX:AL = 4550:50h - EPP BIOS 版本 1.x 的签名 CX:AL = 5050:45h - EPP BIOS 版本 3.x 的签名 EPP BIOS 版本 1.x 和 3x 保持 ES 寄存器内容不变,并且 DX:BX - EPP BIOS 远入口点的段:偏移量 EPP BIOS 修订版 7 返回 ES 内容更改,并且 DX - EPP BIOS I/O 操作的基址 ES:BX - EPP BIOS 远入口点的段:偏移量。
注 1:如果对 INT 17\AX=0200h 的调用没有定向到 EPP BIOS,则 BX 和 CH 寄存器可以包含任何值,除了 5050h 和 45h 之外。
注 2:ES 寄存器中段地址的更改是 EPP BIOS 最新第 7 版的特定症状,它补充了用于 LPT 多路复用器的控制功能。
8.01-89 INT 18 - 无盘引导钩子
[edit | edit source]准备:无
当找不到可引导磁盘时,PC 的 BIOS 系统会调用 INT 18 处理程序。在过时的 PC 中,INT 18 处理程序会启动 BASIC 语言解释器,该解释器存储在 PC 的只读内存 (ROM) 中。现代计算机中的默认 INT 18 处理程序会显示一条关于缺少 BASIC 语言解释器的消息,然后停止 CPU。
但是,扩展卡的 ROM 内存中提供的其他处理程序可以拦截对 INT 18 的调用。特别是,扩展卡提供的处理程序可能会进行拦截,以便通过本地网络实现无盘引导。
8.01-90 INT 19 - 引导加载程序
[edit | edit source]INT 19 处理程序执行 PC 引导过程中的重要部分:它将引导扇区从磁盘的引导分区复制到 PC 内存地址 0000:7C00h,然后将控制权转移到复制的引导扇区的代码。首先寻址该磁盘,该磁盘在 BIOS 设置程序准备的引导备选方案序列中被指定为第一个。从软盘中,它们的引导扇区立即被复制,硬盘的引导分区从 MBR 扇区 (A.13-5) 的分区表中确定。如果寻址的磁盘不可访问,则会尝试寻址准备的引导备选方案序列中的下一个磁盘。如果所有尝试都失败,最后一个默认选项是调用 INT 18 处理程序 (8.01-89)。
但是,INT 19 处理程序不会清除内存,也不会恢复中断表。因此,如果未对该调用进行适当的准备,则计算机很可能在调用 INT 19 处理程序后挂起。在必要时,重新引导不应通过调用 INT 19 处理程序来启动,而应通过其他方式启动:通过键盘控制器的 FEh 命令(A.11-3 的注 3)或通过对引导程序入口点 F000:FFF0h(A.12-1 的注 4)的 CALL FAR 命令 (7.03-08),该入口点在所有 AT 兼容计算机中都相同。
8.01-91 INT 1A\AH=00h - 获取系统滴答计数
[edit | edit source]准备:AH = 00h 返回时:AL - 如果自上次读取滴答计数以来已经过了午夜,则为非零值。CX - 滴答计数的最重要 2 个字节,每 24 小时 1800B0h DX - 滴答计数的最低重要 2 个字节,每秒 18.2 个滴答
注 1:滴答计数在午夜重置。
注 2:午夜后,DOS 必须首先请求系统滴答计数,否则它会错过午夜标志并无法推进日期。
注 3:可以使用 INT 1A\AH=01h 设置系统时间(以滴答数计)。要设置的滴答数必须以相同的方式准备在 CX 和 DX 寄存器中。
8.01-92 INT 1A\AH=02h - 读取实时时钟
[edit | edit source]准备:AH = 02h
返回时:出错时,CF 标志被置位,返回的数据无效。CF 标志的清除状态表示成功终止,然后 CH - 小时 CL - 分钟 DH - 秒 DL = 00h 标准时间(北半球的“冬季时间”) = 01h 夏令时(北半球的“夏季时间”)
注 1:小时、分钟和秒以压缩十进制格式返回,即每个字节两个十进制数字。
注 2:可以使用 INT 1A\AH=03h 设置实时时间。要设置的时间数据必须以相同的形式准备在 CH、CL、DH 和 DL 寄存器中。
8.01-93 INT 1A\AH=04h - 读取实时日期
[edit | edit source]准备:AH = 04h
返回时:出错时,CF 标志被置位,返回的数据无效。CF 标志的清除状态表示成功终止,然后 CH - 世纪 CL - 年份 DH - 月份 DL - 日
注 1:日、月、年和世纪以压缩十进制格式返回,即每个字节两个十进制数字。
注 2:可以使用 INT 1A\AH=05h 设置新日期。要设置的数据必须以相同的形式准备在 CH、CL、DH 和 DL 寄存器中。
INT 1A\AH=06h 函数指定 PC 的 BIOS 系统定期调用 INT 4A 处理程序的时刻。期望的操作(例如时钟闹钟)隐含地由 INT 4A 处理程序完成,该处理程序需要由用户编写并加载。
准备:AH – 06h CH – 小时 CL – 分钟 DH – 秒
返回:出错时 CF 标志被置位:很可能是时间预设已处于活动状态。CF 标志的清除状态表示成功终止。
注意 1:小时、分钟和秒必须以压缩十进制格式准备,即每字节两个十进制数字。
注意 2:预设 FFh 会丢弃部分计数。例如,如果 CH = FFh,则 INT 4A 处理程序每小时调用一次;如果 CH = CL = FFh,则 INT 4A 处理程序每分钟调用一次。
注意 3:时间预设一直有效,直到通过调用 INT 1A\AH=07h 函数禁用它为止,该函数只需要准备 AH = 07h 即可。
准备:无
每次键盘控制器报告 CTRL-Break 按键时,INT 09 处理程序都会调用 INT 1B。默认的 INT 1B 处理程序在 BIOS 数据区设置一个标志的 TRUE 状态(表 A.02-3 中偏移量 71h 处字节的第 7 位),然后控制权返回给被中断的程序。此标志的状态由当前程序调用的某些 MS-DOS 处理程序检查。如果发现标志被设置为 TRUE 状态,则调用 INT 23 处理程序(8.02-83)。后者挂起当前程序的执行,并负责所有后续事件(1.03)。
在中断表中用指向 IRET 命令的指针(7.03-30)替换 INT 1B 处理程序的地址,这是一种常见的技巧,在许多程序中使用,以防止因 CTRL-Break 按键而导致的程序中止。
准备:无
INT 1C 由 INT 08 处理程序(8.01-09)在每个系统计时器的滴答声处调用,即每秒 18.2 次。默认的 INT 1C 处理程序只是将控制权返回给调用者。但是,每个驻留程序都可以用自己的 INT 1C 处理程序替换默认处理程序,该处理程序将在每个计时器滴答声处将控制权传递给程序的驻留模块。因此,计算机系统能够实现对实时开发过程的监控和控制。
INT 20 处理程序从程序的 PSP(A.07-1)恢复以前的 interrupt 表值,释放程序占用的内存,恢复段寄存器和堆栈的状态,然后将控制权转移到 INT 22 指向的调用者代码(8.02-82)。但是,INT 20 要求 CS: 寄存器中存在 PSP 段地址,并且没有机会留下错误级别代码(3.15-03),该代码描述了程序终止的环境。因此,应优先使用 INT 21\AH=4Ch 函数(8.02-55)来终止程序执行。
准备:CS: 寄存器中的段地址必须指向 PSP 段。
返回:不会发生返回。
注意 1:在 Debug.exe 的操作系统环境中,INT 21\AH=4Ch 和 INT 20 处理程序会产生不同的效果:INT 20 将控制权转移到 Debug.exe,而 INT 21\AH=4Ch 会终止调试器的会话并将控制权返回给 DOS。
注意 2:INT 21\AH=00h 也会终止调用者程序,并且始终留下错误级别代码 00h,就像 INT 20 一样。MS-DOS7 支持 INT 21\AH=00h 以保持与旧软件的兼容性。
INT 21\AH=01h 函数从 STDIN(标准输入)通道读取字符代码,将该代码写入 AL 寄存器,并将该代码的副本发送到 STDOUT(标准输出)通道。STDIN 和 STDOUT 通道都可以重定向,但在重定向之前,默认的 STDIN 源是键盘,默认的 STDOUT 目标是屏幕。因此,调用 INT 21\AH=01h 函数会导致 PC 开始等待按键,按键后,相应的字符会出现在屏幕上。
准备:AH = 01h
返回:AL – 收到的字符的 ASCII 代码
注意 1:返回的 ASCII 代码由表 A.02-1 中十六进制数字的两个最右边数字表示。
注意 2:INT 21\AH=01h 函数不应该从命令文件中调用,这些命令文件通过重定向发送到命令解释器,因为在这种情况下,INT 21\AH=01h 函数会拦截 STDIN 流量,包括要接收的命令,这些命令要被命令解释器接收。
注意 3:INT 21\AH=01h 函数检查该标志的状态,该标志在 CTRL-C 和 CTRL-Break 按键后被设置(8.01-95)。如果发现此标志处于 TRUE 状态,则调用 INT 23 处理程序。
注意 4:同样,INT 21\AH=03h 函数从 STDAUX 通道读取字符代码,该通道的默认源是 COM1 端口。
INT 21\AH=02h 函数将指定的 ASCII 代码发送到 STDOUT 通道。如果 STDOUT 通道未重定向,则其默认目标是显示器,因此,与发送的 ASCII 代码相对应的字符将出现在屏幕上。
准备:AH = 02h DL – 要发送到 STDOUT 的字符的 ASCII 代码 返回:AH – 发送的 ASCII 代码,除了制表符代码(09h),它将扩展为空格(20h)。
注意 1:如果 STDOUT 通道被重定向到文件,则发送到 STDOUT 通道不会意味着检查驱动器中的介质是否存在,是否已满,是否写保护等等。但是,当目标驱动器忙于先前的操作时,INT 21\AH=02h 处理程序将等待该先前操作的终止。
注意 2:INT 21\AH=02h 函数检查该标志的状态,该标志在 CTRL-C 和 CTRL-Break 按键后被设置(8.01-95)。如果发现此标志处于 TRUE 状态,则调用 INT 23 处理程序。
注意 3:INT 21\AH=06h 也会将 ASCII 代码发送到 STDOUT 通道,但不会检查 CTRL-C\CTRL-Break 标志。除此之外,如果 DL=FFh(8.02-04),INT 21\AH=06h 函数会执行完全不同的任务。
注意 4:与 INT 21\AH=02h 类似,INT 21\AH=04h 函数将 ASCII 代码发送到 STDAUX 通道(默认目标 - COM1 端口),INT 21\AH=05h 函数将 ASCII 代码发送到 STDPRN 通道(默认目标 - LPT1 端口)。
在给出 DL = FFh 规范后,INT 21\AH=06h 函数从 STDIN 通道读取 ASCII 代码,几乎与 INT 21\AH=01h 函数相同,但不同的是 INT 21\AH=06h 函数
- 不检查 CTRL-C\CTRL-BREAK 标志,
- 不会从源中撤回复制的代码,
- 当源为空时不会导致等待,
- 不会将代码的副本发送到 STDOUT 通道,
- 能够处理扩展键码。
术语“扩展”适用于那些键码,这些键码通过其扫描码部分(表 A.02-1 中数字的左两位)不同,并且其 ASCII 部分值要么是 00h 要么是 E0h。如果 BIOS 报告这两个 ASCII 值中的任何一个,那么 INT 21\AH=06h 函数将清除 ZF 标志并返回 AL = 00h,从而指示具有扩展键码的按键。在这种情况下,INT 21\AH=06h 函数必须再次调用,然后它将在 AL 寄存器中返回扫描码,这使得能够区分具有“扩展”键码的按键。
其他 ASCII 代码(除了 00h 和 E0h)立即在 AL 寄存器中返回,然后无法返回扫描码。在此之后,允许对 INT 21\AH=06h 函数进行重复调用,但它将作为独立于先前调用的单独执行。
准备:AH = 06h DL = FFh(对于其他值 – 注意 3 到 8.02-03)
返回时:ZR(设置)ZF 标志的状态表示源为空 NZ(清除)ZF 标志的状态表示存在数据,然后 AL – 通过 STDIN 通道复制的 ASCII 代码(或扫描码)。
注意 1:INT 21\AH=07h 函数执行几乎相同的操作,但会从 STDIN 源撤回读取的代码,忽略 DL 内容,不更改 ZF 标志的状态,并且如果 STDIN 源是键盘缓冲区,并且此时它为空,则可能会导致等待按键。
注意 2:INT 21\AH=08h 函数与 INT 21\AH=07h 相同(见上文注意 1),但除此之外,它还检查该标志的状态,该标志在 CTRL-C 和 CTRL-Break 按键后设置(8.01-95)。如果发现此标志处于 TRUE 状态,则会调用 INT 23 处理程序。
注意 3:INT 21\AH=06h–08h 函数不应从命令文件调用,这些命令文件通过重定向发送到命令解释器,因为在这种情况下 INT 21\AH=06h–08h 函数会拦截 STDIN 流量,包括那些要被命令解释器接收的命令。
注意 4:如果象形文字语言支持标志(表 A.07-1 中偏移量 3Ch 处的字节)被设置为 TRUE 状态,那么 INT 21\AH=06h–08h 函数能够返回部分形成的双字节代码。
准备:AH = 09h DS:DX – 指向以 '$' 结尾的字符串的起始字节的指针 返回时:AL = 24h(“$”字符的代码,字符串中的最后一个字符)
注意 1:输出将持续到遇到第一个字符“$”(24h)为止;“$”本身不会发送到 STDOUT,并且不能存在于字符串中。
注意 2:INT 21\AH=09h 函数检查该标志的状态,该标志在 CTRL-C 和 CTRL-Break 按键后设置(8.01-95)。如果发现此标志处于 TRUE 状态,则会调用 INT 23 处理程序。
注意 3:另一个能够发送字符串的函数是 INT21\AH=40h(8.02-36)。
当 STDIN 通道没有被重定向时,INT 21\AH=0Ah 函数会等待按键,并在每次按键后将其代码写入准备好的缓冲区。缓冲区不一定要为空:新数据可以追加到先前缓冲区的内容中。写入的代码副本通过 STDOUT 通道发送以显示。在接收到 ENTER 按键产生的 0Dh 代码后,写入将终止。当 STDIN 通道通过重定向从文件接收数据时,缓冲区填充将持续进行,并在遇到第一个 0Dh 字节后终止。在这两种情况下,当准备好的缓冲区变满时,写入将终止。
准备:AH = 0Ah DS:DX – 指向准备好的缓冲区的起始位置,其中需要填充 2 个字节:偏移量 00h:最大缓冲区大小(以字节为单位);偏移量 01h:写入新数据的起始偏移量。
返回时:DS:DX – 指向已填充缓冲区的起始位置,其中 2 个字节表示:偏移量 00h:最大缓冲区大小(以字节为单位);偏移量 01h:实际写入的字节数。
注意 1:如果缓冲区大小(DS:DX 指向)为 00h,INT 21\AH=0Ah 函数不会等待按键,并立即返回控制。
注意 2:准备好的缓冲区中的字节计数从偏移量 02h 开始,不包括终止写入会话的字节 0Dh。
注意 3:INT 21\AH=0Ah 函数检查该标志的状态,该标志在 CTRL-C 和 CTRL-Break 按键后设置(8.01-95)。如果发现此标志处于 TRUE 状态,则会调用 INT 23 处理程序。
注意 4:INT 21\AH=0Ah 函数不应从命令文件调用,这些命令文件通过重定向发送到命令解释器,因为在这种情况下 INT 21\AH=0Ah 函数会拦截 STDIN 流量,包括那些要被命令解释器接收的命令。
INT 21\AH=0Bh 函数用于确定 STDIN 通道源中是否存在任何数据。当 STDIN 通道未被重定向时,INT 21\AH=0Bh 函数报告键盘缓冲区是否为空。如果要通过重定向接收数据,那么 INT 21\AH=0Bh 函数将显示源中是否至少有一个字节挂起。
准备:AH = 0Bh
返回时:如果 STDIN 通道源为空,则 AL = 00h,否则 = FFh,如果 STDIN 通道源中至少有一个字节。
注意 1:INT 21\AH=0Bh 函数检查该标志的状态,该标志在 CTRL-C 和 CTRL-Break 按键后设置(8.01-95)。如果发现此标志处于 TRUE 状态,则会调用 INT 23 处理程序。
INT 21\AH=0Ch 处理程序会清除键盘缓冲区,然后调用由 AL 寄存器中的代码指定的选定 STDIN 输入函数。允许的代码 01h、06h、07h、08h、0Ah 分别对应于函数 INT 21\AH=01h、INT 21\AH=06h、INT 21\AH=07h、INT 21\AH=08h、INT 21\AH=0Ah。其他相关功能由所选的输入函数定义。
准备:AH = 0Ch AL – 输入函数的代码:01h 或 06h 或 07h 或 08h 或 0Ah 其他寄存器 – 按照指定输入函数的要求
返回时:与指定的输入函数返回时相同。
注意 1:INT 21\AH=0Ch 处理程序以及允许的输入函数代码不应从通过重定向发送到命令解释器的命令文件调用,因为在这种情况下,输入函数会拦截 STDIN 流量,包括那些要被命令解释器接收的命令。
注意 2:如果 AL 中的代码不是允许的代码之一(01h、06h、07h、08h、0Ah),那么 INT 21\AH=0Ch 处理程序会清除键盘缓冲区,但不会尝试进行 STDIN 输入。
每次当前程序想要访问另一个磁盘时,都应该将磁盘缓冲区的内容写回当前磁盘。除此之外,调用 INT 21\AH=0Dh 函数将恢复 DTA 区域的默认地址(注意 6 到 A.07-1)。
准备:AH = 0Dh
返回时:CF 标志的清除状态表示成功终止。
注意 1:INT 21\AH=0Dh 函数将磁盘缓冲区写入磁盘,但不更新目录的更改内容。当某个文件的句柄通过 INT 21\AH=3Eh 函数关闭时(8.02-34),目录将被更新。
INT 21\AH=0Eh 函数将“当前”状态分配给该逻辑磁盘,该逻辑磁盘应作为默认选择,以便能够执行磁盘访问操作而无需显式磁盘指定。
准备:AH = 0Eh DL – 所选逻辑磁盘的编号(注意 1)
返回时:AL – LASTDRIVE 规范允许的最大字母名称数量(4.17、4.18)
注意 1:逻辑磁盘的编号遵循其字母名称的顺序:00h = A:,01h = B:,02h = C:,依此类推。
注意 2:在驱动程序启动时被调用时,INT 21\AH=0Eh 函数可能会在 AL 寄存器中返回一个无效的数字,因为它从列表列表(A.01-2)中的偏移量 21h 处读取,并且在启动时可能还没有写入该位置。
注意 3:INT 21\AH=19h 函数(8.02-15)报告当前默认逻辑磁盘的编号。
INT 21\AH=11h 处理程序使用 FCB (文件控制块) - 一种过时的文件数据规格,不适合访问以 FAT-32 文件系统格式化的磁盘上的文件。然而,FCB 适用于在当前目录中匹配文件搜索,包括 FAT-32 文件系统磁盘上的目录。允许的 FCB 结构如表 A.09-5 所示。FCB 中的文件名规格可以是带 "?" 通配符的掩码 (2.01-03)。FCB 可以通过 INT 21\AH=29h 函数 (8.02-19) 方便地排列。
INT 21\AH=11h 处理程序返回的一些搜索数据补充了 FCB 中的数据,如表 A.09-5 所示。但搜索结果的主要部分在 DTA - 数据传输区中返回,该区域长 128 字节。默认的 DTA 位置在 PSP (A.07-1) 内,从偏移量 80h 开始,但 DTA 可以通过 INT 21\AH=1Ah 函数 (8.02-16) 迁移到其他位置。DTA 中返回的数据结构取决于原始 FCB 的类型 - 是正常的 FCB 还是扩展的 FCB。两种变体返回的数据结构如表 A.09-1 所示。
准备 : AH = 11h DS:DX - 指向未打开的 FCB,正常或扩展 (A.09-5)
返回 : AL - 错误代码 (A.06-1): = FFh - 没有找到匹配的文件 = 00h - DTA 区域 (A.09-1) 填充了关于第一个找到的文件的数据。
注意 1: INT 21\AH=11h 函数可以获取关于卷标的信息。为此,应准备一个带有属性字节 08h 的扩展 FCB,并且当前目录必须是磁盘的根目录。
注意 2: INT 21\AH=11h 函数可以获取关于目录的信息。为此,应准备一个带有属性字节 10h 的扩展 FCB,并且当前目录必须是请求的目录的父目录。
注意 3: 如果搜索要使用 INT 21\AH=12h 函数 (8.02-12) 继续,则 FCB 和 DTA 区域中的所有数据,包括返回的数据,必须保持不变。
注意 4: 不使用 FCB 规格的文件搜索由 INT 21\AH=4Eh 函数执行。
INT 21\AH=12h 函数在先前搜索迭代成功终止后继续搜索匹配的文件,先前搜索迭代由 INT 21\AH=11h (8.02-11) 或 INT 21\AH=12h 函数执行。一致继续的必要条件是保持先前搜索迭代后 FCB 和 DTA 中返回的那些数据完整。搜索结果与调用 INT 21\AH=11h (8.02-11) 后的结果相同。
准备 : AH = 12h DS:DX - 指向未打开的 FCB,正常或扩展 (A.09-5) DTA 区域 (A.09-1) 包含上次搜索迭代后剩余的数据
返回 : AL - 错误代码 (A.06-1): = FFh - 没有更多匹配的文件 = 00h - DTA 区域 (A.09-1) 填充了关于下一个找到的文件的数据。
注意 1: INT 21\AH=11h (文章 8.02-11) 的所有注释同样适用于 INT 21\AH=12h 函数。
INT 21\AH=13h 处理程序使用过时的 FCB (文件控制块) 规范形式,但它仍然适用于删除当前目录中的文件(s),包括以 FAT-32 文件系统格式化的磁盘上的目录。允许的 FCB 结构如表 A.09-5 所示。为了删除多个文件,FCB 可以指定一个带 "?" 通配符的掩码 (2.01-03)。FCB 可以通过 INT 21\AH=29h 函数 (8.02-19) 方便地排列。
要删除的文件必须事先关闭 (8.02-34),必须没有 HSR 属性 (A.09-2),并且包含这些文件的磁盘不能是写保护的。
准备 : AH = 13h DS:DX - 指向未打开的 FCB,正常或扩展 (A.09-5)
返回 : AL - 错误代码 (A.06-1): = FFh - 没有找到匹配的文件 = 00h - 匹配的文件已成功删除。
注意 1: 由于扩展 FCB 中的属性字节 (A.09-5),INT 21\AH=13h 函数能够删除卷标和具有 R (只读) 属性的文件。删除子目录也是可能的,但随后这些子目录中的文件将变成丢失的簇。
注意 2: 删除的文件不会被物理删除;而是它的目录项变得无效:该项的第一个字符被无效标记覆盖 - 代码 E5h。
注意 3: INT 21\AH=13h 函数删除任何具有长文件名的文件都不会影响除主目录项之外的关联目录项,而这些目录项包含长文件名的延续。
注意 4: 不使用 FCB 规格的文件(s) 删除由 INT 21\AH=41h 函数 (8.02-37) 执行。
准备 : AH = 17h DS:DX - 指向未打开的 FCB,正常或扩展 (A.09-5)。当前名称在 FCB 中的正常位置写入,建议的新名称必须写入 10h 字节进一步,在下一行转储下方的当前名称下。具体偏移值在表 A.09-5 中给出。两个名称都必须以规范形式写入,例如,由 INT 21\AH=29h 函数 (8.02-19) 提供。对于正常 FCB,所需缓冲区的长度为 28 字节,对于扩展 FCB,所需缓冲区的长度为 35 字节。
返回 : AL - 错误代码 (A.06-1): = 00h - 指定的文件已成功重命名。 = FFh - 失败:要么没有找到匹配的文件,要么文件受 HRS 属性保护,要么具有建议的新名称的文件已经存在。
注意 1: FCB 中允许使用文件掩码,但仅使用 "?" 通配符 (2.01-03),并且在两个文件掩码中使用相同的通配符位置:在替换当前文件名时和在替换建议的新文件名时。与通配符位置相对应的字符将从当前实际文件名中复制,并插入到新分配的文件名中的相同位置。
注意 2: 由于 FCB 没有指定路径,INT 21\AH=17h 函数只能重命名当前目录中的文件。重命名当前目录以外的文件可以通过 INT 21\AH=56h 函数 (8.02-62) 执行,该函数不使用 FCB 规范。
注意 3: 带有属性字节 10h 的扩展 FCB 能够从父目录重命名子目录,而带有属性字节 08h 的扩展 FCB 能够从当前磁盘的根目录重命名卷标。
INT 21\AH=19h 函数报告在没有显式磁盘规格的情况下,磁盘访问操作默认将采用哪个逻辑磁盘。
准备 : AH = 19h
返回 : AL - "当前" 逻辑磁盘的编号 (8.02-10 的注意 1)。
注意 1: "当前" 逻辑磁盘的任命可以通过 INT 21\AH=0Eh 函数 (8.02-10) 更改。
数据传输区 (DTA) 是一个 128 字节长的缓冲区,由文件搜索函数 (8.02-11, 8.02-12, 8.02-57, 8.02-58) 使用。DTA 区域的默认位置在当前程序的 PSP 内,偏移量为 0080h (A.07-1 的注意 6)。
准备 : AH - 子功能: = 1Ah - 指定 DTA 的新位置 = 2Fh - 报告当前的 DTA 位置 DS:DX - 指向新的 DTA 位置 (仅适用于 AH = 1Ah 子功能)
返回 : ES:BX - 指向当前的 DTA 位置 (仅适用于 AH = 2Fh 子功能)
注意 1: DTA 数据结构的示例如表 A.09-1 所示。
注意 2: 每次调用 INT 21\AH=0Dh 函数 (8.02-09) 后,DTA 将返回其默认位置 (PSP:0080h)。
准备 : AH = 1Ch DL - 逻辑磁盘编号 (注意 1) 返回 : AH - 介质标识符 (ID 字节): = F8h - 固定磁盘 (HDD), = F9h - 1.2 Mb 或 720 kb 软盘, = FAh - 虚拟 RAM 盘, = FDh - 360 kb 软盘, = F0h - 其他介质,包括 1.44 Mb 软盘。 CX - 每扇区的字节数; DS:BX - 指向内存中的同一介质标识符字节; DX 和 AL 的内容不会保留。
注 1:此函数使用“移位”的逻辑磁盘编号:00h 是默认(“当前”)逻辑磁盘,然后是 01h = A:,02h = B:,03h = C:,依此类推。
注 2:应用于无效或不存在的磁盘时,INT 21\AH=1Ch 不会使用 CF 标志指示错误,而是返回 AH、BX 和 DS 寄存器中的值不变。
注 3:INT 21\AH=1Bh 以相同的方式报告有关默认(“当前”)磁盘的信息,忽略 DL 内容。INT 21\AH=1Ch 和 INT 21\AH=1Bh 都是过时的函数,无法识别大多数现代媒体类型。
准备:AH = 25h AL – 中断号,其处理程序地址将被写入 DS:DX – 指向新的中断处理程序的指针
注 1:此函数覆盖了以前处理程序的地址。如果它不应该丢失,您必须事先注意保存它。
注 2:MS-DOS7 提供的 INT 21\AH=25h 处理程序可以在 CPU 处于实模式或 V86 模式时使用,但在保护模式下不能使用。
INT 21\AX=2901h 函数排列一个未打开的普通类型 FCB(文件控制块)(A.09-5),其中填充了给定文件名的规范形式。文件的文件名和扩展名分别写入其 FCB 字段,字母被转换为大写字母,星号通配符(2.01-03)被扩展为适当数量的“?”通配符。如果文件名少于 8 个字节,或扩展名少于 3 个字节,则其余空闲字符单元将用空格(20h)填充。解析在遇到第一个斜杠或空格或 0Dh 终止符字节时停止(00h 终止符字节不允许)。
文件名不能以路径开头,但可以以磁盘的字母名称开头(例如,A:Config.sys)。磁盘的字母名称将被转换为逻辑磁盘号,写入 FCB 中文件名字段之前的单元格。如果给定行中的第二个字符不是冒号,则磁盘的字母名称被视为缺失,并且 FCB 中的磁盘号单元格将填充 00h – 默认(“当前”)磁盘的编号。
准备:AH = 2901h DS:SI – 指向要解析的文件名字符串的指针(允许通配符)ES:DI – 指向准备好的缓冲区的指针,长度为 21 个字节,用于 FCB
返回时:AL = 00h – 解析成功,没有遇到通配符 = 01h – 解析成功,通配符存在 = FFh – 解析失败(无效规范)DS:SI – 指向解析停止的字符的指针 ES:DI – 指向已填充未打开的 FCB 的缓冲区的指针
注 1:如果 FCB 稍后需要被转换为“打开”形式以提供对文件的访问,则缓冲区必须长 36 个字节。
注 2:解析也可以由 INT 21\AX=2903h 函数执行,该函数不会覆盖 FCB 中磁盘号单元格的先前内容。
准备:AH = 2Ah
返回时:AL – 星期几(00h = 星期日)CX – 年份(范围 1980 – 2099)DH – 月份 DL – 日
注 1:所有值都以压缩十进制格式返回,即每个字节两位十进制数。
注 2:系统日期可以通过 INT 21\AH=2Bh 函数更改。所需的值应以 AL、CX、DH、DL 寄存器的形式准备,如上所示。如果 INT 21\AH=2Bh 函数失败,它将返回 AL=FFh 并保持系统日期不变。
准备:AH = 2Ch
返回时:CH – 小时 CL – 分钟 DH – 秒 DL – 秒的 1/100 部分
注 1:所有值都以压缩十进制格式返回,即每个字节两位十进制数。
注 2:某些计算机以 0.05 秒的步长计算 DL 值,而另一些计算机始终返回 DL = 00h。
注 3:系统时间可以通过 INT 21\AH=2Dh 函数更改。所需的值应以 CH、CL、DH、DL 寄存器的形式准备,如上所示。如果 INT 21\AH=2Dh 函数失败,它将返回 AL=FFh 并保持系统时间不变。
准备:AX = 3000h – 在 BH 中返回制造商(OEM)标识符 = 3001h – 在 BH 中返回版本标志字节。
返回时:AL.AH – DOS 版本号 BH – OEM 标识符或版本标志字节。
注 1:OEM 标识符对于 IBM 为 00h,对于 PhysTechSoft 为 66h,对于 DR-DOS 为 EEh,对于 Novell 为 EFh,对于 FreeDOS 为 FDh,对于 Microsoft 为 FFh。
注 2:版本标志字节中位 3 的 TRUE 状态标志着专为存储在 ROM 中而设计的特殊 DOS 版本。
注 3:返回的版本号是从调用程序的 PSP(A.07-1)中偏移量为 40h 的字读取的。如果安装了 SETVER.EXE 驱动程序,并且如果调用程序的名称已写入 SETVER 的表中,则请求的版本将替换调用程序的 PSP 中偏移量为 40h 的真实 DOS 版本号。
注 4:INT 21\AX=3306h 函数(8.02-27)肯定会报告真实的 DOS 版本号。
准备:AH = 31h AL – 十六进制错误级别值(注意 8.02-55 的第 3 点)DX – 驻留模块的大小,以 16 字节段为单位,不小于 6 个段,从 PSP(A.07-1)的开头算起。
注 1:INT 21\AH=31h 函数释放主程序的内存(除了其驻留模块),恢复中断表中的指针,恢复段寄存器的状态和堆栈,然后将控制权转移到 INT 22(8.02-82)指向的调用程序代码。但是 INT 21\AH=31h 函数不会关闭已打开的文件,也不会释放环境内存区域以及通过 INT 21\AH=48h(8.02-50)分配的内存。如有必要,这些操作必须由程序在终止之前执行。
注 2:过时的 INT 27 处理程序(8.02-86)执行相同的操作,但将驻留模块的大小限制为 64 kb 并且不会留下错误级别值。
准备:AH = 32h DL – 逻辑磁盘号(注意 8.02-17 的第 1 点)
返回时:AL = FFh, – 请求的磁盘无效或网络磁盘 = 00h, – 请求成功执行,然后 DS:BX – 指向 DPB 块的指针(A.03-1)
注 1:也可以通过 INT 21\AH=1Fh 获取指向默认(“当前”)磁盘的 DPB 的指针;后者会忽略 DL 中的值。
注 2:INT 21\AH=32h 和 INT 21\AH=1Fh 都尝试通过读取请求的磁盘来更新 DPB。如果读取失败,INT 24 处理程序将被调用,并带有其“中止、重试、失败?”问题。如果此时不希望尝试访问磁盘,可以通过 DOS 的列表列表找到指向任何 DPB 的指针(注意 A.01-2 的第 1 点)。
注 3:INT 21\AH=32h 和 INT 21\AH=1Fh 无法应用于使用 FAT-32 格式化的磁盘:然后应使用 INT 21\AX=7302h 函数(8.02-79)代替。
准备:AX = 3300h
返回时:DL = 00h – BREAK 标志关闭 = 01h – BREAK 标志打开
注 1:BREAK 标志位于 DOS 的可交换区域,偏移量为 17h(A.01-3)。
注 2:BREAK 标志的状态可以通过 INT 21\AX=3301 函数更改,该函数以相同的方式接受要设置的状态,来自 DL 寄存器。
准备:AX = 3305h
返回时:DL – 启动驱动器号(注意 8.02-17 的第 1 点)
注 1:INT 21\AX=3305h 函数从 DOS 的列表列表(A.01-2)中偏移量为 43h 的位置读取用于启动 PC 的磁盘的编号。
准备:AX = 3306h
返回时:AL = FFh,如果 DOS 的真实版本低于 5.00。当 AL 寄存器返回其他任何值时,则:BL.BH - DOS 的真实版本 DH - 标志位:位 3 - DOS 存储在 ROM 中 位 4 - DOS 加载到 HMA 区域 DL - DOS 修订号。
注意 1:INT 21\AX=3306h 函数返回的数据不受 SETVER.EXE 驱动程序的影响(与 INT 21\AH=30h 返回的数据不同)。
注意 2:INT 21\AX=3306h 函数在低于 5.00 的 DOS 版本中不受支持。除了 AL = FFh 之外,过时的 DOS 版本的症状可能是 BL < 05h 和 BH > 64h。
InDOS 标志是活动 DOS 函数嵌套级别的字节计数器:每当调用任何 INT 21 函数时,它都会递增,并在其执行终止时递减。在从任何驻留模块调用 DOS 函数之前,应检查 InDOS 标志和严重错误标志(注意 1)的状态:如果这两个标志中的任何一个具有非零值,则此类调用不安全。由于相同的原因,INT 21\AH=34h 函数应在 TSR 程序初始化时调用一次,并且应保存返回的指针。稍后,当调用 DOS 函数可能不安全时,可以立即读取系统标志的状态,这得益于保存的指针。
准备:AH = 34h
返回时:ES:BX - 指向一个字节 InDOS 标志的指针
注意 1:严重错误标志是紧接 InDOS 标志之前的字节(A.01-3)。可以通过 INT 21\AX=5D06h 函数获取指向严重错误标志的指针。
准备:AH = 35h AL - 中断号
返回时:ES:BX - 指向中断处理程序的指针。
准备:AH = 36h DL - 逻辑磁盘号(8.02-17 的注意 1)
返回时:AX - 每个簇的扇区数 BX - 可用簇数 CX - 每个扇区的字节数 DX - 请求磁盘上的总簇数
注意 1:可用空间(以字节为单位)可以作为 AX * BX * CX 的乘积找到。
注意 2:整个磁盘的空间(以字节为单位)可以作为 AX * CX * DX 的乘积找到。
注意 3:INT 21\AH=36h 函数将“丢失”的簇计入已使用的簇中。
注意 4:在请求无效或不存在的磁盘后,将返回 AX = FFFFh 值。在请求 CD\DVD-ROM 后,返回的数据肯定无效。
注意 5:允许请求 FAT-32 磁盘,但实际报告的空间限制为 2048 MB。对于更大的磁盘,应使用 INT 21\AX=7303h 函数(8.02-80)代替。
准备:AH = 39h - 创建子目录 = 3Ah - 删除空子目录 DS:DX - 指向包含目标目录名称的字符串的指针。字符串必须以 00h 字节结尾。名称前面可以有路径。字符串的最大长度为 64 字节。
返回时:出错时,CF 标志被置位,AL 返回错误代码(A.06-1)。CF 标志的清除状态表示成功终止。AX 的内容不会被保留。
注意 1:如果目录是根目录,或者它不是空闲的,或者它在 CDS 表中被标记为“当前”(A.03-3),则不能删除目录。
注意 2:与普通目录不同,根目录的容量有限:如果根目录已满,则无法在该根目录中创建新的子目录。
INT 21\AH=3Bh 函数会将特定磁盘的 CDS 表项(A.03-3)中的默认目录路径名重写。
准备:AH = 3Bh DS:DX - 指向包含新默认目录名称的字符串的指针。字符串必须以 00h 字节结尾。名称前面可以有路径,可以选择包含磁盘的字母名称。字符串的最大长度为 64 字节。
返回时:出错时,CF 标志被置位,AL 返回错误代码(A.06-1)。CF 标志的清除状态表示成功终止。AX 的内容不会被保留。
注意 1:如果对 INT 21\AH=3Bh 的调用指定了一个磁盘,而该磁盘此时不是“当前”磁盘,则“当前”目录不会立即更改,但提议的默认目录将在“当前”状态被分配到指定磁盘时成为“当前”目录。
注意 2:INT 21\AH=47h 函数(8.02-49)报告默认目录的当前分配。
句柄是 SFT 条目(A.01-4)的十六进制标识符。每个 SFT 条目都与某个对象相关联:要么与现有文件相关联,要么与 XMS 内存的专用区域相关联,要么与访问通道相关联。句柄可以被视为对该对象的数字引用。INT 21\AH=3Dh 函数会调查 SFT 表中是否包含与指定对象相关的条目。如果相关的条目已经存在,则该条目中注册的引用数量会增加 1,该 SFT 条目的编号会写入 JFT 表(A.07-1,偏移量 18h)中的字节单元,并且该字节单元在 JFT 表中的序号将作为请求的句柄返回给调用程序。如果与指定对象相关的 SFT 条目不存在,则 INT 21\AH=3Dh 处理程序会为指定对象创建一个新的 SFT 条目,然后执行与之前描述相同的操作序列,最终将新的句柄返回给调用程序。那些获得了关联句柄的文件被称为“打开”的文件。
准备:AH = 3Dh AL - 访问和共享权限(A.09-4) DS:DX - 指向对象名称的指针(以 00h 字节结尾)
返回时:出错时,CF 标志被置位,AX 返回错误代码(A.06-1)。CF 标志的清除状态表示成功终止,然后 AX - 句柄 - 对指定对象的数字引用
注意 1:为了获取驱动程序控制通道的句柄,您必须指定该名称,该名称存储在驱动程序头的偏移量 0Ah 处(A.05-1)。在附录 A.01-2 的注意 2、文章 8.03-12 和第 8.03 部分的介绍性文章中描述了查找驱动程序头的几种方法。
注意 2:对象名称中不允许使用通配符。
注意 3:打开文件时,它的访问点将设置为它的第一个字节。
注意 4:打开文件的可能性不取决于它的属性,但 INT 21\AH=3Dh 函数无法将句柄与目录相关联。
注意 5:INT 21\AH=3Dh 处理程序可以通过服务器函数 INT 21\AX=5D00h(8.02-68)调用,这使得可以在 CL 寄存器中为要打开的文件指定属性掩码(A.09-2)。
注意 6:从父程序继承的句柄继承相同的共享和访问限制。AL 寄存器中的访问权限字节(A.09-4)也定义了特定句柄是否会被继承。
注意 7:如果文件存储在使用 FAT-32 文件系统格式化的逻辑磁盘中,则应通过 INT 21\AX=6C00h 函数(8.02-78)为该文件提供关联的句柄。
INT 21\AH=3Eh 函数会将关联的 SFT 条目(A.01-4)中对相同对象的注册引用数量减少 1,并从调用程序的 JFT 表(A.07-1)中的字节单元中删除该条目的编号。如果对象是文件,并且它已经被修改,则相应的目录记录会被修正,并且磁盘缓冲区的内容会被写回磁盘。如果调用程序没有对同一个文件的重复句柄,则该文件将变得不可访问,或者对于调用程序来说“关闭”。但操作系统只在对该文件的引用数量为 0 时才认为文件关闭:只有在这种情况下,才能删除该文件,并且只有在这种情况下,该文件才会不再阻止其驱动器中的可移动介质。具有 0 个引用的 SFT 条目也被认为是已关闭的,并且无效。
准备:AH = 3Eh BX - 要删除的句柄(8.02-33)
返回时:出错时,CF 标志被置位,AX 返回错误代码(A.06-1)。CF 标志的清除状态表示成功终止。AX 的内容不会被保留。
注释 1:句柄可以通过 INT 21\AH=68h 和 INT 21\AH=6Ah 函数删除。这些函数的其他规范(除 AH 外)相同。
注释 2:当一个程序准备终止时,所有由该程序打开的文件可以通过 INT 21\AX=5D01h 函数(8.02-69)一次性关闭。
注释 3:由 EMM386.EXE 驱动程序(5.04-02)打开的扩展内存区域的句柄,应通过 INT 67\AH=45h 函数(8.03-61)删除。
准备:AH = 3Fh BX – 源对象的句柄(8.02-33):文件、通道或设备 CX – 要读取的字节数 DS:DX – 指向用于读取数据的缓冲区的指针
返回值:发生错误时,CF 标志被设置,AX 返回错误代码(A.06-1)。CF 标志清除状态表示成功终止,然后 AX – 实际读取的字节数,DS:DX – 指向已填充数据的缓冲区的指针。
注释 1:每个程序都会自动继承句柄 0000h,这使得能够从 STDIN 通道源读取数据,当然,当 STDIN 通道准备好提供这些数据时。但是,如果 STDIN 通道没有被重定向,并且其缓冲区为空,那么对 0000h 句柄的请求会启动一个缓冲区填充过程,并等待来自键盘的输入。输入的字符将显示在屏幕上,其数量不受 CX 寄存器中数字的限制。输入在 ENTER 键按下后终止,然后,预设在 CX 寄存器中的字符数量从 STDIN 缓冲区读取到另一个缓冲区,该缓冲区由 DS:DX 指针定义。STDIN 缓冲区中的剩余字符可供 INT 21\AH=3Fh 函数的后续调用读取。
注释 2:文件数据从当前访问位置开始读取,因此在每次成功读取操作后,访问位置都会更新。
注释 3:如果 CX 寄存器中请求的字节数导致访问位置超出文件末尾,那么 INT 21\AH=3Fh 函数将成功终止,但 AX 寄存器中返回的读取字节数将小于 CX 寄存器中请求的字节数。
准备:AH = 40h BX – 目标对象的句柄(8.02-33):文件、通道或设备 CX – 要传输的字节数 DS:DX – 指向包含要传输数据的缓冲区的指针
返回值:发生错误时,CF 标志被设置,AX 返回错误代码(A.06-1)。CF 标志清除状态表示成功终止,然后 AX – 实际传输的字节数。
注释 1:每个程序都会自动继承 4 个活动句柄到目标通道:0001h – 到 STDOUT 通道,0002h – 到 STDERR 通道,0003h – 到 STDAUX 通道(COM1 端口),以及 0004h – 到 STDPRN 通道(LPT1 端口)。STDOUT 通道可以被重定向,但其默认目标是显示。STDERR 通道不能被重定向;它始终将字符显示在屏幕上。
注释 2:写入文件从 SFT 中定义的当前访问位置开始(在表 A.01-4 中的偏移量为 15h)。在每次成功写入过程后,当前访问位置都会自动更新。如果写入过程导致当前访问位置超出文件末尾,那么文件的长度会自动增加。但是,直到文件句柄被删除(8.02-48)之前,所产生的更改都不会写入磁盘。
注释 3:使用 CX = 0000h 的调用不会导致数据传输,但会导致目标文件被截断(或扩展)到该长度,该长度由当前访问位置定义。
注释 4:在使用 FAT-32 文件系统的逻辑磁盘上,如果文件通过 INT 21\AX=6C00h 函数打开,并且“扩展大小”标志处于 TRUE 状态,那么文件允许增长超过 2 Gb。
注释 5:如果在数据传输后,AX 寄存器中返回的数字小于 CX 寄存器中请求的数字,那么造成这种差异最可能的原因是目标磁盘上没有足够的可用空间。
准备:AH = 41h DS:DX – 指向包含文件名字符串的指针。名称前可以加路径。字符串必须以 00h 字节结尾。
返回时:出错时,CF 标志被置位,AX 返回错误代码(A.06-1)。CF 标志的清除状态表示成功终止。AX 的内容不会被保留。
注释 1:删除的文件不会被物理擦除;而是其目录条目被标记为无效:该条目的第一个字符将被无效标记(代码 E5h)覆盖。
注释 2:通过 INT 21\AH=41h 函数删除任何带有长文件名的文件都不会影响主条目之外的相关条目,而这些目录条目包含长文件名的延续。
注释 3:可以删除打开的文件,但它们的句柄将保持活动状态。这可能会导致 FAT 损坏和数据丢失。每个要删除的文件都必须提前关闭(8.02-34)。
注释 4:文件名中的通配符不允许使用,除非 INT 21\AH=41h 是通过服务器函数 INT 21\AX=5D00h 调用。服务器函数还允许在 CL 寄存器中为要删除的文件指定属性掩码(A.09-2)。
注释 5:也可以通过 INT 21\AH=13h 函数(8.02-13)删除当前目录中的文件。
文件的访问位置由文件 SFT 条目中的指针定义(在表 A.01-4 中的偏移量为 15h)。访问点位置从文件开始处计算。INT 21\AH=42h 函数会影响文件 SFT 条目中的该指针,从而移动文件的访问点。
准备:AH = 42h AL – 请求的访问点移动的来源代码:= 00h – 文件开始处 = 01h – 当前访问点位置(注释 1) = 02h – 文件末尾(注释 1) BX – 文件的句柄(8.02-33) CX:DX – 从 AL 寄存器中指定的来源处的请求访问点的双字移动。
返回值:发生错误时,CF 标志被设置,AX 返回错误代码(A.06-1)。CF 标志清除状态表示成功终止,然后 DX:AX – 从文件开始处计算的新的访问点位置。
注释 1:选择来源代码 01h 和 02h 意味着 CX:DX 中的请求移动是带符号的双字。带符号移动的操作可能会将访问点设置在文件开始处之前。在这种情况下,INT 21\AH=42h 函数会返回 CF 标志清除,但错误会在访问尝试时显现出来。
注释 2:如果新的访问点位置超出文件末尾,那么最接近的下一次写入操作(8.02-36)会自动将文件的长度扩展到实际的访问点位置。
注释 3:在使用 AX=4202h 和 CX=DX=0000h 的 INT 21\AH=42h 函数调用后,DX:AX 寄存器中会返回文件的大小(以字节为单位)。
注释 4:在使用 FAT-32 文件系统的逻辑磁盘上,如果文件通过 INT 21\AX=6C00h 函数打开,并且“扩展大小”标志处于 TRUE 状态,那么允许超出 2 Gb 的文件访问点位置。
准备:AX = 4300h DS:DX – 指向包含文件名字符串的指针。名称前可以加路径。字符串必须以 00h 字节结尾。
返回值:发生错误时,CF 标志被设置,AX 返回错误代码(A.06-1)。CF 标志清除状态表示成功终止,然后 CX – 文件的属性字(A.09-2)
注释 1:INT 21\AX=4301h 函数可以设置 CX 寄存器中准备的属性。返回值时,AX 内容可能会丢失。其他功能相同。
句柄 (8.02-33) 是一个十六进制标识符,用于标识 SFT 条目 (A.01-4)。每个 SFT 条目都与某个对象相关联:可以是现有的文件,也可以是 XMS 内存的专用区域,或者是一个访问通道。句柄可以被视为对该对象的数字引用。INT 21\AH=4400h 函数可以用来获取给定句柄本身及其关联对象的某些属性。
准备:AX = 4400h BX - 句柄 (8.02-33)
返回:错误时 CF 标志被设置,AX 返回错误代码 (A.06-1)。CF 标志的清除状态表示成功终止,此时 AX 的内容不会被保留;DX - 数据字 (注 1)
注 1:返回的数据字中第 7 位的清除状态表示文件句柄数据字,应根据表 A.04-2 进行解释。返回的数据字中第 7 位的设置(TRUE)状态表示非文件对象的属性字。此属性字应根据表 A.05-2 进行解释。
注 2:属性字 (A.05-2) 中通道句柄的属性可以通过 INT 21\AX=4401h 函数进行校正。属性字的第 7-0 位的状态应在 DX 寄存器中准备,第 15-8 位必须清除,AX = 4401h,其他所有规格相同。
I/O 控制 (IOCTL) 的主要思想是 DOS 为驱动程序的控制数据分配一些内存空间,并允许程序访问此内存空间以读取和影响驱动程序的控制数据。INT 21\AX=4402h–4403h 处理程序负责访问驱动程序的控制数据。
驱动程序属性字 (A.05-2) 中第 6 位和第 7 位的状态表示特定驱动程序是否支持可编程 I/O 控制。如果支持可编程 I/O 控制,则可以使用句柄来寻址该驱动程序的控制数据,该句柄可以通过 INT 21\AH=3Dh 或 INT 21\AX=6C00h 函数打开 (8.02-33 的注 1)。
准备:AX = 4402h - 读取驱动程序控制数据 = 4403h - 发送驱动程序控制数据 BX - 引用目标驱动程序的句柄 (8.02-33) CX - 要传输的字节数(缓冲区的长度) DS:DX - 指向用于数据或要发送数据的缓冲区
返回值:发生错误时,CF 标志被设置,AX 返回错误代码(A.06-1)。CF 标志清除状态表示成功终止,然后 AX – 实际传输的字节数。
注 1:控制数据的格式对于每个特定驱动程序都是唯一的。例如,表 A.15-4 显示了 CD/DVD-ROM 驱动程序的一组命令。
注 2:磁盘驱动器 (块设备) 的驱动程序控制数据不能使用句柄来寻址,但可以通过 INT 21\AX=4404h 读取,并通过 INT 21\AX=4405h 发送。这些函数的数据规范与上面显示的类似,除了 AX 和 BX 寄存器:BL 指定磁盘号 (8.02-17 的注 1),BH 被忽略。
准备:AX = 4406h - 输入(读取)就绪检查 = 4407h - 输出(写入)就绪检查 BX - 引用目标对象的句柄 (8.02-33)。
返回:错误时 CF 标志被设置,AX 返回错误代码 (A.06-1)。CF 标志的清除状态表示成功终止,此时 AL = FFh - 表示目标对象已准备好访问 = 00h - 表示目标对象尚未准备好访问。
注 1:如果文件访问点通过访问点移位操作 INT 21\AH=42h (8.02-38) 设置在文件末尾,则 INT 21\AX=4406h 检查可能会错误地报告文件已准备好读取 (AL = FFh)。当文件访问点通过读取或写入操作 (8.02-35, 8.02-36) 设置时,此错误不会发生。
注 2:INT 21\AX=4407h 函数不检查驱动器中是否有介质,也不检查该介质是否有可用空间用于写入。
准备:AX = 4408h BL - 逻辑磁盘号 (8.02-17 的注 1)
返回:错误时 CF 标志被设置,AX 返回错误代码 (A.06-1)。CF 标志的清除状态表示成功终止,此时 AX = 0000h - 请求的逻辑磁盘是可移动的,= 0001h - 请求的逻辑磁盘是固定的 (HDD)。
驱动程序的属性可以用来确定请求的磁盘是真实的还是虚拟的,是本地磁盘还是网络驱动器,是否可用于 BIOS 函数。返回的属性字的解释如表 A.05-2 所示。
准备:AX = 4409h BL - 逻辑磁盘号 (8.02-17 的注 1)
返回:错误时 CF 标志被设置,AX 返回错误代码 (A.06-1)。CF 标志的清除状态表示成功终止,此时 AX 的内容不会被保留;DX - 驱动程序的属性字 (A.05-2)。
注 1:驱动程序属性字反映驱动程序的功能,这些功能不一定与请求的磁盘的属性相对应。例如,属性字中第 11 位的 TRUE 状态被解释为驱动程序能够支持可移动介质,但这并不能说明请求的磁盘是可移动磁盘。
准备:AX = 440Ah BX - 句柄 (8.02-33)
返回:错误时 CF 标志被设置,AX 返回错误代码 (A.06-1)。CF 标志的清除状态表示成功终止,此时 DX >= 8000h - 表示通过网络访问。
INT 21\AX=440Dh 函数实际上是调用许多 IOCTL 子函数的模板。子函数的类型由 CL 寄存器中的代码定义。CH 寄存器的内容定义类别代码:CH = 08h 对应于磁盘子函数,这些子函数继承自先前版本的 DOS,并且可以应用于具有 FAT-12 和 FAT-16 文件系统的磁盘。类别代码 CH=48h 对应于在 MS-DOS7 中引入的磁盘子函数,这些子函数可以应用于具有 FAT-32 文件系统的磁盘。
本文介绍了类别代码 CH = 48h 的子函数,这些子函数可以应用于具有 FAT-12、FAT-16、FAT-32 文件系统的磁盘,并且不需要 BIOS 对 INT 13 扩展的支持 (8.01-55)。可以使用 INT 21\AX=4411h 函数 (8.02-47) 检查您的计算机是否支持特定 IOCTL 子函数。
所有 IOCTL 子函数的数据表示的通用形式是由 DS:DX 寄存器指向的数据块。对于某些子函数,此数据块中数据的解释如附录 A.04 所示。下面说明了其他几个子函数的特定条件。
准备:AX = 440Dh BL - 逻辑磁盘号 (8.02-17 的注 1) CX - 子函数:= 4840h - 从表中设置磁盘参数 (A.04-3) = 4841h - 将磁道写入逻辑磁盘 (A.04-4) = 4842h - 格式化并验证逻辑磁盘上的磁道 (A.04-5) = 4846h - 设置卷的序列号 (A.04-1) = 4847h - 设置访问标志 (注 1) = 4848h - 设置介质锁定状态 (注 2) = 4849h - 从驱动器中弹出介质(不需要数据块) = 4860h - 读取磁盘参数 (A.04-3) = 4861h - 从逻辑磁盘读取磁道 (A.04-4) = 4862h - 验证逻辑磁盘的磁道 (A.04-5) = 4866h - 获取卷的标签和 FAT 类型 (A.04-1) = 4867h - 获取访问标志 (注 1) = 4868h - 确定软盘类型 (注 3) DS:DX - 指向数据块的指针,如果子函数需要的话
返回:错误时 CF 标志被设置,AX 返回错误代码 (A.06-1)。CF 标志的清除状态表示成功终止,此时 DS:DX - 指向数据块的指针,如果子函数需要返回的话。
注 1:子函数 CX=4847h 接受,子函数 4867h 在 DS:DX 数据块中返回的只是偏移量为 01h 的访问字节。任何非零值都表示允许访问。
注 2:子函数 CL=4848h 从 DS:DX 数据块中偏移量为 00h 的字节中接受操作代码:00h - 锁定磁盘,02h - 解锁磁盘,03h - 报告锁定状态(与 INT 13\AH=45h, 8.01-58 相同)。锁定状态 - 该磁盘上挂起的锁定的数量 - 在相同数据块的字节 01h 中返回。
注释 3:在 DS:DX 数据块中偏移地址 00h 的字节处,子函数 CX=4868h 返回代码 01h,如果介质是请求驱动器的默认类型,否则返回代码 00h,如果介质是任何其他类型。特定介质类型的代码在同一数据块的偏移地址 01h 的字节处返回:02h - 720kb 软盘,07h - 1.44 Mb 软盘,09h - 2.88 Mb 软盘。
INT 21\AX=4411h 函数用于检查特定 PC 上的 BIOS、硬件和可安装驱动程序是否支持指定的 IOCTL 子函数。
准备:AX = 4411h BL - 逻辑磁盘号(参见 8.02-17 的注释 1)CX - 子函数代码,与 INT 21\AX=440Dh(8.02-46)相同。
返回:发生错误时,CF 标志被置位,AX 返回错误代码(A.06-1)。CF 标志的清除状态表示成功终止,此时 AX = 0000h - 确认请求的函数受支持。
注释 1:INT 21\AX=4411h 函数本身和其他一些 IOCTL 子函数的支持可以通过驱动程序的属性字 (A.05-2) 来确认。
INT 21\AH=45h 函数将 JFT 表(参见 A.07-1 的注释 3)中的一个字节单元中的 SFT 条目号复制到同一 JFT 表中最近的空闲字节单元中。这两个字节单元的序号变成了句柄,它们与同一个 SFT 条目和同一个“打开”对象相关联。创建重复句柄可能是为了保存 SFT 条目号,或者为了在 JFT 表中重新定位条目号,或者仅仅是为了删除重复句柄,因为删除句柄会启动文件保存到磁盘,而另一个句柄的存在会阻止文件的关闭。
INT 21\AH=46h 函数也会将 JFT 表中的一个字节单元中的 SFT 条目号复制到一个预定的字节单元中,覆盖该单元中的前一个 SFT 条目号。例如,如果与 STDOUT 通道关联的 0001h 句柄被设置为与文件关联的另一个句柄的重复句柄,那么通常发送到显示器的输出将被重定向到该文件。DOS 正是通过这种方式执行输入和输出数据流量的重定向(2.04-02 - 2.04-05)。
准备:AH = 45h - 复制,保留当前关联 = 46h - 复制,覆盖选定的关联 BX - 活动句柄(8.02-33),它将被复制 CX - 另一个句柄,它将获得 BX 中句柄的关联(仅对于 INT 21\AH=46h 函数)。
返回:发生错误时,CF 标志被置位,AL 返回错误代码 (A.06-1)。CF 标志的清除状态表示成功终止,此时 AX - 自动分配的重复句柄(仅在调用 INT 21\AH=45h 函数后)。
注释 1:如果 CX 寄存器中指定的句柄与一个打开的文件相关联,那么在调用 INT 21\AH=46h 函数后,该文件将自动关闭。
注释 2:重复句柄的文件访问点的移动会导致另一个句柄的文件访问点的相同移动,因为两者都引用同一个 SFT 条目 (A.01-4)。
准备:AH = 47h DL - 逻辑磁盘号(参见 8.02-17 的注释 1)DS:SI - 指向路径名的 64 字节缓冲区的指针。
返回:发生错误时,CF 标志被置位,AL 返回错误代码 (A.06-1)。CF 标志的清除状态表示成功终止,此时 AX 的内容不会被保留;DS:SI - 指向路径名的指针,以 00h 字节结尾。
注释 1:返回的路径名不包括磁盘的字母名称和初始反斜杠。
注释 2:默认目录分配可以通过 INT 21\AH=3Bh 函数(8.02-32)更改。
准备:AH = 48h BX - 请求的块的大小(以 16 字节段为单位)
返回:发生错误时,CF 标志被置位,AL 返回错误代码 (A.06-1)。CF 标志的清除状态表示成功终止,此时 AX - 分配的块的段地址 BX - 最大可用块的大小(以段为单位)。
注释 1:BX=FFFFh 的请求无法满足,但执行 INT 21\AH=48h 函数后,BX 寄存器会返回可用常规内存的总大小。
注释 2:来自 *.COM 程序的 INT 21\AH=48h 函数的请求可能会失败并返回错误代码 AL=08h (“内存不足”),因为默认情况下,DOS 会将所有可用常规内存分配给任何当前执行的 *.COM 程序(有关详细信息,请参见 A.12-7 的注释 5)。*.COM 程序必须通过调用 INT 21\AH=4Ah 函数 (8.02-52) 来声明所需的内存量,否则所有剩余的常规内存将不会被视为可用内存。
准备:AH = 49h ES - 要释放的块的段地址
返回:发生错误时,CF 标志被置位,AL 返回错误代码 (A.06-1)。CF 标志的清除状态表示成功终止。
准备:AH = 4Ah BX - 请求的块的大小(以 16 字节段为单位)ES - 要调整大小的块的段地址
返回:发生错误时,CF 标志被置位,AL 返回错误代码 (A.06-1)。CF 标志的清除状态表示成功终止,此时:BX - 指定内存块可用的最大段数
注释 1:如果内存不足以按请求扩展块,则块将尽可能大。
准备:AH = 4Bh AL - 子函数:= 00h - 加载和启动执行 = 01h - 加载但不启动执行 = 03h - 覆盖加载(可交换的代码部分)DS:DX - 指向包含程序调用完整规范的字符串的指针。程序名称必须包含后缀。该字符串必须以 00h 字节结尾。ES:BX - 指向参数块 A.07-2 的指针。
返回:发生错误时,CF 标志被置位,AL 返回错误代码 (A.06-1)。CF 标志的清除状态表示成功终止。BX 和 DX 寄存器的内容不会被保留。
注释 1:子函数 AL=00h 为加载的程序创建一个新的 PSP(A.07-1),并用调用者的环境的副本填充其环境段。新 PSP 中的命令行以字节 00h 结尾(而在普通 PSP 中,它以字节 0Dh 结尾)。
注释 2:调用者的任务包括检查是否有足够的内存用于加载的程序。
注释 3:加载过程由 AL = 00h 和 AL = 01h 子函数以相同的方式执行,但后者不会启动加载的程序的执行。为了启用延迟执行启动,在 ES:BX 参数块 (A.07-2) 中,AL = 01h 子函数会返回加载程序的入口点地址和指向其堆栈顶部的指针。
注释 4:如果可执行文件以签名 MZ 或 ZM 开头,则它将被加载并执行为 *.EXE 程序。要作为 *.COM 程序执行的可执行文件不应该以签名 LE、LX、MP、MZ、NE、P2、P3、PE、PL、W3、W4、ZM 开头。
注释 5:为了执行批处理文件,INT 21\AH=4Bh 函数必须加载带 /C 参数的命令解释器 COMMAND.COM (6.04)。批处理文件的名称应在该参数之后指定,位于由 DS:DX 指向的同一字符串中。
注释 6:当子函数 AL = 03h 加载覆盖时,它不会创建 PSP 和环境,不会启动加载的代码的执行,也不会检查目标内存区域是否已分配给调用者程序。子函数 AL = 03h 需要其他形式的 ES:BX 参数块:第一个字必须是目标段地址,偏移地址 02h 处的第二个字必须是覆盖重定位因子。
INT 21\AX=4B05h 函数由拦截 INT 21\AX=4B00h 调用的程序使用,以便为程序执行做准备,包括替换 DOS 版本号。
准备:AX = 4B05h DS:DX – 指向执行状态描述符的指针 (A.07-3) 返回:发生错误时,CF 标志被置位,AL 返回错误代码 (A.06-1)。CF 标志清除表明成功终止,此时 AX = 0000h。
注意 1:从 INT 21\AX=4B05h 调用返回到子进程启动之间,不允许执行任何 DOS、BIOS 或其他软件中断。
注意 2:如果 DOS 在 HMA 区域运行,则从 INT 21\AX=4B05h 调用返回后,A20 线会被关闭。
准备:AH = 4Ch AL – 十六进制错误级别代码 (注意 3)
返回:不会发生返回。
注意 1:在应用 INT 21\AH=4Ch 函数之前,应释放由执行的程序设置的所有网络锁。
注意 2:INT 21\AH=4Ch 函数会关闭执行的程序打开的所有文件,并释放其所有内存,除非父 PSP 指针 (在 PSP 中偏移量为 16h,A.07-1) 指向当前 PSP 本身。这是永久加载程序的症状,例如命令解释器 COMMAND.COM (6.04)。
注意 3:指定的错误级别代码被写入 DOS 可交换数据区 (A.01-3) 中偏移量为 14h 的字。存储的错误级别代码可以在以后由 INT 21\AH=4Dh 函数 (8.02-56) 读取,或者可以通过 "If errorlevel..." 命令 (3.15-03) 检查。
注意 4:在 DEBUG.EXE 的操作环境内,INT 21\AH=4Ch 函数会关闭调试器的会话并将控制权转移到 DOS。如果需要继续调试器的会话,则应通过其他方式终止被测程序的执行:要么使用断点,要么调用 INT 20 (8.02-01)。
准备:AH = 4Dh
返回:AH – 终止类型:= 00h – 正常终止 (8.02-01, 8.02-55) = 01h – 由 CTRL-C 按键引起的中止 (8.01-95, 8.02-83) = 02h – 由严重错误引起的中止 (8.02-84) = 03h – 终止并留下驻留模块 (8.02-23, 8.02-86) AL – 十六进制错误级别代码 (注意 1 和 2)
注意 1:错误级别提供有关先前程序终止情况的信息,但不包括永久加载程序和在后台模式下执行的程序。
注意 2:错误级别存储在 DOS 可交换数据区 (A.01-3) 中偏移量为 14h 的字。每次调用 INT 21\AH=4Dh 函数后,错误级别会自动清除;这就是为什么它只能读取一次。可以使用批处理文件 (3.15-03) 多次读取错误级别值。
注意 3:COMMAND.COM 解释器的内部命令不会留下错误级别代码,也不会影响先前程序终止后留下的代码。
INT 21\AH=4Eh 函数将返回的数据留在 DTA 区域。默认 DTA 地址位于程序的 PSP (A.07-1) 中偏移量为 0080h 的位置,但可以通过 INT 21\AH=1Ah 函数 (8.02-16) 更改。INT 21\AH=2Fh 函数 (8.02-16) 会报告指向实际 DTA 位置的指针。返回的数据在 DTA 区域中的格式显示在表 A.09-1 的 F4E 列中。
准备:AX = 4E00h CH = 00h CL – 文件的属性掩码 (A.09-2) DS:DX – 指向包含要搜索的文件名称的字符串的指针。名称前面可以带路径。文件名可以使用通配符进行匹配。字符串必须以 00h 字节结尾。
返回:发生错误时,CF 标志被置位,AL 返回错误代码 (A.06-1)。CF 标志清除表明成功终止,此时将在 DTA 区域 (A.09-1) 返回第一个找到的文件的相关数据。
注意 1:文件属性掩码 (A.09-2) 中的位 0 和 5 被忽略。文件属性掩码中位 1、2 和 4 的 TRUE 状态不会排除找到没有对应属性的文件。位 3 (卷标) 的 TRUE 状态会排除找到文件。
注意 2:INT 21\AH=11h 函数 (8.02-11) 也能搜索当前目录中请求的文件。
准备:AH = 4Fh DTA 区域 (A.09-1) 中包含之前搜索过程留下的数据
返回:发生错误时,CF 标志被置位,AL 返回错误代码 (A.06-1)。CF 标志清除表明成功终止,此时将在 DTA 区域 (A.09-1) 返回下一个找到的文件的相关数据。
注意 1:为了继续搜索,INT 21\AH=4Fh 函数会使用之前 INT 21\AH=4Eh 或 INT 21\AH=4Fh 调用返回并在 DTA 区域 (8.02-16) 中存储的数据。在搜索完成之前,必须避免重命名、删除和移动文件操作,这些操作会更改目录条目,从而可能使 DTA 区域中留下的数据失效。
准备:AH = 52h
返回:ES:BX – 指向 DOS 的 "List-of-Lists" 的指针 (A.01-2)
注意 1:ES 寄存器中返回的段地址指向由 DOS 加载程序 IO.SYS 安排的数据块。
注意 2:如果当前程序不是在真实 DOS 环境中执行,而是在模拟的 DOS 环境中执行,则 INT 21\AH=52h 函数可能会返回一个明显无效的 ES:BX 地址,例如 0000:0000h 或 FFFF:FFFFh。
准备:AH = 54h
返回:AL = 00h – 验证标志处于关闭状态,= 01h – 验证标志处于打开状态
注意 1:如果验证标志处于打开状态,则每次磁盘写入操作后都会进行验证过程 (详细信息请参见文章 3.33)。验证标志的默认状态为关闭。
注意 2:INT 21\AH=2Eh 函数可以更改验证标志的状态。它以相同的形式从 AL 寄存器接收请求的验证标志状态。
INT 21\AH=55h 函数会安排一个新的 PSP (A.07-1),它派生自调用程序的实际 PSP。新 PSP 中的父段字段填充了调用程序 PSP 的段地址。INT 22、INT 23 和 INT 24 处理程序的指针被写入新 PSP 中的中断处理程序字段。继承的句柄的 JFT 表字段填充了复制的相应 SFT 条目的编号 (A.01-4),并且这些 SFT 条目中的引用计数增加了 1。安排的新的 PSP 可用于执行 *.COM 程序。
准备:AH = 55h DX – 新 PSP 的段地址 SI – 用于 PSP 中偏移量为 02h 的内存大小字段的值。
返回:AL 的内容可能会改变。
注意 1:新 PSP 的内存段必须由 INT 21\AH=48h 函数 (8.02-50) 分配。要执行的 *.COM 文件应从偏移量为 0100h 的位置开始写入此段。之后,应进行控制转移过程,该过程包括通过 INT 21\AH=50h 重新定义当前进程标识符 (8.02-73 的注意 1) 以及对分配的段中偏移量为 0100h 的位置执行 CALL FAR 命令。
更正目录条目可以重命名文件和子目录。将文件从一个目录移动到同一个逻辑磁盘上的另一个目录,也可以通过移动目录条目来实现。由于这并不涉及文件复制,因此移动目录条目会快得多。
准备:AH = 56h DS:DX – 指向包含现有对象 (文件或目录) 名称的字符串的指针 (注意 4)。名称前面可以带路径。字符串必须以 00h 字节结尾。ES:DI – 指向包含新名称 (注意 4) 或其他路径的字符串的指针。字符串必须以 00h 字节结尾。
返回:发生错误时,CF 标志被置位,AL 返回错误代码 (A.06-1)。CF 标志的清除状态表示成功终止。
注意 1:如果 DS:DX 指向的名称属于现有文件,而 ES:DI 指向的名称属于同一个逻辑磁盘上的现有目录,则对应于指定文件的条目将被移动到目标目录中。
注 2:如果 ES:DI 指向的名称不属于任何现有对象,而 DS:DX 指向的名称属于一个现有对象 - 关闭的文件或目录,则将重命名该现有对象。不允许重命名打开的文件。
注 3:INT 21\AH=56h 函数不会将 "A" 属性分配给已重命名或移动的文件。
注 4:名称中的通配符是不允许的,除非 INT 21\AH=56h 函数通过服务器调用 INT 21\AX=5D00h (8.02-68) 调用。除了通配符 (2.01-03) 之外,服务器调用还从 CL 寄存器接受一个属性掩码 (A.09-2),并通过错误代码 AL = 12h (= 没有更多匹配的文件) 来标记文件组的成功重命名 (或移动)。
准备:AX = 5700h BX - 文件的句柄 (8.02-33)
返回:发生错误时,CF 标志被设置,AL 返回错误代码 (A.06-1)。CF 标志的清除状态表示成功终止,然后 CX - 文件最后修改的时间:位 15-11 - 小时,从 00 到 23;位 10-5 - 分钟;位 4-0 - 秒。DX - 文件最后修改的日期:位 15-9 - 年,从 1980 年开始计数;位 8-5 - 月;位 4-0 - 日。
注 1:文件最后修改的日期和时间可以通过 INT 21\AX=5701h 函数设置:它接受来自 CX 寄存器的以相同形式的时间和来自 DX 寄存器的日期。
注 2:文件创建的日期和时间可以通过 INT 21\AX=5706h 函数读取,并通过 INT 21\AX=5707h 函数设置。这两个函数都使用 SI 寄存器来存储以 0.01 秒为单位的时间代码。但是,文件创建的日期和时间不一定在 DOS 下注册。
注 3:最后访问文件的日期可以通过 INT 21\AX=5704h 函数读取,并通过 INT 21\AX=5705h 函数设置(后者需要指定 CX=0000h)。但是,最后访问日期的注册可能会被 ACCDATE 命令 (4.01) 禁止。
准备:AX = 5800h
返回:发生错误时,CF 标志被设置,AL 返回错误代码 (A.06-1)。CF 标志的清除状态表示成功终止,然后 AX - 当前策略代码:位 7 和 6:= 00 - 使用常规内存;= 01 - 使用上部内存;= 10 - 使用常规内存,只有在上部内存不可用时使用;位 1 和 0:= 00 - 分配第一个合适的空间;= 01 - 分配最合适的空间;= 10 - 分配最后一个合适的空间。位 15-8 和 5-2 必须清零。
注 1:INT 21\AX=5801h 函数在 BX 寄存器中接受相同的策略代码,并允许设置它。
注 2:在每个已更改策略设置的程序终止之前,必须恢复以前的内存分配策略。
注 3:适当的内存分配策略是必要的,但对于上部内存的使用来说还不够:除了这一点,CONFIG.SYS 文件中还必须存在命令 DOS=UMB (4.08)。
准备:AH = 59h BX = 0000h
返回:CL、DX、SI、BP 和 DS 寄存器的内容不会被保留;BH - 错误类别 (A.06-2);BL - 建议的操作 (A.06-3);CH - 可能的错误位置 (A.06-4);AX - 错误代码 (A.06-1);如果 AX=0022h,则 ES:DI - 指向介质标识符 (A.06-1 的注 2)。
注 1:错误信息是从 DOS 的可交换区域 (A.01-3) 中读取的。
注 2:错误信息由 INT 21\AX=5D0Ah 函数写入 DOS 的可交换区域;它在 DS:DX 寄存器中接受指向参数列表的指针 (A.07-4),并从该列表中与寄存器 AX、BX、CX、DI、DX、ES 相对应的字获取数据。
准备:AH = 5Ah CX - 文件的属性 (A.09-2) DS:DX - 指向包含路径的字符串的指针,以反斜杠结尾。在反斜杠之后,必须跟随 13 个字节 00h:这是一个用于自动生成的自动生成的文件名的空间。
返回:发生错误时,CF 标志被设置,AL 返回错误代码 (A.06-1)。CF 标志的清除状态表示成功终止,然后 AX - 创建的临时文件的句柄 (8.02-33);DS:DX - 指向包含路径和附加文件名的字符串的指针。
注 1:创建的文件会自动获得一个唯一的名称,排除名称冲突。
注 2:根目录的容量是有限的。如果磁盘的根目录已满,则无法在该目录中创建文件。
注 3:在请求创建该临时文件的程序终止之前,必须关闭并删除每个临时文件。
准备:AH = 5Bh CX - 文件的属性 (A.09-2) DS:DX - 指向包含新文件名(字符串)的指针。名称可以由路径开头。字符串必须以字节 00h 结尾。
返回:发生错误时,CF 标志被设置,AL 返回错误代码 (A.06-1)。CF 标志的清除状态表示成功终止,然后 AX - 创建的新文件的句柄 (8.02-33)。
注 1:如果指定目录中已经存在同名文件,则 INT 21\AH=5Bh 函数无法创建新文件。
注 2:根目录的容量是有限的。如果磁盘的根目录已满,则无法在该目录中创建文件。
注 3:INT 21\AH=3Ch 执行相同的操作并接受相同的规范(除了 AH),但如果相同目录中存在同名文件,则不会返回错误。此同名文件将被简单地截断为零长度,并且指向其第一个簇的指针将丢失。因此,恢复截断文件的步骤比通过函数 INT 21\AH=13h (8.02-13) 或 INT 21\AH=41h (8.02-37) 偶尔执行普通删除后的恢复步骤复杂得多。
INT 21\AX=5D00h 函数提供了一个模板,使能够调用 INT 21 处理程序的任何其他函数,并以单独进程的形式执行该函数,以便进行选择性和重复执行。特别是,INT 21\AH=3Dh 函数的服务器调用使能够为目标文件指定属性掩码。除此之外,INT 21\AH=56h 和 INT 21\AH=41h 函数的服务器调用使能够重命名和删除通过带有通配符 (2.01-03) 的文件掩码指定的文件。
准备:AX = 5D00h DS:DX - 指向数据块的指针 (A.07-4),指定所有应为执行请求的函数准备好的寄存器的状态。
返回: - 应由请求的函数返回。
注 1:不会检查数据块中初始数据的有效性。如果数据块为 AH 寄存器指定了请求函数的无效编号,则计算机可能会挂起。
注 2:INT 21 调用所需的文件名必须使用 INT 21\AH=60h 函数 (8.02-72) 以规范形式准备好完整的路径。
INT 21\AH=5D01h 函数关闭调用进程打开的文件,更新所有相关的目录条目,并将磁盘缓冲区的內容写入磁盘。如果有通过网络访问的打开文件,则会自动调用网络服务函数 INT 2F\AX=1107h。
准备:AX = 5D01h DS:DX - 指向数据块的指针 (A.07-4),在偏移量 12h 处指定虚拟机标识符,在偏移量 14h 处指定进程标识符。数据块中寄存器数据字段的內容被忽略。
返回:发生错误时,CF 标志被设置,AX 返回错误代码 (A.06-1)。CF 标志的清除状态表示成功终止。
DOS 函数存储调用者的状态信息:这可能在以后需要,用于同一进程调用的这些或其他 DOS 函数。但是,当前进程可能会被其他进程中断 - 一个调用的 TSR 程序或中断处理程序。由该其他进程调用的 DOS 函数会存储其他状态信息,并破坏与被中断进程相关的数据。损坏的数据会阻止被中断进程的正确恢复。为了避免此类冲突,相关数据应被保存,并在以后恢复。因此,MS-DOS 将相关数据存储在 SDA - 可交换数据区域 (A.01-3) 中。INT 21\AX=5D06h 函数返回 SDA 区域的地址和该数据块的大小,该数据块应在特定情况下保存。
准备:AX = 5D06h
返回:发生错误时,CF 标志位被置位,AX 返回错误代码(A.06-1)。CF 标志位清零表示成功终止,此时 DS:SI 指向 SDA 区域的起始位置(A.01-3),CX 表示整个 SDA 区域的大小(以字节为单位),包括状态数据和 DOS 的堆栈。为了能够正确恢复被中断的 DOS 函数,必须保存整个 SDA 区域。DX 表示 SDA 区域中状态数据部分的大小(以字节为单位),当被中断的进程不是 DOS 函数时,应该保存此部分数据。
注释 1:如果中断进程不调用 DOS 函数,则无需保存 SDA 的数据。
注释 2:INT 21\AX=5D06h 也是一个 DOS 函数,有可能在中断发生后损坏 SDA 区域中的数据。因此,应该在驱动程序或驻留程序启动之前调用 INT 21\AX=5D06h 函数。返回的信息应保存并保留,以便将来使用。
8.02-71 INT 21\AX=5F08h - 隐藏逻辑磁盘
[edit | edit source]准备:AX = 5F08h DL - 逻辑磁盘号(参见 8.02-10 的注释 1)
返回:发生错误时,CF 标志被设置,AX 返回错误代码 (A.06-1)。CF 标志的清除状态表示成功终止。
注释 1:INT 21\AX=5F08h 函数会检查 DOS 内部表中的磁盘参数。如果发现磁盘参数无效,INT 21\AX=5F08h 函数将失败。
注释 2:INT 21\AX=5F07h 函数接受相同的规范(除了 AX),但执行相反的操作:将隐藏的磁盘变成有效的磁盘。
8.02-72 INT 21\AH=60h - 将文件名或路径转换为规范形式
[edit | edit source]INT 21\AH=60h 函数的作用与文章 3.29 中描述的 TRUENAME 命令的作用相同。将文件名和路径转换为规范形式对于多个 DOS 函数来说是必要的,并且可以避免错误,否则可能会导致不良后果。
准备:AH = 60h DS:SI - 指向包含名称的字符串的指针,该名称前面可能带有一个路径。字符串的最大长度为 64 字节。字符串必须以 00h 字节结尾。ES:DI - 指向用于转换后的名称和路径的 128 字节缓冲区的指针。
返回:发生错误时,CF 标志位被置位,缓冲区内容指针被保留,AX 寄存器提示可能的错误原因:AX = 0002h - 路径的某些组成部分无效或缺失 = 0003h - 磁盘的字母名称组合错误或无效。CF 标志位清零表示成功终止,此时 ES:DI 指向包含转换后的规范的缓冲区,AX 内容可能会丢失。
注释 1:不会检查指定名称和路径的实际存在性。
注释 2:INT 21\AH=60h 函数不能应用于网络路径。
8.02-73 INT 21\AH=62h - 获取当前 PSP 地址
[edit | edit source]DOS 将当前 PSP 地址视为当前进程的标识符。将当前进程标识符替换为另一个标识符是多任务执行控制中的关键操作。标识符替换意味着使用 INT 21\AH=62h 函数从 SDA 区域(A.01-3)读取当前标识符,保存当前标识符,然后将新的标识符写入 SDA 区域。完成其工作后,程序必须在将控制权交回之前恢复以前的进程标识符。还有一些其他原因需要调用 INT 21\AH=62h 函数来确定当前 PSP 地址(9.07-02 中有一个示例)。
准备:AH = 62h
返回:BX - 当前进程的 PSP 段地址(A.07-1)。
注释 1:可以使用 INT 21\AH=50h 将新的进程标识符写入 SDA 区域;后者从 BX 寄存器接收准备好的新标识符。除了 BX 和 AH=50h 之外,不需要其他数据。
8.02-74 INT 21\AX=6501h - 国家信息
[edit | edit source]准备:AX = 6501h BX - 十六进制代码页号,或 BX=FFFFh 用于请求当前代码页。CX - 准备好的数据缓冲区的大小,不少于 29h 字节 DX - 国家标识符,或 DX=FFFFh 用于请求当前国家 ES:DI - 指向准备好的数据缓冲区的指针
返回:发生错误时,CF 标志位被置位,AX 返回错误代码(A.06-1)。CF 标志位清零表示成功终止,此时 ES:DI 指向填充了数据的缓冲区(A.02-4),CX 表示缓冲区填充部分的大小(以字节为单位)。
注释 1:INT 21\AX=6502h、6504h、6505h、6506h 函数使用相同的规范(除了 AX),但在 ES:DI 缓冲区中仅返回偏移量为 01h 的一个 4 字节地址。
- INT 21\AX=6502h 返回指向大写字母表指针,该表以其大小(1 个字)开头,后面跟着 80h 到 FFh 的字符的大写等价字符(如果有的话)。
- INT 21\AX=6504h 返回指向文件名大写字母表指针,该表的结构相同,但仅应用于文件名。
- INT 21\AX=6505h 返回指向文件名限制表的指针(A.02-5)。
- INT 21\AX=6506h 返回指向排序顺序表的指针,该表以其大小(1 个字)开头,后面跟着 256 字节,定义了 00h 到 FFh 字符的排序顺序。
注释 2:有关当前未安装的其他国家和代码表的的信息不可用,除非安装了 NLSFUNC.EXE 驻留程序 (5.02-03)。
注释 3:MS-DOS7 中的国家信息可以使用 INT 21\AX=7002h 函数设置。该函数在 DS:SI 中接收指向数据表的指针(A.02-4),在 CX 中接收该表的大小(通常为 0026h 字节)。如果返回时 CF 清零,则 CX 表示实际设置的数据的大小。CF 标志位置位表示错误:AX = 7000h 表示不支持该函数;其他错误代码对应于表 A.06-1。
8.02-75 INT 21\AX=6521h - 国家相关的字符串大写转换
[edit | edit source]准备:AX = 6521h CX - 要大写转换的字符串的长度 DS:DX - 指向要大写转换的字符串的指针
返回:发生错误时,CF 标志位被置位,AX 返回错误代码(A.06-1)。CF 标志位清零表示成功,提交的字符串已转换为大写。
注释 1:INT 21\AX=6522h 函数执行相同的操作,但会忽略 CX,并要求字符串结尾用 00h 字节标记。
注释 2:INT 21\AX=6520h 函数用于将单个字符转换为大写,该字符在 DL 中接收和返回。CX 和 DS 内容被忽略。
8.02-76 INT 21\AH=67h - 设置句柄表的大小
[edit | edit source]默认情况下,不能同时保留超过 20 个句柄,因为原始 JFT(A.07-1 中偏移量为 18h)的大小限制为 20 字节。INT 21\AH=67h 函数会在 PSP 外部创建一个新的 JFT 表,从而消除了由原始 JFT 长度有限造成的默认限制。
准备:AH = 67h BX - 当前进程的新 JFT 表中的句柄数量
返回:发生错误时,CF 标志被设置,AX 返回错误代码 (A.06-1)。CF 标志的清除状态表示成功终止。
注释 1:如果当前 JFT 位于 PSP 内部,并且 BX 中的新大小不超过 20 字节,则不会执行任何操作。
注释 2:如果当前 JFT 位于 PSP 外部,并且不包含超过 20 个活动句柄,并且 BX 中的新 JFT 大小不超过 20 字节,则 JFT 将被复制回 PSP。
注释 3:如果请求减小 JFT 大小,并且活动句柄无法容纳在此减小的大小内,则 INT 21\AH=67h 函数将失败,并返回错误代码 0004h(= 打开文件过多)。
注释 4:同时打开的文件数量不仅受 JFT 表限制,还受 SFT 表(A.01-4)限制。后者的长度由配置文件 CONFIG.SYS 中的命令 FILES (4.12) 定义。
注释 5:无论当前 JFT 的大小和位置如何,子进程都无法从其父进程继承超过 20 个活动句柄。
8.02-77 INT 21\AX=6900h - 获取卷标和 FAT 类型
[edit | edit source]INT 21\AX=440Dh\CX=4866h 和 INT 21\AX=6900h 函数都返回包含磁盘卷规格的相同数据块 A.04-1,只是后者在访问失败的情况下不会调用关键错误处理程序 INT 24 (8.02-84)。所有错误都通过返回的 AX 中的错误代码报告。
准备:AX = 6900h BH = 00h BL - 逻辑磁盘号(参见 8.02-17 的注释 1) DS:DX - 指向 19h 字节长的数据块缓冲区的指针
返回时:如果出现错误,则设置 CF 标志,AX 返回错误代码 (A.06-1)。CF 标志清除表示成功终止,然后 DS:DX – 指向包含已写入数据块的缓冲区的指针 (A.04-1) AH 内容可能会被更改。
注意 1:返回数据块中偏移量 02h 处开始的数据是从扩展 BPB 块 (A.03-4) 中偏移量 27h–3Dh 处的字节复制过来的。
注意 2:如果在请求的磁盘中找不到扩展 BPB,则会报告错误代码 0005h。
注意 3:INT 21\AX=6900h 函数不能应用于网络驱动器。此类调用将返回错误代码 0001h。
注意 4:INT 21\AX=6901h 函数执行相反的操作:它接受 DS:DX 指向的数据块 (A.04-1),并将磁盘的卷数据从该块复制到该磁盘的扩展 BPB 中,该磁盘由 BX 寄存器中的数字类似地指定。
8.02-78 INT 21\AX=6C00h – 扩展获取句柄函数
[edit | edit source]可以使用 INT 21\AH=3Dh (8.02-33) 和 INT 21\AX=6C00h 函数获得访问对象的句柄,但后者提供了扩展功能来定义句柄的属性和规定的操作。
准备:AX = 6C00h BH – 属性标志:位 4 – 允许文件大小超过 2GB(仅限 FAT-32)位 5 – 返回错误而不是调用 INT 24h 位 6 – 立即写入磁盘,绕过缓存缓冲区 BL – 访问和共享条件 (A.09-4) CX – 文件的属性 (A.09-2),如果要创建文件,则 DH = 00h DL – 规定的操作代码:= 01h – 打开现有文件,如果不存在则失败;= 10h – 打开新文件,如果存在同名文件则失败;= 11h – 打开文件;如果不存在则新建;= 12h – 打开新文件;如果存在同名文件,则删除。DS:SI – 指向包含文件名字符串的指针,该字符串前面可以选择性地加上路径。文件名中不允许使用通配符。该字符串必须以字节 00h 结尾。
返回时:如果出现错误,则设置 CF 标志,AX 返回错误代码 (A.06-1)。CF 标志清除表示成功终止,然后 AX – 返回打开文件的句柄 CX – 状态代码:= 0001h – 文件已打开;= 0002h – 文件已创建;= 0003h – 文件已替换。
注意 1:规定的操作 DL = 11h 在远程磁盘上不受支持。
注意 2:对远程磁盘的操作不会在 CX 中返回状态代码。
注意 3:如果新建文件,则 BH 和 BL 的内容将复制到新的 SFT 条目 (A.01-4) 中。
注意 4:打开文件时,其访问指针将设置为文件的开头。
注意 5:打开文件的可能性与它的属性无关。
8.02-79 INT 21\AX=7302h – 扩展 DPB 的复制
[edit | edit source]INT 21\AX=7302h 函数将磁盘参数块 (DPB) 复制到准备好的缓冲区中。请求的 DPB (A.03-1) 可以属于使用 FAT-12、FAT-16 或 FAT-32 文件系统格式化的磁盘。
准备:AX = 7302h DL – 逻辑磁盘号(8.02-17 的注意 1)CX – 准备好的缓冲区的长度,不小于 3Dh 字节 ES:DI – 指向准备好的 DPB 缓冲区的指针
返回时:如果出现错误,则设置 CF 标志,AX 返回错误代码 (A.06-1)。CF 标志清除表示成功,DPB 表已复制(注意 2)。
注意 1:与类似函数 INT 21\AH=1Fh 和 INT 21\AH=32h (8.02-24) 不同,INT 21\AX=7302h 函数在以前的 DOS 版本中不可用,如果 PC 的 BIOS 不支持 INT 13 扩展 (8.01-55),则会失败。
注意 2:返回数据块中偏移量 00h 处的值是它的长度;DPB (A.03-1) 的副本从偏移量 DI+02 开始。
注意 3:返回的 DPB 副本中偏移量 13h 处用于驱动程序头地址的位置将填充为 FFFFh。
注意 4:INT 21\AX=7302h 函数尝试读取请求磁盘上的 BPB 以更新 DPB。如果访问失败,则会调用 INT 24 处理程序。
8.02-80 INT 21\AX=7303h – 获取可用空间表
[edit | edit source]INT 21\AX=7303h 函数报告使用 FAT-12、FAT-16 或 FAT-32 文件系统格式化的磁盘上的可用空间。返回的数据块 (A.13-7) 将复制到准备好的缓冲区中。与 INT 21\AH=36h 函数 (8.02-30) 返回的值不同,数据块 A.13-7 中的值不受限于 2048 Mb。
准备:AX = 7303h CX – 准备好的缓冲区的长度,不小于 34h 字节 DS:DX – 指向字符串的指针,定义请求的磁盘(注意 2)ES:DI – 指向数据块缓冲区的指针;此缓冲区中偏移量 02h 处的值事先必须填充为 0000h。
返回时:如果出现错误,则设置 CF 标志,AX 返回错误代码 (A.06-1)。CF 标志清除表示成功终止,然后 ES:DI – 指向填充有数据块 (A.13-7) 的缓冲区的指针,AL – 返回数据块的大小。
注意 1:与类似函数 INT 21\AH=36h 不同,INT 21\AX=7302h 函数在以前的 DOS 版本中不可用,如果 PC 的 BIOS 不支持 INT 13 扩展 (8.01-55),则会失败。
注意 2:准备好的字符串必须定义请求的磁盘,就像它在 CDS 表 (A.03-3) 中定义的那样:例如,本地磁盘为 C:\,通过网络访问的磁盘为 \\SERVER\Share。准备好的字符串必须以字节 00h 结尾。
8.02-81 INT 21\AX=7305h – 扩展读/写操作
[edit | edit source]INT 21\AX=7305h 函数提供了 5 个子函数,用于在使用 FAT-12、FAT-16 或 FAT-32 文件系统格式化的逻辑磁盘内执行读写操作。与 INT 25 和 INT 26 处理程序 (8.02-85) 类似,INT 21\AX=7305h 的子函数会忽略文件结构,并通过扇区号进行寻址,每个逻辑磁盘从其开头分别计数。
准备:AX = 7305h DL – 逻辑磁盘号(8.02-17 的注意 1)DS:BX – 指向磁盘地址包的指针(注意 2)SI – 子函数:= 0000h – 读取 = 0001h – 写入任何非特定数据 = 2001h – 写入 FAT 数据 = 4001h – 写入目录数据 = 6001h – 写入文件数据
返回:发生错误时,CF 标志被设置,AX 返回错误代码 (A.06-1)。CF 标志的清除状态表示成功终止。
注意 1:与类似函数 INT 25 和 INT 26 (8.02-85) 不同,INT 21\AX=7302h 函数在以前的 DOS 版本中不可用,如果 PC 的 BIOS 不支持 INT 13 扩展 (8.01-55),则会失败。
注意 2:磁盘地址包长度为 10 个字节,包含在偏移量处:00h – 双字:操作开始扇区号;04h – 字:要读取或写入的扇区数;06h – 双字:包含数据或用于数据的缓冲区的地址。
8.02-82 INT 22 – 控制返回点的地址
[edit | edit source]中断表中 INT 22 单元格中的地址不是指向处理程序,而是指向父进程内部的返回点。当前程序终止时,控制将仅转移到该返回点的 INT 22 地址。大多数情况下,INT 22 指向启动当前程序的 INT 21\AH=4Bh 函数 (8.02-53) 调用之后的命令。
不应直接调用中断 INT 22,因为父进程无法正常执行,而无需恢复许多必要的条件,包括堆栈状态和中断表中 INT 22 – INT 24 单元格中的地址。所有必要的准备工作由程序终止处理程序 INT 20 (8.02-01) 和 INT 21\AH=4Ch (8.02-55) 执行。这些处理程序从中断表中读取 INT 22 地址,临时保存它,将父进程的控制返回点地址从当前程序的 PSP (A.07-1) 中的偏移量 0Ah 复制到相同的 INT 22 单元格中,然后执行 JMP FAR 命令 (7.03-39) 转到临时保存的地址。
8.02-83 INT 23 – CTRL-C/CTRL-Break 处理程序
[edit | edit source]每次键盘控制器报告 CTRL-C/CTRL-Break 按键时,INT 09 处理程序都会调用 INT 1B,后者会将 BIOS 数据区中的标志 (表 A.02-3 中的偏移量 71h) 设置为 TRUE 状态。当前程序调用的某些 MS-DOS 函数会检查此标志的状态。如果发现标志设置为 TRUE 状态,则会调用 INT 23 处理程序,该处理程序会暂停当前程序的执行。
INT 23 处理程序的代码是在假设其调用者是 DOS 函数的情况下编写的。因此,应用程序程序不允许调用 INT 23,除非通过 INT 1B (8.01-95) 间接调用。
后续事件部分取决于环境,但在大多数情况下,用户必须选择:继续或终止暂停程序的执行。响应中可能的用户操作在第 1.03 条中描述。如果选择终止选项,则 INT 23 处理程序将关闭暂停程序打开的所有文件,释放其内存,定义为零错误级别,将 CF 标志设置为 CY 状态,然后将控制权转移到父进程 - 那个调用了当前程序的进程。如果用户选择继续,则所有寄存器和标志的状态将被恢复,并将控制权转移到调用 INT 23 处理程序的 DOS 函数。完成其任务后,此 DOS 函数将控制权返回给其调用方 - 当前程序。
8.02-84 INT 24 - 严重错误处理程序
[edit | edit source]当对 DOS 函数的请求返回不适当的响应时,这些 DOS 函数将调用 INT 24 - 严重错误处理程序。INT 24 处理程序分析每个错误的信息,但最常见的是不依赖于自身,而是向用户提出其著名的“中止、重试、失败?”问题。在得到用户的决定后,INT 24 处理程序将其传递给执行调用 INT 24 的 DOS 函数。
INT 24 处理程序的代码是在其调用者为 DOS 函数的假设下编写的。因此,不允许应用程序程序直接调用 INT 24。
在返回时,所有寄存器(除 AL 外)的状态从堆栈中恢复,AL 返回操作码:AL = 00h - 返回调用程序并返回错误代码(失败);= 01h - 再次尝试相同的请求(重试);= 02h - 终止调用程序的执行(中止);= 03h - 承认系统故障并停止 CPU。
注意 1:通过设置 SDA(A.01-3)偏移量 2Ah 处标志的状态,可以确保自动回答失败和不停地继续执行。特别是,当使用未公开的参数 /f(6.04)启动命令解释器 COMMAND.COM 时,此标志被设置。
8.02-85 直接磁盘读取(INT 25)和写入(INT 26)
[edit | edit source]NT 25 和 INT 26 处理程序允许访问使用 FAT-12 和 FAT-16 文件系统格式化的逻辑磁盘。磁盘访问通过扇区号进行,每个逻辑磁盘从扇区号 00000000h 开始单独计数。数据缓冲区地址和特定扇区号在磁盘地址包中传输,在 8.02-81 的注释 2 中进行了描述。
准备:AL - 逻辑磁盘号(8.02-10 的注释 1)CX = FFFFh(注释 3)DS:BX - 指向磁盘地址包的指针(8.02-81 的注释 2)。
在返回时:BX、CX、DX、DI、SI 寄存器的状态不会保留。发生错误时,CF 标志被设置,AL 返回错误代码(A.06-1),AH 根据表 A.06-5 返回错误状态。CF 标志的清除状态表示成功终止。
注意 1:INT 25 和 INT 26 处理程序在堆栈顶部留下一个标志状态字。调用程序要么从堆栈中弹出此字,要么在 SP 寄存器中恢复以前的值。
注意 2:INT 25 和 INT 26 处理程序能够提供对具有 32 位数据传输的逻辑磁盘的访问,由驱动程序属性字(A.05-2)中的位 1 的 TRUE 状态标记。
注意 3:应用于没有簇结构的小型逻辑磁盘(32 Mb 或更小,表 A.13-6 中的 ID 04h),INT 25 和 INT 26 处理程序使用不同的规范形式:CX - 要读取或写入的扇区数 DX - 起始扇区的数量 DS:BX - 指向包含数据的缓冲区或用于数据的缓冲区。
注意 4:INT 25 和 INT 26 处理程序不能应用于使用 FAT-32 文件系统格式化的逻辑磁盘,应使用 INT 21\AX=7305h 处理程序(8.02-81)。
8.02-86 INT 27 - 终止执行,留下常驻模块
[edit | edit source]准备:CS - 当前程序的 PSP 的段地址 DX - 常驻模块的大小,从 60h 到 FFF0h 字节,从当前程序的 PSP 的开始处计数
注意 1:INT 27 处理程序将控制权转移到父进程 - 那个启动了当前程序的进程。INT 27 处理程序为控制权转移做必要的准备:释放主程序的内存(除了其常驻模块),恢复中断表中的指针。但 INT 27 处理程序不会关闭打开的文件:必须由当前程序事先自行完成。
注意 2:INT 21\AH=31h 函数(8.02-23)具有相同的任务,但不会将常驻模块的大小限制在 64 kb,并且能够留下非零错误级别值。
8.02-87 INT 28 - DOS 空闲钩子,用于后台执行
[edit | edit source]当任何 DOS 的字符输入函数(INT 21\AH=01h–0Ch)正在等待来自键盘的输入时,INT 28 中断以定时器的滴答速度(每秒 18 次)被调用。在这样的等待间隔期间,DOS 实际上处于空闲状态。默认的 INT 28 处理程序是一个单独的 IRET 指令 (7.03-30),它只是将控制权返回给调用方。拦截 INT 28 允许在前景程序正在等待用户输入时激活后台程序或 TSR。拦截 INT 28 处理程序获得指向 DOS 堆栈顶部的 SS:SP 寄存器,并且必须在返回时恢复所有寄存器的状态。
注意 1:拦截 INT 28 的程序必须检查 InDOS 标志的状态(在 A.01-3 中的偏移量 01h 处)。该标志的地址必须事先通过调用 INT 21\AH=34h(8.02-28)函数找到,并且必须从程序初始化开始存储。在 INT 28 调用时,InDOS 标志的值通常为 01h;如果它具有更大的值,则禁止拦截程序对 DOS 函数的所有调用。
注意 2:当 InDOS 标志具有其正常值 01h 时,设计用于后台执行的程序可以调用 DOS 函数,但 INT 21\AH=01h–0Ch 函数除外,并且针对 CON 设备句柄的调用除外(通常这些是句柄 0000h–0002h)。
8.02-88 INT 29 - 不可重定向的控制台输出
[edit | edit source]当 STDOUT 输出被(或可能被)重定向到其他位置 - 到文件或设备(而不是显示 (CON) 设备)时,INT 29 处理程序用于在屏幕上显示消息。
准备:AL - 要显示的字符的 ASCII 代码 在返回时:BX 寄存器的内容可能会被更改。
注意 1:默认的 INT 29 处理程序通过 BIOS 的函数 INT 10\AH=0Eh(8.01-21)将字符代码发送到显示器。
注意 2:CON 设备驱动程序属性字 (A.05-2) 中的位 4 指示 CON 设备驱动程序是否支持 INT 29。
注意 3:可以通过 INT 21\AH=40h 函数(8.02-36)地址的 STDERR 通道 (句柄 0002h) 执行字符字符串的不可重定向显示。与 INT 29 不同,STDERR 通道始终受 CON 设备驱动程序支持。
8.02-89 INT 2E - 将命令传输到解释器
[edit | edit source]INT 2E 处理程序将命令行传输到命令解释器 COMMAND.COM 以供执行,但不会重新加载解释器的模块。命令行被传输到已加载的解释器常驻模块,该模块已启动了调用程序。
准备:DS:SI - 指向要执行的命令行的指针。命令行的格式必须与 PSP (A.07-1,偏移量 80h) 中的格式相同:第一个字节是行长,然后是命令行本身,以字节 0Dh 结束。长度计数不包括结束字节。
在返回时:AX - 错误代码 (A.06-1);所有寄存器的内容(除了 CS:IP)都可能被更改。
注意 1:命令解释器的常驻模块可能需要加载 COMMAND.COM 解释器的瞬态部分才能执行指定的命令。调用程序必须确保 DOS 能够为 COMMAND.COM 解释器的瞬态部分分配足够的内存。
注 2:COMMAND.COM 解释器在被 INT 2E 调用时,使用其原始环境,这可能与调用者的环境不同。因此,环境变量的所有更改(如果有)将无法被调用者访问。
注 3:INT 2E 不应被从批处理文件启动的程序调用。
当 DOS 开始执行应用程序程序时,指向 BIOS 和 DOS 中断处理程序的指针当然已经写入中断表中的单元格。应用程序程序不需要检查这些单元格中是否存在这些指针。对于那些由可选软件(驱动程序和 TSR 程序)加载的处理程序,情况并非如此。中断表中的相应单元格可能为空,应用程序程序必须检查这些单元格是否已填充有效的指针。
很久以前,当驱动程序数量不多时,每个驱动程序都使用中断表中的一个单元格。然后可以通过在地址点的某个附近存在特定签名来确认处理程序地址的有效性。这种确认方式可以应用于 EMM386.EXE 驱动程序的驻留模块(8.03-62 的注 1),其祖先自 1983 年以来就已为人所知。
随着越来越多的驱动程序出现,中断表中的空间不足开始导致冲突。此外,当地址的驻留模块未加载时,消除挂起的威胁也是可取的。为了解决这两个问题,多路中断 INT 2F 的想法被提了出来。每个参与的驱动程序都必须拦截 INT 2F 调用,从而形成一个拦截器链(A.07-5 中的详细信息)。INT 2F 的调用必须沿着这个链从一个处理程序传递到另一个处理程序,每个处理程序都会分析 AH 寄存器中的标识符。如果处理程序没有在 AH 中识别出自己的标识符,则它会保持 AX 不变,并让此调用沿着链继续“传播”。如果指定标识符没有被所有处理程序识别,则 INT 2F 的调用将到达链的最后一个环节——IRET 命令,最初由 DOS 设置。IRET 命令将控制权返回给调用程序,因此 AX 值将不变地返回。AX 内容的改变可以被认为是某个处理程序已经识别出自己标识符的证据;因此,所请求的驻留模块已加载。
当然,多路中断不仅适合识别。它能够在不冒在需要模块未加载时挂起的风险的情况下,访问可选驻留模块的主要功能。但是,跟踪很长的引用链需要时间,并且会使执行速度变慢。为了避免延迟,许多驱动程序通过 INT 2F 返回其入口点的地址。直接调用这些入口点会比通过多路中断调用驻留模块的特定功能快得多。例如,HIMEM.SYS 驱动程序 (5.04-01) 使用多路中断 INT 2F 来返回其入口点的地址 (8.03-23)。
INT 2F 使用的做法在一段时间内取得了有限的成功,但它无法消除由对不同驱动程序和驻留模块分配标识符不一致造成的冲突。为了避免此类冲突,提出了另一种想法——动态分配标识符:每个驻留模块应为自己分配第一个找到的可用标识符。这个想法由多路中断 INT 2D 实现(A.07-6 中的详细信息)。现在,驻留 DOS 软件由于多路中断 INT 2D 而摆脱了标识符冲突。
同时,许多具有已知标识符的驱动程序继续使用多路中断 INT 2F。此外,在以前的 DOS 版本中由驱动程序加载的几个驻留模块,现在与它们的 INT 2F 标识符一起集成到 DOS 内核中,以保持兼容性。测试是否存在具有 INT 2F 标识符 AH = 05h、08h 和 12h 的驻留模块毫无意义,这些标识符实际上现在是 DOS 函数。但是,这些集成函数在下面 8.03 部分中与可选加载软件的函数一起描述,因为否则将失去按序搜索它们的便利性。
准备:AX = 0501h BX – 要转换的错误代码 (A.06-1)
返回时:AX、DI、ES 寄存器的内容和标志的状态不保留。CF 标志的状态设置为表示 DOS 没有提交代码的消息。CF 标志的状态清除表示成功终止,然后 ES:DI – 指向只读消息的指针,以字节 00h 结尾;AL = 00h – 消息需要用磁盘的字母名称补充;= 01h – 返回的消息是完整的。
INT 2F\AX=0801h 函数将 DOS 的磁盘数据表 (DDT) 链附加一个准备好的 DDT 表,并在引用相同物理驱动器的其他表中修改磁盘描述标志。从那时起,添加的逻辑磁盘可以通过集成到 DOS 内核中的块设备驱动程序访问。
准备:AX = 0801h DS:DI – 指向准备好的 DDT 表的指针 (A.03-2)
返回时:AX、BX、SI、ES 寄存器的内容不保留。
注 1:INT 2F\AX=0801h 函数不应用于 IFS、远程和其他磁盘,这些磁盘无法由本机 DOS 块设备驱动程序提供服务。
注 2:可以通过 INT 2F\AX=0803h 函数获取 DDT 表的示例。
INT 2F\AX=0802h 函数执行与逻辑磁盘相关的请求,这些逻辑磁盘由有效的磁盘数据表 (A.07-5) 表示,并由集成到 DOS 内核中的块设备驱动程序控制。地址的磁盘号和请求的操作代码 (A.07-5) 都应在请求数据块 (A.06-4) 中指定。
准备:AX = 0802h ES:BX – 指向请求数据块的指针 (A.06)
返回时:ES:BX – 指向请求数据块的指针,已根据请求的操作更新 (A.05-3 – A.05-7)
注 1:INT 2F\AX=0802h 函数在堆栈顶部留下一个标志状态字。调用程序必须将此字从堆栈中弹出,或者恢复 SP 寄存器中的先前值。
注 2:可能的错误由返回的错误代码宣布,这些错误代码位于请求数据块中的偏移量 03h 和 04h 的字节中 (A.05-9)。在任何情况下都不会调用关键错误处理程序 (INT 26)。
准备:AX = 0803h
返回时:DS:DI – 指向第一个 DDT 表开头的指针 (A.03-2)
注 1:可以通过以下方式轻松跟踪 DDT 表的链:每个 DDT 表中的第一个双字都是指向下一个 DDT 表的指针 (A.03-2)。
准备:AX = 1202h 中断号应位于堆栈顶部
返回时:ES:BX – 指向中断处理程序地址的指针;AX 寄存器的内容可能被更改;堆栈的状态保持不变。
注 1:当 CPU 处于实模式时,INT 2F\AX=1202h 函数只将中断号乘以 4。
准备:AX = 1212h ES:DI – 指向 ASCIIZ 字符串的指针,以 00h 字节结尾。
返回时:CX – 字符串的长度,包括终止的 00h 字节。
注 1:INT 2F\AX=1225h 函数执行相同操作,但接受来自 DS:SI 寄存器对的指针。
准备:AX = 1213h 字符的 ASCII 码应位于堆栈顶部。
返回值:AL – 与该字符相同的 ASCII 大写代码。堆栈状态保持不变。
准备:AX = 1212h DS:SI – 第一个指针 ES:DI – 第二个指针
返回值:如果指针相等,则 ZF 标志位设置,CF 标志位清除;如果指针不同,则 ZF 标志位清除,CF 标志位设置。
INT 2F\AX=1216h 函数接收一个 SFT 条目的编号(A.01-4),并返回指向该 SFT 条目的指针,从而提供直接访问 SFT 的机会。
准备:AX = 1216h BX – 请求的 SFT 条目的编号(注意 2)
返回值:AX 值不被保存。CF 标志位的设置状态表示任务失败。CF 标志位的清除状态表示任务成功完成,然后:ES:DI – 指向请求的 SFT 条目的指针,BX – 该条目在特定 SFT 中的相对编号。
注意 1:最可能导致错误的原因是请求的 SFT 条目编号大于 SFT 条目的最大数量,该数量由 CONFIG.SYS 文件中 FILES 命令(4.12)指定。
注意 2:指向与特定句柄相关的 SFT 条目编号的指针由 INT 2F\AX=1220h 函数(8.03-11)返回。
准备:AX = 121Eh DS:SI – 指向第一个文件名的指针,以 00h 字节结尾;ES:DI – 指向第二个文件名的指针,以 00h 字节结尾。
返回值:如果文件名相同,则 ZF 标志位设置,如果文件名不同,则 ZF 标志位清除。
JFT 表(A.07-1 的注意 3)中填充了 SFT 条目的编号(A.01-4),定义了那些被打开以供访问的对象——通道或文件。对这些对象的访问是通过句柄进行的——对调用程序已知的数字引用。从句柄到相应 SFT 条目的路径从调用 INT 2F\AX=1220h 函数开始,该函数返回指向该相应 SFT 条目编号的指针。该编号是调用 INT 2F\AX=1216h 函数(8.03-09)的规范中的主要数据项,该函数返回相应 SFT 条目的地址。
准备:AX = 1220h BX – 一个活动的(已打开的)句柄
返回值:如果出错,则 CF 标志位设置,AX = 06h(– 无效句柄错误)。CF 标志位的清除状态表示任务成功完成,然后:ES:DI – JFT 中存储所需 SFT 条目编号的字节的地址。
注意 1:ES:DI 寄存器中地址指向的 JFT 字节的值为 FFh,表示指定句柄处于非活动(已关闭)状态。
INT 2F\AX=122Ch 函数能够跟踪整个设备驱动程序头链,因为每个头中的第一个双字是指向下一个头的指针。最后一个头以第一个字 FFFFh 标记。
准备:AX = 122Ch
返回值:BX:AX – 指向第二个驱动程序的头(第一个是 DOS 中的“列表列表”中的 NUL 设备驱动程序,A.01-2)。
准备:AX = 1500h BX = 0000h
返回值:AL = FFh – 成功完成的签名(注意 1);BX – CD/DVD 驱动器的数量;CX – 分配给第一个 CD/DVD 驱动器的驱动器编号(0002h = C:,0003h = D:,等等)。
注意 1:返回的初始值 AL = 00h 表示 CD/DVD 文件系统转换器(5.08-03 或 5.08-04)的驻留模块未加载,该模块必须执行 INT 2F\AX=1500h 函数。
注意 2:INT 2F\AX=1500h 函数与 GRAPHICS.COM 驱动程序的函数冲突,此外,当安装了 INTERLINK.EXE 网络驱动程序时,可能会返回第一个 CD/DVD 驱动程序的错误字母名称。
准备:AX = 1501h ES:BX – 指向缓冲区的指针(每个磁盘预期 5 个字节)
返回值:ES:BX – 指向已填充每个驱动器 5 字节块的缓冲区的指针。在每个块中,第一个字节——与特定驱动程序相关的磁盘子单元编号,接下来的双字——指向该驱动程序头的指针。缓冲区中数据的总长度取决于 INT 2F\AX=1500h 函数(8.03-13)返回的 CD/DVD 驱动器数量。
注意 1:除非 INT 2F\AX=150Bh 函数(8.03-17)预先确认所需的模块已加载,否则不应调用 INT 2F\AX=1501h 函数,该函数由 CD/DVD 文件系统转换器(5.08-03 或 5.08-04)的驻留模块执行。
注意 2:在 WINDOWS 操作系统下的“DOS 框”内调用时,INT 2F\AX=1501h 函数将返回 AX=0000h 和无效的头地址。
准备:AX = 1505h CX – CD/DVD 驱动器编号(0002h = C:,0003h = D:,等等)DX – 扇区索引(注意 2)ES:BX – 指向已准备好的 2048 字节缓冲区的指针。
返回值:如果出错,则 CF 标志位设置,AL – 错误代码:AL = 15h – 无效驱动器编号;= 21h – 驱动器未准备好或驱动器中没有介质。CF 标志位的清除状态表示任务成功完成,然后:AL – 卷标描述符类型:= 01h – 标准卷标描述符;= FFh – 最后一个卷标描述符;= 00h – 任何其他卷标描述符类型。ES:BX – 指向包含目录表的 2048 字节缓冲区的指针。
注意 1:除非 INT 2F\AX=150Bh 函数(8.03-17)预先确认所需的模块已加载,否则不应调用 INT 2F\AX=1505h 函数,该函数由 CD/DVD 文件系统转换器(5.08-03 或 5.08-04)的驻留模块执行。
注意 2:一张 CD/DVD 光盘可能有多个卷标描述符:扇区索引 0000h 对应第一个描述符,扇区索引 0001h 对应第二个描述符,等等。
准备:AX = 1508h – 读取 CD/DVD 扇区 = 1509h – 写入 CD/DVD 扇区(注意 3)CX – CD/DVD 驱动器编号(0002h = C:,0003h = D:,等等)DX – 要读取或写入的扇区数量 ES:BX – 指向缓冲区的指针(包含写入函数的数据)SI:DI – 起始扇区编号
返回值:如果出错,则 CF 标志位设置,AL – 错误代码:AL = 0Fh – 无效驱动器;= 15h – 驱动器繁忙或驱动器中没有介质。CF 标志位的清除状态表示任务成功完成,然后在读取操作后,ES:BX 缓冲区将填充读取的数据。
注意 1:除非 INT 2F\AX=150Bh 函数(8.03-17)预先确认所需的模块已加载,否则不应调用 INT 2F\AX=1508h–1509h 函数,该函数由 CD/DVD 文件系统转换器(5.08-03 或 5.08-04)的驻留模块执行。
注意 2:在 WINDOWS 操作系统下的“DOS 框”内调用时,INT 2F\AX=1508h–1509h 函数始终返回错误代码 AL=15h。
注意 3:早期版本的 CD/DVD 文件系统转换器程序(5.08-03 和 5.08-04)不支持写入操作。此外,写入函数需要 CD/DVD 驱动器的硬件支持。
准备:AX = 150Bh CX – CD/DVD 驱动器编号(0002h = C:,0003h = D:,等等)
返回时:BX = ADADh,– 一个签名,确认 CD/DVD 文件系统转换器 (5.08-03 或 5.08-04) 模块已加载并处于活动状态。AX = 0000h – 此零值表示 CD/DVD 文件系统转换器 (5.08-03 或 5.08-04) 无法控制请求的驱动器。
8.03-18 INT 2F\AX=150Dh – 获取 CD/DVD 驱动器的驱动器号
[edit | edit source]准备:AX = 150Dh ES:BX – 指向驱动器号缓冲区的指针 (每个驱动器 1 字节)
返回时:ES:BX – 指向已填充驱动器号的缓冲区的指针 (02h = C:,03h = D:,依此类推)。驱动器号列表以字节 00h 结束。
注意 1:除非 INT 2F\AX=150Bh 函数 (8.03-17) 事先确认所需模块已加载,否则不应调用 INT 2F\AX=150Dh 函数,该函数由 CD/DVD 文件系统转换器 (5.08-03 或 5.08-04) 的驻留模块执行。
8.03-19 INT 2F\AX=150Fh – 复制 CD/DVD 目录项
[edit | edit source]准备:AX = 150Fh CH = 00h – 直接复制“按原样”,不进行转换 = 01h – 复制并转换为规范形式 (A.09-6) CL – CD/DVD 驱动器号 (02h = C:,03h = D:,依此类推) ES:BX – 指向路径名的指针,以 00h 字节结尾 SI:DI – 指向缓冲区的指针,直接复制的最小值为 255 字节
返回时:如果发生错误,则设置 CF 标志,AX 返回错误代码 (A.06-1)。CF 标志的清除状态表示成功终止,然后 SI:DI – 指向已填充目录数据的缓冲区的指针 AX = 0000h – 如果磁盘为 High Sierra 格式,= 0001h – 如果磁盘为 ISO 9660 格式。
注意 1:除非 INT 2F\AX=150Bh 函数 (8.03-17) 事先确认所需模块已加载,否则不应调用 INT 2F\AX=150Fh 函数,该函数由 CD/DVD 文件系统转换器 (5.08-03 或 5.08-04) 的驻留模块执行。
8.03-20 INT 2F\AX=160Ah – Windows 操作系统环境测试
[edit | edit source]准备:AX = 160Ah
返回时:AX = 0000h,如果 Windows 操作系统响应此测试 BH:BL – Windows 操作系统的版本 CX – 安装类型 (0002h = 标准,0003h = 增强)
注意 1:AX 寄存器中返回值不为零并不表示调用程序不是在 Windows 操作系统或其“DOS 框”中执行的。原因是在 Windows 的设置中有一个名为“阻止 DOS 程序检测 Windows”的标志。当设置此标志时,Windows 操作系统不会响应 INT 2F\AX=160Ah 测试。
8.03-21 INT 2F\AX=1687h – 对 DPMI 服务器的试用请求
[edit | edit source]DPMI 服务器为应用程序提供扩展的 API 函数,这些函数旨在在 CPU 的 V86 模式下执行。通过对 DPMI 服务器的请求,可以激活 INT 31 处理程序,这使得可以安装新的保护模式中断处理程序,并向保护模式操作系统发送资源请求。用于 DOS 的 DPMI 服务器 (QDPMI.SYS、CWSDPMI.EXE 等) 现在并不流行,因为 Windows 操作系统提供自己的 DPMI 服务器,并且始终可用。从 Windows 的“DOS 框”发送的 DPMI 服务器的试用请求始终会收到积极的响应,即使 Windows 操作系统没有合法地显示自身 (8.03-20 的注释 1)。此外,对试用请求的积极响应是 CPU 的 V86 模式的充分证据。由于这些原因,INT 2F\AX=1687h 函数可能需要,尽管 MS-DOS7 不包含 DPMI 服务器,并且本书中没有描述 DPMI 函数的使用方法。
准备:AX = 1687h
返回时:AX = 0000h – 此零值表示 DPMI 服务器已加载;BX – 设置位 0 的状态表示支持 32 位程序;CL – CPU 类型 (02h – 80286,03h – 80386,04h – 80486,…);DH:DL – DPMI 服务器版本;SI – DPMI 服务器数据块的大小 (以 16 字节段为单位);ES:DI – INT 31 处理程序激活入口点的地址。
注意 1:DOS 的 DPMI 服务器环境与 Windows“DOS 框”之间的区别在于,后者无法访问 BIOS 定时器 (8.01-73) 和 VCPI 函数 (8.03-71 – 8.03-73)。
注意 2:在“Caldera Open DOS”操作系统中,DPMI 服务器已集成到 EMM386.EXE 驱动程序中。
8.03-22 INT 2F\AX=4300h – XMS 驱动程序的活动测试
[edit | edit source]准备:AX = 4300h
返回时:AL = 80h – 此值确认 XMS 驱动程序 HIMEM.SYS (5.04-01) 已加载并处于活动状态。任何其他返回的 AL 值表示 XMS 函数不可用。
8.03-23 INT 2F\AX=4310h – 获取 XMS 驱动程序的入口点
[edit | edit source]INT 2F\AX=4310h 函数返回 HIMEM.SYS (5.04-01) 驱动程序的入口点地址。表 A.12-3 中列出的各种 XMS 函数可以通过指向此入口点的 CALL FAR 命令 (7.03-08) 来调用。
准备:AX = 4310h
返回时:ES:BX – XMS 驱动程序入口点 (5.04-01) 的地址。
注意 1:除非 INT 2F\AX=4300h 函数 (8.03-22) 事先确认所需模块已加载,否则不应调用 INT 2F\AX=4310h 函数,该函数由 HIMEM.SYS 驱动程序 (5.04-01) 的驻留模块执行。
注意 2:对 XMS 函数的调用,包括 INT 2F\AX=4310h 和通过 CALL FAR 命令的调用,至少需要 256 字节的可用堆栈空间。
8.03-24 INT 2F\AX=4B52h – KEYRUS.COM 驱动程序的函数 (5.02-05)
[edit | edit source]准备:AX = 4B52h (= 'KR') BL – 子函数:= 00h – 安装检查;= 4Ch – 切换到美国键盘布局;= 90h – 切换到国家/地区 (俄语) 键盘布局
返回时:如果 KEYRUS.COM 驱动程序 (5.02-05) 已加载,则 AL = 82h – 签名,确认驱动程序处于活动状态;BH:BL – KEYRUS.COM 驱动程序的版本号;ES 值未保留。
8.03-25 INT 2F\AX=AD00h – DISPLAY.SYS 驱动程序的安装检查
[edit | edit source]准备:AX = AD00h
返回时:AL = FFh – 签名,确认 DISPLAY.SYS 驱动程序 (5.02-02) 已安装,并且其函数可用。BX 寄存器的内容可能会更改。
8.03-26 INT 2F\AX=AD01h–AD02h – 设置/获取活动代码页
[edit | edit source]INT 2F\AX=AD01h–AD02h 函数由 DISPLAY.SYS 驱动程序 (5.02-02) 的驻留模块执行。在发送对其中任何一个函数的调用之前,您必须使用 INT 2F\AX=AD00h 函数 (8.03-25) 检查所需驻留模块是否已安装。
准备:AX = AD01h – 将活动代码页替换为另一个代码页 = AD02h – 获取活动代码页的编号 (A.02-2) BX – 新代码页的十六进制编号 (仅限 AX = AD01h)
返回时:如果发生错误,则设置 CF 标志,AX 和 BX 的内容将不会保留。CF 标志的清除状态表示成功,然后在 AX=AD02h 调用之后,只有 BX – 当前代码页的十六进制编号。
8.03-27 INT 2F\AX=AD03h – 获取代码页信息
[edit | edit source]INT 2F\AX=AD03h 函数由 DISPLAY.SYS 驱动程序 (5.02-02) 的驻留模块执行。在发送此函数的调用之前,必须使用 INT 2F\AX=AD00h 函数 (8.03-25) 检查是否安装了所需的驻留模块。
准备:AX = AD03h ES:DI – 指向代码页信息的缓冲区的指针 CX – 缓冲区的大小(以字节为单位)(A.02-6)
返回:发生错误时设置 CF 标志。可能原因:准备好的缓冲区太小。CF 标志的清除状态表示成功终止,然后 ES:DI – 指向填充有数据块的缓冲区的指针 (A.02-6)。
准备:AX = AD80h
返回:AL = FFh – 签名,确认 KEYB.COM 驱动程序 (5.02-04) 已安装,其功能可用;BH:BL – KEYB.COM 驱动程序的版本号;ES:DI – 指向 KEYB.COM 驱动程序的数据块的指针;AH 寄存器的内容可能会改变。
INT 2F\AX=AD81h 函数由 KEYB.COM 驱动程序 (5.02-04) 的驻留模块执行。在发送此函数的调用之前,必须使用 INT 2F\AX=AD80h 函数 (8.03-28) 检查是否安装了所需的驻留模块。
准备:AX = AD81h BX – 提议的代码页的十六进制编号 (A.02-2)
返回:发生错误时设置 CF 标志,然后 AX = 0001h 值表示提议的代码页不可用。CF 标志的清除状态表示成功终止。
INT 2F\AX=AD82h–AD83h 函数由 KEYB.COM 驱动程序 (5.02-04) 的驻留模块执行。在发送这两个函数的任何一个的调用之前,必须使用 INT 2F\AX=AD80h 函数 (8.03-28) 检查是否安装了所需的驻留模块。
准备:AX = AD82h – 设置键盘的布局 = AD83h – 获取当前键盘的布局 BL – 子函数(仅限于 AX = AD82h 函数):= 00h – 切换到美国布局(就像可以通过 CTRL-ALT-F1 键组合切换一样) = FFh – 切换到国家布局(就像可以通过 CTRL-ALT-F2 键组合切换一样)
返回:发生错误时设置 CF 标志。可能原因:BL 值无效。CF 标志的清除状态表示成功,然后仅在 AX=AD83h 调用之后 BL = 00h – 美国布局;= FFh – 国家布局。
重置操作将鼠标驱动程序恢复到其默认状态:移动和滚轮计数器重置为零,鼠标光标变为不可见,并放置在屏幕页面 0 的中心(应调用函数 INT 33\AX=0001h 以使光标可见)。除了重置之外,INT 33\AX=0000h 函数还可以用来确定是否安装了鼠标驱动程序以及是否有可用的鼠标指向设备。
准备:AX = 0000h
返回:AX = 0000h 值表示鼠标驱动程序未加载(注释 2)。= FFFFh 值表示鼠标驱动程序已加载,然后 CX = 0000h – 鼠标按钮的数量不是两个;= 0002h(以及 FFFFh)– 使用了双键鼠标;= 0003h – 使用了 Mouse Systems/Logitech 三键鼠标。
注释 1:如果视频模式已更改,则在将重置应用于鼠标驱动程序之前,应清除视频模式更改标志(注释 2 到 INT 33\AX=0028h,8.03-52)。
注释 2:MS-DOS7 使用对 IRET 命令的引用填充中断表中的空单元格(直到 INT 3F)(7.03-30)。当鼠标驱动程序未加载时,此 IRET 命令只是返回初始 AX 值,保持不变。如果不需要重置操作,则应使用 INT 33\AX=0021h 函数 (8.03-49) 报告鼠标驱动程序的状态。
准备:AX = 0001h – 显示鼠标光标 = 0002h – 隐藏鼠标光标
注释 1:如果程序调用了 INT 33\AX=0001h 函数来显示鼠标光标,则此程序在终止之前必须隐藏鼠标光标,从而恢复原始状态。除此之外,每次在屏幕上的图像重新绘制之前,都应隐藏鼠标光标,但在后一种情况下,最好使用 INT 33\AX=0010h 函数 (8.03-42) 在本地隐藏光标。
注释 2:隐藏鼠标光标的多次调用将需要多次调用来取消隐藏。使用 INT 33\AX=002Ah 函数 (8.03-53) 报告显示鼠标光标的挂起禁止的数量。
准备:AX = 0003h
返回:BH – 自上次调用以来的 8 位带符号滚轮移动量(注释 1 到 8.03-33) BL – 鼠标按钮状态字节(注释 2 到 8.03-33) CX – 光标的水平 X 坐标(注释 1 到 8.03-53) DX – 光标的垂直 Y 坐标(注释 1 到 8.03-53)
注释 1:如果鼠标设备中存在滚轮并且鼠标驱动程序支持滚轮,则会报告滚轮移动量。应通过调用 INT 33\AX=0011h 函数 (8.03-43) 检查这两个条件。正移动量对应于向下滚轮移动。滚轮移动计数器通过调用 INT 33\AX=0003h 函数以及通过 INT 33\AX=0005h 或 INT 33\AX=0006h 函数 (8.03-35) 发送到此计数器的请求来重置。
注释 2:按钮状态字节报告那些尚未释放的按钮的状态。按钮状态字节中位 0 和 1 的设置状态对应于鼠标左键和右键的按下状态。如果鼠标设备中存在中间按钮并且鼠标驱动程序支持它,则位 2 的设置状态对应于中间按钮的按下状态。
注释 3:在文本视频模式下,坐标以字符单元格大小的倍数报告。
准备:AX = 0004h CX – 光标的 X 坐标(在视频模式 3 中为 0000h–0280h) DX – 光标的 Y 坐标(在视频模式 3 中为 0000h–00C0h)
注释 1:使用 INT 33\AX=0026h 函数 (8.03-51) 以及 INT 33\AX=0031h 函数 (8.03-54) 报告任何当前视频模式的最大坐标值。
注释 2:在文本视频模式下,坐标值会自动四舍五入到最接近的较低字符单元格大小的倍数。
准备:AX = 0005h – 请求有关按钮按下或滚轮事件的信息 = 0006h – 请求有关按钮释放或滚轮事件的信息 BX = 0000h – 请求有关左键事件的信息 = 0001h – 请求有关右键事件的信息 = 0002h – 请求有关中间按钮事件的信息 = FFFFh – 请求有关滚轮移动事件的信息。
返回:AH – 自上次调用以来的 8 位带符号滚轮移动量(注释 1 到 8.03-33) AL – 按钮状态字节(注释 2 到 8.03-33) BX – 在请求按钮事件之后:自上次调用相同函数以来的按钮事件数量(按下或释放);– 在请求滚轮移动事件之后:自上次调用以来的 16 位带符号滚轮移动量(注释 1 到 8.03-33) CX – 最后请求事件(按下或释放或滚轮旋转)发生时的鼠标光标的水平 X 坐标;DX – 最后请求事件(按下或释放或滚轮旋转)发生时的鼠标光标的垂直 Y 坐标。
注释 1:如果自上次调用这些函数以来,尚未对请求的按钮发生任何请求的事件,则返回 BX、CX 和 DX 寄存器中的零值。
准备:AX = 0007h – 定义光标的水平范围 = 0008h – 定义光标的垂直范围 CX – 坐标值的较低限制(注释 2 到 8.03-34) DX – 坐标值的上限(注释 2 到 8.03-34)
注释 1:如果鼠标光标超出所需范围,则 INT 33\AX=0007h–0008h 函数会将光标的位置移到允许范围内的最接近的边界。
8.03-37 INT 33\AX=0009h – 图形视频模式下的鼠标光标
[edit | edit source]准备: AX = 0009h BX – 光标热点水平偏移量(从 -16 到 +16) CX – 光标热点垂直偏移量(从 -16 到 +16) ES:DX – 指向位图掩码块的指针(注 1)。
注 1:位图掩码块包含屏幕掩码和光标掩码,每个掩码长度为 16 字节。屏幕掩码从偏移量 00h 开始,光标掩码从偏移量 20h 开始。掩码中的每个字定义屏幕线上十六个像素。每个字的最低有效位对应最右边的像素。屏幕掩码与视频内存内容通过逻辑 AND 运算叠加,然后光标掩码与结果通过逻辑 XOR 运算叠加。
注 2:当前光标的热点位置由 INT 33\AX=002Ah 函数返回(8.03-53)。
8.03-38 INT 33\AX=000Ah – 文本视频模式下的鼠标光标
[edit | edit source]准备: AX = 000Ah BX = 0000h – 软件定义的光标(注 1) = 0001h – 硬件定义的光标(注 2) CX – 屏幕掩码(如果 BX=0000h),或起始扫描行(如果 BX=0001h) DX – 光标掩码(如果 BX=0000h),或最后一个扫描行(如果 BX=0001h)
注 1:如果选择了软件定义,则视频内存中光标位置的字符/颜色内容将与屏幕掩码进行位与位逻辑 AND 运算,然后结果与光标掩码进行位与位逻辑 XOR 运算。来自 CH 和 DH 寄存器的掩码字节叠加在视频内存中的颜色字节(A.10-5)上。例如,如果 CX=0000h,则光标获取由其在 DL 中的 ASCII 码定义的字符形式;其颜色由 DH 中的字节 0-3 根据表 A.10-5 定义。DH 中的字节 4-6 定义背景颜色,第 7 个字节控制闪烁。CH 寄存器中位 4-6 的非零值使颜色依赖于原始视频内存内容,从而使光标在任何背景图像上更明显。
注 2:如果选择了硬件定义,则光标是一个闪烁的条形或一个闪烁的矩形。例如,值 CX=0002h DX=0003h 将鼠标光标定义为字符行上方的条形;值 CX=0003h DX=0004h 将鼠标光标定义为下划线。
8.03-39 INT 33\AX=000Bh – 读取鼠标运动计数器
[edit | edit source]准备: AX = 000Bh
返回值: CX – 自上次调用 INT 33\AX=000Bh 后的水平偏移量 DX – 自上次调用 INT 33\AX=000Bh 后的垂直偏移量
注 1:鼠标光标的偏移量以步长(“米奇”)计算,这是鼠标可以感知的最小位置增量。Microsoft 的驱动程序将正偏移量分配给向下运动和向右运动。像素和鼠标步长(“米奇”)之间的对应关系可以通过 INT 33\AX=000Fh 函数(8.03-41)设置。
注 2:INT 33\AX=0027h 函数也只接受 AX 值,并在 CX 和 DX 中返回相同的偏移量,但除此之外,根据软件或硬件光标定义(8.03-38)返回:在寄存器 AX 中 – 屏幕掩码或光标的起始扫描行,在寄存器 BX 中 – 光标掩码或光标的最后一个扫描行。
8.03-40 INT 33\AX=000Ch – 鼠标驱动程序对驻留子例程的调用
[edit | edit source]准备: AX = 000Ch CX – 子例程调用条件的掩码: 位 0 设置: – 鼠标移动时调用 位 1 设置: – 左键按下时调用 位 2 设置: – 左键释放时调用 位 3 设置: – 右键按下时调用 位 4 设置: – 右键释放时调用 位 5 设置: – 中键按下时调用 位 6 设置: – 中键释放时调用 位 7 设置: – 轮子旋转时调用(注 1 到 8.03-33) ES:DX – 指向 CALL FAR 命令的子例程入口的指针。(7.03-08)
注 1:在 CX 寄存器中,可以指定多个条件,然后鼠标驱动程序在满足指定条件之一时调用子例程。CX 寄存器中位 15-8 的状态被忽略。CX 寄存器中位 7-5 的状态仅由支持相应鼠标功能的驱动程序考虑。
注 2:驻留子例程以以下寄存器状态调用
- AX – 调用条件(与 CX 掩码中相同的位分配)
- BH – 自上次调用以来的有符号轮子移动量(注 1 到 8.03-33)
- BL – 按钮状态字节(注 2 到 8.03-33)
- CX – 光标的水平坐标(注 2 到 8.03-34)
- DX – 光标的垂直坐标(注 2 到 8.03-34)
- SI – 水平光标偏移量(注 1 到 8.03-39)
- DI – 垂直光标偏移量(注 1 到 8.03-39)。
注 3:INT 33\AX=0014h 函数能够用新的值替换调用掩码和子例程入口地址,这些新的值在 CX 和 ES:DX 寄存器中以类似方式指定;返回值 CX 和 ES:DX 寄存器包含相应替换的旧值。
注 4:如果程序指定了对驻留子例程的鼠标调用,则在程序终止之前必须禁用此鼠标调用。为此,应使用 CX 寄存器中为 0000h 的掩码再次调用 INT 33\AX=000Ch 函数。
注 5:Microsoft 的鼠标驱动程序能够调用最多四个不同的驻留子例程。第一个子例程必须由 INT 33\AX=000Ch 函数指定,其余三个子例程可以通过 INT 33\AX=0018h 函数(8.03-45)指定。
8.03-41 INT 33\AX=000Fh – 鼠标偏移量记录的灵敏度
[edit | edit source]准备: AX = 000Fh CX – 每 8 个像素的水平步长数(默认值为 8) DX – 每 8 个像素的垂直步长数(默认值为 16)。
8.03-42 INT 33\AX=0010h – 对光标显示的局部禁止
[edit | edit source]当鼠标的光标在屏幕上移动时,鼠标的驱动程序会在鼠标的光标移动到的每个位置恢复以前的屏幕图像。鼠标驱动程序恢复以前图像内容的操作可能会干扰前台程序执行的屏幕图像更新过程。如果在屏幕图像的更新部分隐藏鼠标光标,可以避免这种干扰。与 INT 33\AX=0002h 函数(8.03-32)隐藏整个屏幕的鼠标光标不同,对光标显示的局部禁止使光标的闪烁几乎不可察觉。当局部图像更新过程结束时,应通过调用 INT 33\AX=0001h 函数(8.03-32)使鼠标光标可见。
准备: AX = 0010h CX – 禁止区域左上角的水平 X 坐标 DX – 禁止区域左上角的垂直 Y 坐标 SI – 禁止区域右下角的水平 X 坐标 DI – 禁止区域右下角的垂直 Y 坐标。
8.03-43 INT 33\AX=0011h – 指示设备滚轮支持检查
[edit | edit source]准备: AX = 0011h
返回值: AX = 574Dh – 确认驱动程序支持滚轮的签名(注 1) CX – 位 0 设置表示鼠标指示设备具有滚轮。BX 内容可能会被更改。
注 1:GMOUSE.COM 驱动程序(5.03-01)版本 9.06+ 对 INT 33\AX=0011h 函数的调用做出响应,AX = FFFFh 签名。这意味着驱动程序不支持指示设备滚轮,但在 BX 寄存器中返回鼠标的活动按钮数量。
8.03-44 INT 33\AX=0016h–0017h – 保存/恢复鼠标驱动程序的状态
[edit | edit source]准备: AX = 0016h – 将驱动程序的状态记录写入准备好的缓冲区 = 0017h – 从缓冲区中的数据恢复鼠标驱动程序的状态 BX – 缓冲区的大小(注 2) ES:DX – 指向缓冲区的指针(对于 AX=0017h,它必须已填充)
返回值: ES:DX – 指向包含鼠标驱动程序状态记录的缓冲区的指针。
注 1:鼠标驱动程序状态的恢复必须在与将驱动程序的状态记录写入缓冲区时处于活动状态的视频模式相同。
注 2:存储驱动程序状态记录所需的缓冲区大小应事先通过 INT 33\AX=0015h 函数确定:所需大小(以字节为单位)将在 BX 寄存器中返回。
8.03-45 INT 33\AX=0018h – 鼠标驱动程序对驻留子例程的调用
[edit | edit source]微软的鼠标驱动程序能够调用最多四个不同的驻留子程序。第一个子程序必须由 INT 33\AX=000Ch 函数指定(8.03-40),其余三个子程序可以由 INT 33\AX=0018h 函数指定。
准备:AX = 0018h CX – 子程序调用条件掩码
- 位 0 设置:– 鼠标移动时调用
- 位 1 设置:– 左键按下时调用
- 位 2 设置:– 左键释放时调用
- 位 3 设置:– 右键按下时调用
- 位 4 设置:– 右键释放时调用
- 位 5 设置:– 在 SHIFT 键按下状态下调用(注 1)
- 位 6 设置:– 在 CTRL 键按下状态下调用(注 1)
- 位 7 设置:– 在 ALT 键按下状态下调用(注 1)
ES:DX – CALL FAR 指令的子程序入口指针。(7.03-08)
返回时:AX = 0018h – 成功终止的签名;AX = FFFFh – 失败的签名。
注 1:由 INT 33\AX=0018h 函数注册的子程序,当任何“功能”键(SHIFT、CTRL、ALT)按下时都会被调用,因此 CX 掩码中的位 7–5 至少要设置一个。CX 寄存器中位 15–8 的状态将被忽略。CX 掩码中位 4–0 的状态将根据逻辑或运算来考虑:当这些条件中的任何一个满足时,如果同时按下了指定的“功能”键,则会调用子程序。
注 2:当鼠标驱动程序调用子程序时,它会在寄存器中保留文章 8.03-40 注 2 中列出的那些值。
注 3:为了停止对某个子程序的调用,INT 33\AX=0018h 函数应再次调用,CX 寄存器中使用相同的掩码字,但在 ES:DX 寄存器中使用 0000:0000h 入口点地址。
注 4:INT 33\AX=0018h 函数从版本 6.0 开始由微软的鼠标驱动程序支持,但不一定受其他供应商的鼠标驱动程序支持。
8.03-46 INT 33\AX=0019h – 子程序入口点地址
[edit | edit source]响应对 INT 33\AX=0019h 函数的调用,微软的鼠标驱动程序会返回那个 TSR 子程序的入口点地址,该子程序已经由 INT 33\AX=0018h 函数(8.03-45)注册,并在 CX 寄存器中指定了调用条件掩码。返回的数据稍后可供任何前台程序使用,以恢复特定子程序的活动。
准备:AX = 0019h CX – 调用条件掩码(8.03-45)
返回时:CX = 0000h – 错误:未找到具有提交掩码的 TSR。任何其他结果都表示成功,然后 BX:DX – 找到的 TSR 子程序的入口点地址;CX – 子程序调用条件的实际掩码(8.03-45)。
8.03-47 INT 33\AX=001Dh–001Eh – 鼠标光标的屏幕页码
[edit | edit source]准备:AX = 001Dh – 定义鼠标光标的屏幕页码 = 001Eh – 报告当前光标的屏幕页码 BX – 要访问的屏幕页码(仅限 INT 33\AX=001Dh)
返回时:BX – 当前屏幕页码(仅限 INT 33\AX=001Eh 之后)
8.03-48 INT 33\AX=001Fh–0020h – 禁用/重新启用鼠标驱动程序
[edit | edit source]准备:AX = 001Fh – 禁用鼠标驱动程序 = 0020h – 重新启用鼠标驱动程序
返回时:AX = FFFFh – 失败的签名。成功时,AX 值将保持不变。
注 1:INT 33\AX=001Fh 函数会恢复 INT 10 和 INT 74 处理程序的中断表中的地址,这些地址在加载鼠标驱动程序之前就存在。
注 2:如果由鼠标驱动程序设置的中断处理程序地址被 INT 33\AX=001Fh 函数从中断表中删除,那么 INT 33\AX=0020h 函数就可以将这些地址写回中断表。
注 3:成功终止后,INT 33\AX=001Fh 函数会在 ES:BX 寄存器中返回在安装鼠标驱动程序之前位于中断表中的 INT 33 处理程序的地址。如果前台程序将该地址写回中断表,那么通过中断调用鼠标驱动程序的可能性将完全消除。
8.03-49 INT 33\AX=0021h – 鼠标驱动程序安装测试
[edit | edit source]准备:AX = 0021h
返回时:当未安装鼠标驱动程序时,最可能的是 AX = 0021h。AX= FFFFh 值确认已安装鼠标驱动程序,然后 BX – 鼠标按钮的数量(注 2)。
注 1:MS-DOS7 会用指向 IRET 命令的引用来填充中断表中的空单元格(最多 INT 3F)(7.03-30)。当未加载鼠标驱动程序时,此 IRET 命令只会返回初始 AX 值不变。INT 33\AX=0000h 函数(8.03-31)也会报告鼠标驱动程序的状态,该函数也会将驱动程序重置为初始状态。INT 33\AX=0021h 函数不会将鼠标驱动程序重置为初始状态,但会重置滚轮移动计数器。
注 2:在识别出 2 键鼠标后,一些鼠标驱动程序会返回 BX = FFFFh。
8.03-50 INT 33\AX=0024h – 鼠标类型和 IRQ 设置
[edit | edit source]准备:AX = 0024h
返回时:AX = FFFFh – 鼠标设备识别失败的签名。AX 中的任何其他值都表示成功,然后 BH.BL – 鼠标驱动程序版本 CH – 鼠标指示设备类型和连接:= 00h – 鼠标指示设备未连接;= 01h – 鼠标通过扩展卡连接;= 02h – 鼠标连接到串行端口;= 04h – 鼠标连接到 PS/2 端口;= 05h – 特殊的惠普鼠标。CL – 十六进制 IRQ 号码(PS/2 端口除外,CL=00h)。
8.03-51 INT 33\AX=0026h – 光标的最大坐标值
[edit | edit source]准备:AX = 0026h
返回时:BX 寄存器中的非零值表示错误。BX = 0000h – 成功终止的签名,然后 CX – 当前视频模式的最大水平 X 坐标 DX – 当前视频模式的最大垂直 Y 坐标。
注 1:INT 33\AX=0026h 函数报告整个屏幕的光标坐标值。如果光标区域限制在某些范围内(8.03-36),则应使用 INT 33\AX=0031 函数(8.03-54)确定允许的最小和最大坐标值。
注 2:除非通过 INT 33\AX=0032h(8.03-55)确认鼠标驱动程序支持此功能,否则不应调用 INT 33\AX=0026h 函数。
8.03-52 INT 33\AX=0028h – 始终如一的视频模式更改
[edit | edit source]由于鼠标光标是通过直接访问视频内存绘制的,因此鼠标驱动程序的干预必须符合视频内存中当前数据的格式。但是,不同的视频模式定义了不同的数据格式。因此,每次更改视频模式时,都必须与鼠标驱动程序使用的视频数据格式更改相协调。INT 33\AX=0028h 函数提供了一种机会,可以为视频内存和鼠标驱动程序进行一致的视频模式更改,这样就不会影响鼠标光标的外观和移动。
准备:AX = 0028h CX – 提议的视频模式代码(A.10-1) DH – 字符单元的垂直大小(注 1) DL – 字符单元的水平大小(注 1)
返回时:CL 寄存器中的非零值表示失败。CL = 00h – 成功终止的签名。
注 1:零值 DH = DL = 00h 指定任何视频模式的默认字符单元大小。如果提议的视频模式不支持字符单元大小控制,那么 DH 和 DL 寄存器中的任何值都会被忽略。
注 2:如果调用时 CX = 0000h,则不会设置视频模式,但会清除内部视频模式更改标志。在每次调用鼠标驱动程序的重置函数(8.03-31)之前,必须清除此标志。
注 3:除非通过 INT 33\AX=0032h(8.03-55)确认鼠标驱动程序支持此功能,否则不应调用 INT 33\AX=0028h 函数。
注 4:鼠标驱动程序支持的视频模式代码列表可以通过对 INT 33\AX=0029h 函数进行多次连续调用来返回。第一次调用接受 CX = 0000h,并在 CX 中返回第一个支持的视频模式代码。第二次调用使用 CX 中的该代码不变,并在 CX 中返回下一个支持的视频模式代码,依此类推。一些鼠标驱动程序会在 DS:DX 中返回指向包含视频模式描述的字符串的指针;其他一些鼠标驱动程序可能会在 DS:DX 中保留零值。调用循环的结束以返回零值 CX = 0000h 为标志。
8.03-53 INT 33\AX=002Ah – 鼠标光标的参数
[edit | edit source]准备: AX = 002Ah
返回时: AX – 显示鼠标光标的待处理禁令数(8.03-32) BX – 光标热点的水平 X 偏移量(注 1) CX – 光标热点的垂直 Y 偏移量(注 1) DX – 鼠标类型,由 INT 33\AX=0024h(8.03-50)返回的 CH。
注 1:光标坐标相对于光标块的左上角进行计数,但光标指向其热点。热点相对于光标块左上角的偏移量对于两个坐标都可能在 -128 到 +127 之间。
注 2:除非通过 INT 33\AX=0032h(8.03-55)确认鼠标驱动程序支持此函数,否则不应调用 INT 33\AX=002Ah 函数。
8.03-54 INT 33\AX=0031h – 获取当前坐标范围
[edit | edit source]INT 33\AX=0031h 函数报告当前范围限制的值,当可用鼠标光标区域被 INT 33\AX=0007h–0008h(8.03-36)设置的虚拟窗口限制时。
准备: AX = 0031h
返回时: AX – 水平 X 坐标的最小值 BX – 垂直 Y 坐标的最小值 CX – 水平 X 坐标的最大值 DX – 垂直 Y 坐标的最大值
注 1:当可用光标区域不受窗口限制时,坐标范围应由 INT 33\AX=0026h 函数(8.03-51)报告。
注 2:除非通过 INT 33\AX=0032h(8.03-55)确认鼠标驱动程序支持此函数,否则不应调用 INT 33\AX=0031h 函数。
8.03-55 INT 33\AX=0032h – 鼠标驱动程序支持的函数
[edit | edit source]准备: AX = 0032h
返回时: AX – 一个标志字,其中每一位表示对从 INT 33\AX=0034h 到 INT 33\AX=0025h 的鼠标驱动程序函数的支持。
- 位 3 设置: – 支持 INT 33\AX=0031h;
- 位 10 设置: – 支持 INT 33\AX=002Ah;
- 位 11 设置: – 支持 INT 33\AX=0029h;
- 位 12 设置: – 支持 INT 33\AX=0028h;
- 位 14 设置: – 支持 INT 33\AX=0026h。
BX、CX、DX 寄存器的内容不会被保存。
8.03-56 INT 4A – 报警处理程序钩子
[edit | edit source]默认 INT 4A 处理程序只是将控制权返回给调用程序。调用程序的作用属于 BIOS 的实时时钟报警,如果它通过 INT 1A\AH=06h 函数(8.01-94)设置为某个时间。建议应用程序加载一个拦截 INT 4A 处理程序,该处理程序将在预定时间被调用以执行所需操作。
注 1:INT 4A 中断是在硬件中断处理程序内部调用的。因此,必须采取所有必要的预防措施来防止重新进入 DOS(8.02-70、8.02-87)。
8.03-57 INT 67\AH=41h – 获取页帧段
[edit | edit source]默认情况下,EMM386.EXE 驱动程序(5.04-02)在高端内存(低于 1024 kb)中安排 4 个“物理”页,分组到一个 64-kb 帧中。对扩展内存的访问是通过动态映射扩展内存“逻辑”页(超过 1088 kb)到页帧内的这 16-kb“物理”页来实现的。页帧通常从段地址 E000h 开始。
准备: AH = 41h
返回时: AH – 错误代码(A.06-1);如果 AH = 00h,则 BX – 页帧的段地址(4 个“物理”页)。
注 1:除非通过 INT 67\AH=46h(8.03-62 注 1)确认 EMM386.EXE(5.04-02)驱动程序处于活动状态,否则不应调用 INT 67\AH=41h 函数。
8.03-58 INT 67\AH=42h – 获取 EMS 页数
[edit | edit source]根据 EMS 规范,EMM386.EXE 驱动程序提供了对扩展内存中从 1088 到 32768 kb 排列的选定“逻辑”16-kb 页的访问,除了由 /L 参数(5.04-02)为 XMS 驱动程序(5.04-01)安排的访问保留的区域。INT 67\AH=42h 函数报告扩展内存中可供 EMM386.EXE 驱动程序使用的“逻辑”EMS 页的统计信息。
准备: AH = 42h
返回时: AH – 错误代码(A.06-1);如果 AH = 00h,则 BX – 未分配(空闲)“逻辑”EMS 页数 DX – “逻辑”EMS 页总数。
注 1:除非通过 INT 67\AH=46h(8.03-62 注 1)确认 EMM386.EXE(5.04-02)驱动程序处于活动状态,否则不应调用 INT 67\AH=42h 函数。
8.03-59 INT 67\AH=43h – 分配一个句柄和扩展内存
[edit | edit source]与 INT 21\AH=3Dh 函数(8.02-33)不同,EMM386.EXE 驱动程序(5.04-02)只分配那些引用扩展内存区域的句柄,这些区域超出 1088 kb 边界。每个区域可能包含整数个“逻辑”16-kb 页。任何特定“逻辑”页的规范包括它在分配区域中的编号以及分配给该分配区域的句柄。
准备: AH = 43h BX – 请求的非零“逻辑”页数,每个 16 kb。返回时: AH – 错误代码(A.06-1);如果 AH = 00h,则 DX – 包含请求页数的区域的句柄。
注 1:除非通过 INT 67\AH=46h(8.03-62 注 1)确认 EMM386.EXE(5.04-02)驱动程序处于活动状态,否则不应调用 INT 67\AH=43h 函数。
注 2:默认情况下,EMM386.EXE 驱动程序最多可以同时保持 64 个句柄处于活动状态,但“h”参数(5.04-02)可以将活动句柄数增加到 255 个。
注 3:LIM EMS 规范版本 4.0 规定了具有相同任务的 INT 67\AX=5A00h 函数。唯一的区别是允许在 BX 寄存器中请求 0 个“逻辑”页。
8.03-60 INT 67\AH=44h – 将“逻辑”页映射到“物理”页
[edit | edit source]这里的术语“映射”意味着对低于 1024 kb 的特定“物理”16-kb 页的调用将由 CPU 自动转移到扩展内存中超过 1088 kb 边界处的指定“逻辑”16-kb 页。
准备: AH = 44h AL – 选定“物理”16-kb 页的编号;BX – 请求的“逻辑”16-kb 页的编号,或者 = FFFFh – 为了使指定的“物理”页变为空闲;DX – 包含请求“逻辑”页的内存区域的句柄。
返回时: AH – 错误代码(A.06-1);AH = 00h 表示成功终止。
注 1:除非通过 INT 67\AH=46h(8.03-62 注 1)确认 EMM386.EXE(5.04-02)驱动程序处于活动状态,否则不应调用 INT 67\AH=44h 函数。
注 2:内存页的计数,“物理”和“逻辑”都从 0 号开始。
注释 3:“物理”页 00h–03h 构成页面帧。页面帧的地址由 INT 67\AH=41h 函数(8.03-57)报告。如果存在,“物理”页 04h–1Bh 的位置可以通过 INT 67\AX=5800h 函数(8.03-70)报告。如果一个“物理”页位于传统内存(低于 640 kb),则该内存页所占用的内存空间必须由操作系统分配给打算使用该“物理”页的程序。
当与句柄关联的扩展内存的一部分不再需要时,句柄拥有者程序必须通知 EMM386.EXE 驱动程序(5.04-02)。在调用 INT 67\AH=45h 函数后,扩展内存的这一部分将被视为可用,并且关联的句柄将被禁用。
准备:AH = 45h DX – 要释放的内存区域的句柄
返回时: AH – 错误代码(A.06-1);AH = 00h 表示成功终止。
注释 1:INT 67\AH=45h 函数应该仅用于禁用那些由 EMM386.EXE 驱动程序(5.04-02)在调用 INT 67\AX=5A00h 或 INT 67\AH=43h 函数(8.03-59)后分配的句柄。其他句柄应通过 INT 21\AH=68h、INT 21\AH=6Ah 或 INT 21\AH=3Eh 函数(8.02-34)禁用。
注释 2:对句柄的重复请求不能恢复对与已禁用的句柄关联的扩展内存页面的访问。
准备:AH = 46h
返回:AH – 错误代码 (A.06-1);如果 AH = 00h,则 AL – EMM386.EXE 驱动程序的版本号(5.04-02)。
注释 1:存储在中断表 0000:019Eh 单元中的 INT 67 处理程序的地址指向处理程序头的开头。相对于处理程序头开头的偏移量 0Ah,EMM386.EXE 驱动程序写入了签名 EMMXXXX0。如果找不到此签名,则无法调用 INT 67 处理程序的任何函数,因为中断表中的 INT 67 单元默认情况下未填充,可能包含无效指针(例如,0000:0000h)。在适当位置存在 EMMXXXX0 签名确认 EMM386.EXE 驱动程序已加载,然后应该调用 INT 67\AH=46h 函数。INT 67\AH=46h 函数返回的 AH = 00h 值表示 EMM386.EXE 驱动程序处于活动状态,并且已准备好执行其他 INT 67 函数。
注释 2:当确定 EMM386.EXE 驱动程序已加载时,INT 67\AH=46h 函数返回的任何非零错误代码都表示 EMM386.EXE 驱动程序处于非活动状态。在这种情况下,INT 67\AX=FFA5h 函数(8.03-74)可能会有所帮助:它返回 EMM386.EXE 驱动程序的 API 入口点的地址。使用指向此入口点的 CALL FAR 命令(7.03-08),可以将 EMM386.EXE 驱动程序切换到活动状态。
准备:AH = 4Bh
返回:AH – 错误代码 (A.06-1);如果 AH = 00h,则 BX – EMM386.EXE 驱动程序分配的活动句柄数量。
注释 1:除非 INT 67\AH=46h(8.03-62 的注释 1)确认 EMM386.EXE(5.04-02)驱动程序处于活动状态,否则不应调用 INT 67\AH=4Bh 函数。
注 2:默认情况下,EMM386.EXE 驱动程序最多可以同时保持 64 个句柄处于活动状态,但“h”参数(5.04-02)可以将活动句柄数增加到 255 个。
准备:AH = 4Ch DX – 分配给某个扩展内存区域的活动句柄
返回:AH – 错误代码 (A.06-1);如果 AH = 00h,则 BX – 与指定句柄关联的“逻辑”页面数量。
注释 1:INT 67\AH=4Ch 函数仅接受那些由 EMM386.EXE 驱动程序(5.04-02)的 INT 67\AH=43h 函数(8.03-59)分配的活动句柄。除非 INT 67\AH=46h(8.03-62 的注释 1)确认 EMM386.EXE 驱动程序处于活动状态,否则不应调用 INT 67\AH=4Ch 函数。
如果驻留模块打算使用 EMS 访问扩展内存,则应考虑任何由调用驻留模块中断的前台程序也可能使用 EMS 访问扩展内存。除非中断驻留模块在完成其任务后恢复原始的扩展内存映射,否则无法恢复此前台程序的执行。为此,INT 67\AH=4Eh 提供了 4 个子函数,这些子函数可以保存当前扩展内存映射,并稍后恢复它。
准备:AH = 4Eh AL – 子函数:= 00h – 将当前映射保存到数据块中;= 01h – 从数据块中恢复映射;= 02h – 连续执行子函数 00h 和 01h;= 03h – 确定数据块所需的缓冲区大小。ES:DI – 指向空缓冲区的指针(对于子函数 00h 和 02h)DS:SI – 指向数据块的指针(对于子函数 01h 和 02h)
返回:AH – 错误代码 (A.06-1);如果 AH = 00h,则 AL – 所需的缓冲区大小(以字节为单位)(仅在子函数 03h 之后)。
注释 1:INT 67\AH=4Eh 函数由 EMM386.EXE 驱动程序的版本 4.00 及更高版本(5.04-02)执行。因此,除非 INT 67\AH=46h(8.03-62 的注释 1)确认 EMM386.EXE 驱动程序的适当版本和活动状态,否则不应调用 INT 67\AH=4Eh 函数。
注释 2:从 EMM386.EXE 驱动程序的版本 3.00 开始,可以分别通过 INT 67\AH=47h 和 INT 67\AH=48h 函数来执行扩展内存映射状态的保存和恢复。这些函数仅恢复 64-kb 页面帧的状态,不需要明确的数据块,但需要在 DX 寄存器中提供一个句柄,该句柄由 EMM386.EXE 驱动程序分配给调用模块。
映射列表是一个表,它表示与一个句柄关联的“物理”和“逻辑”内存页面之间的对应关系。INT 67\AX=5000h 函数可以将当前映射列表替换为新的映射列表。INT 67\AX=5000h 函数的单个调用等效于多次连续调用 INT 67\AH=44h 映射函数(8.03-60)。
准备:AX = 5000h CX – 映射列表中的条目数量,每个条目 4 个字节(注释 3)DX – 分配给某个扩展内存区域的活动句柄 DS:SI – 指向建议的(新的)映射列表开头的指针 返回:AH – 错误代码 (A.06-1);AH = 00h 表示成功终止。
注释 1:INT 67\AX=5000h 函数仅适用于那些由 EMM386.EXE 驱动程序的 INT 67\AH=43h 或 INT 67\AX=5A00h 函数(8.03-59)分配的句柄。除非 INT 67\AH=46h(8.03-62 的注释 1)确认 EMM386.EXE(5.04-02)驱动程序处于活动状态,否则不应调用 INT 67\AX=5000h 函数。
注释 2:如果一个“物理”页位于传统内存(低于 640 kb),则该内存页所占用的内存空间必须由操作系统分配给打算使用该“物理”页的程序。
注释 3:映射列表中的每个条目长度为 4 个字节,由两个字组成。每个条目中的第二个字是“物理”页面号(最常为 0000h–0003h)。对于映射操作,条目中的第一个字必须是“逻辑”页面号。对于相反的取消映射操作,条目中的第一个字必须是 FFFFh 值:它强制取消与相应“物理”页面的当前关联。
注释 4:INT 67\AX=5001h 函数负责执行相同的任务,并接受相同的规范(除了 AX),但对映射列表中的其他数据进行操作:每个条目中的第二个字必须是相应“物理”页面的段地址。
准备 : AH = 51h BX – 为句柄请求的“逻辑”页数 DX – 一个活动句柄,分配给某个扩展内存区域
返回时 : AH – 错误代码 (A.06-1); 如果 AH = 00h,那么 BX – 与指定句柄关联的实际页数。
注意 1: INT 67\AX=51h 函数只对那些由 EMM386.EXE 驱动程序的函数 INT 67\AH=43h 或 INT 67\AX=5A00h (8.03-59) 分配的句柄进行操作。除非 EMM386.EXE (5.04-02) 驱动程序的活动状态通过 INT 67\AH=46h (8.03-62 的注意 1) 确认,否则不应调用 INT 67\AX=51h 函数。
注意 2: 如果调用 INT 67\AH=51h 函数以增加关联的“逻辑”页数,那么新页的序号将跟随当前可用的“逻辑”页的序号。如果调用 INT 67\AH=51h 函数以减少关联的“逻辑”页数,那么序号最大的页将首先丢失。
当代码在扩展内存中执行时,控制转移操作 JMP FAR 和 CALL FAR 的目标“逻辑”页应提前被访问。为此,EMM386.EXE 驱动程序提供两个函数,将控制转移与为指定句柄替换映射列表结合起来。INT 67\AH=55h 函数替换映射列表并执行 JMP FAR 操作 (7.03-39),INT 67\AH=56h 函数替换映射列表并执行 CALL FAR 操作 (7.03-08)。这两个函数都从准备好的数据块中接收大部分所需参数。此数据块的结构如表 A.12-6 所示。
准备 : AX = 5500h – 用于 JMP FAR 操作 = 5600h – 用于 CALL FAR 操作 DX – 一个活动句柄,分配给某个扩展内存区域 DS:SI – 指向数据块 (A.12-6) 起始位置的指针。
返回时: AH – 错误代码(A.06-1);AH = 00h 表示成功终止。
注意 1: INT 67\AH=55h–56h 函数应仅由那些设计为在扩展内存中执行的程序使用。
注意 2: INT 67\AX=5501h 和 INT 67\AX=5601h 函数承担相同的任务并接受相同的规格 (除了 AX),但操作映射列表中的其他数据:每个条目中的第二个字必须是相应“物理”页的段地址。
注意 3: INT 67\AX=5602h 函数不需要其他初始数据,除了 AX 值,并在 BX 寄存器中返回为返回值地址保留的字节数,这些地址由 INT 67\AX=5600-5601h 函数保存在堆栈中。
INT 67\AX=5700h–5701h 函数允许在内存区域之间复制数据或交换数据,这些内存区域可以通过不同的句柄访问或属于常规内存。寻址参数在表 A.12-5 中所示的描述符中指定。
准备 : AX = 5700h – 将数据从一个内存区域复制到另一个内存区域 = 5701h – 在内存区域之间交换数据 DS:SI – 指向参数描述符 (A.12-5) 的指针
返回时: AH – 错误代码(A.06-1);AH = 00h 表示成功终止。
注意 1: 函数 INT 67\AX=5700h–5701h 仅对那些由 EMM386.EXE 驱动程序的函数 INT 67\AH=43h 或 INT 67\AX=5A00h (8.03-59) 分配的句柄进行操作。除非 EMM386.EXE (5.04-02) 驱动程序的活动状态通过对 INT 67\AH=46h (8.03-62 的注意 1) 的调用确认,否则不应调用 INT 67\AX=5700h–5701h 函数。
准备 : AX = 5800h ES:DI – 指向要填充的缓冲区的指针
返回时 : AH – 错误代码 (A.06-1); 如果 AH = 00h,那么 CX – 缓冲区中的条目数 (每个条目 4 字节);ES:DI – 指向已填充条目的缓冲区的指针 (注意 2)
注意 1: 除非 EMM386.EXE (5.04-02) 驱动程序的活动状态通过对 INT 67\AH=46h (8.03-62 的注意 1) 的调用确认,否则不应调用 INT 67\AH=5800h 函数。
注意 2: 缓冲区中的每个条目长度为 4 字节,由 2 个字组成:第一个是物理页段,第二个是相应的物理页号。
注意 3: 物理页数 (以及缓冲区的长度) 可以通过 INT 67\AX=5801h 函数提前获得,该函数以类似的方式在 CX 寄存器中返回条目数,但不填充缓冲区并忽略 ES:DI 寄存器的内容。
INT 67\AX=DE06h 函数由 VCPI 服务器执行。它有助于理解由切换到 V86 模式 CPU 执行的 USB 地址空间转换概念。由于在 MS-DOS7 中 EMM386.EXE 驱动程序 (5.04-02) 负责 VCPI 服务器的任务,因此当 EMM386.EXE 驱动程序的活动状态尚未通过对 INT 67\AH=46h (8.03-62 的注意 1) 的调用确认,以及当 VCPI 函数通过 /noVCPI 参数 (5.04-02 的注意 2) 禁用时,不应调用 INT 67\AH=DE06h 函数。
准备 : AX = DE06h CX – 1024 KB 边界以下的 4 KB 页数 (注意 1)
返回时 : AH – 错误代码 (A.06-1); AH = 8Bh 表示页号无效。AH = 00h 值表示成功,然后 EDX – 请求页的物理地址 (注意 2)。
注意 1: 与 LIM EMS 函数不同,VCPI 函数操作 4 KB 页,由 32 位 CPU 中的 TLB 地址转换机制处理。4 KB 页的页号通过将其线性地址右移 12 位获得。例如,内存单元 D400:1ABCh 的线性地址为 D5ABCh,因此其页号为 CX = 00D5h。
注意 2: 对于 DOS 程序,访问 EDX 和其他 32 位寄存器的方法如文章 7.02-06 所示。
与使用 MOV 命令 (7.03-58 的注意 1) 读取 CR0 寄存器状态的操作不同,该操作需要 CPU 的实模式或最高特权级别,VCPI 服务器的 INT 67\AX=DE07h 函数在 CPU 的 V86 模式下第三 (最低) 特权级别可用。由于在 MS-DOS7 中 EMM386.EXE 驱动程序 (5.04-02) 负责 VCPI 服务器的任务,因此当 EMM386.EXE 驱动程序的活动状态尚未通过对 INT 67\AH=46h (8.03-62 的注意 1) 的调用确认,以及当 VCPI 函数通过 /noVCPI
参数 (5.04-02 的注意 2) 禁用时,不应调用 INT 67\AH=DE07h 函数。
准备 : AX = DE07h
返回时 : AH – 错误代码 (A.06-1); 如果 AH = 00h,那么 EBX – 控制寄存器 CR0 的当前状态 (注意 1)。
注意 1: 对于 DOS 程序,访问 EBX 和其他 32 位寄存器的 方法如文章 7.02-06 所示。
与使用 MOV 命令 (7.03-58 的注意 1) 访问 CPU 的寄存器 DR0–DR7 不同,该操作需要 CPU 的实模式或最高特权级别,VCPI 服务器的 INT 67\AX=DE08h–DE09h 函数在 CPU 的 V86 模式下第三 (最低) 特权级别可用。由于在 MS-DOS7 中 EMM386.EXE 驱动程序 (5.04-02) 负责 VCPI 服务器的任务,因此当 EMM386.EXE 驱动程序的活动状态尚未通过对 INT 67\AH=46h (8.03-62 的注意 1) 的调用确认,以及当 VCPI 函数通过 /noVCPI 参数 (5.04-02 的注意 2) 禁用时,不应调用 INT 67\AH=DE08h–DE09h 函数。
准备 : AX = DE08h – 将 DR0–DR7 寄存器中的内容读取到缓冲区中 = DE09h – 将缓冲区中的内容写入 DR0–DR7 寄存器中 ES:DI – 指向包含数据的缓冲区的指针或用于数据的指针 (注意 1)
返回时: AH – 错误代码(A.06-1);AH = 00h 表示成功终止。
注意 1: 缓冲区长度为 32 字节,每个寄存器从 DR0 到 DR7 填充 4 个数据字节。与 DR4 和 DR5 寄存器相对应的数据不会被读取,在写入操作中被忽略。DR 寄存器的作用在附录 A.11-5 中描述。
INT 67\AX=FFA5h 函数,从 4.2 版开始由 LIM EMS 规范规定,与其他 INT 67 函数的不同之处在于,即使 EMM386.EXE 驱动程序处于非活动状态,它也会被执行,并忽略所有其他请求。但是,此功能不会排除在调用 INT 67\AX=FFA5h 函数之前检查 EMM386.EXE 驱动程序是否已加载的必要性 (8.03-62 的注意 1)。
准备 : AX = FFA5h
返回时:AH = 84h – 成功终止的签名,然后 BX:CX – EMM386.EXE API 入口点的地址。
注意 1:对 BX:CX 入口点的 CALL FAR 命令(7.03-08)强制 EMM386.EXE 执行操作,由 AX 寄存器中的值定义。
- 如果 AX = 0100h – 将自身切换到活动状态;
- 如果 AX = 0101h – 将自身切换到非活动状态;
- 如果 AX = 0500h – 显示关于当前状态的消息。
当 UMB 块和 EMS 页面正在使用时,切换到非活动状态的请求将不会执行。
当 CPU 处于实模式时,INT 70 – INT 77 中断处理程序组会响应来自各种设备通过 IRQ 8 – IRQ 15 线发送到第二个中断控制器的请求,第二个中断控制器又将输出通过第一个中断控制器的 IRQ 2 线(INT 0A,8.01-09)发送到 CPU。每个 IRQ 8 – IRQ 15 输入线都可以通过向端口 A1h 发送一个位来禁用(屏蔽),该位在下面的表中第三列指定。一些 IRQ 线具有专用硬件源,在下面的表中第四列列出,但其他一些 IRQ 线可用于接收来自任何设备的请求,这些设备被调整为通过这些线之一发送请求,并且由一个加载了相应中断处理程序的驱动程序支持。
中断 | 线 | 掩码 | 请求来源 | 注释 |
---|---|---|---|---|
INT 70 | IRQ 8 | 位 0 | 实时时钟 | 注意 *1 |
INT 71 | IRQ 9 | 位 1 | – | |
INT 72 | IRQ 10 | 位 2 | – | |
INT 73 | IRQ 11 | 位 3 | – | |
INT 74 | IRQ 12 | 位 4 | – | 注意 *2 |
INT 75 | IRQ 13 | 位 5 | 算术协处理器 | |
INT 76 | IRQ 14 | 位 6 | 第一个 IDE 控制器 | |
INT 77 | IRQ 15 | 位 7 | – | 注意 *3 |
注意 1:INT 70 处理程序每秒被调用 1024 次。有些 BIOS 系统只在事件等待间隔中调用 INT 70 处理程序(INT 15\AH=83h,8.01-73)。
注意 2:IRQ 12 线的首选源是 PS2 鼠标(如果使用)。
注意 3:IRQ 15 线的首选源是第二个 IDE 控制器或 SCSI 总线控制器(如果在特定 PC 中存在)。