受这个问题的启发
我想知道 INT 21h 作为一个概念。现在,我对内部结构有了一些非常生疏的知识,但没有那么多细节。我记得在 C64 中有常规中断和不可屏蔽中断,但我的知识到此为止。你能给我一些线索吗?它是与DOS相关的策略吗?
受这个问题的启发
我想知道 INT 21h 作为一个概念。现在,我对内部结构有了一些非常生疏的知识,但没有那么多细节。我记得在 C64 中有常规中断和不可屏蔽中断,但我的知识到此为止。你能给我一些线索吗?它是与DOS相关的策略吗?
从这里:用于各种功能的多用途 DOS 中断,包括读取键盘和写入控制台和打印机。它还用于使用早期的文件控制块 (FCB) 方法读取和写入磁盘。
DOS 可以被认为是一个用于为 PC 提供文件/目录抽象的库(以及更多)。int 21h
是一个简单的硬件“技巧”,可以很容易地从这个库中调用代码,而无需事先知道它将在内存中的位置。或者,您可以将其视为利用 DOS API 的方式。
现在,软件中断的主题是一个复杂的话题,部分原因是随着英特尔向 x86 系列添加功能,同时试图保持与旧软件的兼容性,这些概念随着时间的推移而演变。一个适当的解释需要几页,但我会尽量简短。
主要问题是您是处于实模式还是受保护模式。
实模式是 x86 处理器的简单“原始”操作模式。这是 DOS 运行的模式(当您在 Windows 下运行 DOS 程序时,实模式处理器是虚拟化的,因此在其中适用相同的规则)。当前运行的程序可以完全控制处理器。
在实模式下,有一个向量表告诉处理器从 0 到 255 的每个中断要跳转到哪个地址。该表由 BIOS 和 DOS 以及设备驱动程序填充,有时还包含有特殊需要的程序。其中一些中断可以由硬件产生(例如通过按键)。其他是由某些软件条件生成的(例如除以 0)。它们中的任何一个都可以通过执行int n
指令来生成。
程序可以设置/清除“启用中断”标志;该标志只影响硬件中断,不影响int
指令。
DOS 设计者选择使用中断号 21h 来处理 DOS 请求——这个数字没有实际意义:它在当时只是一个未使用的条目。还有很多其他的(例如,数字 10h 是 BIOS 安装的处理图形的中断例程)。另请注意,所有这些仅适用于 IBM PC 兼容机。比如说嵌入式系统中的 x86 处理器的软件和中断表的排列方式可能完全不同!
保护模式是在 286 处理器中引入并在 386 上得到很大扩展的复杂的“安全感知”模式。它提供多个特权级别。操作系统必须配置所有这些(如果操作系统出错,您就有潜在的安全漏洞)。用户程序通常受限于“最小特权”操作模式,在这种模式下,尝试访问硬件端口、更改中断标志或访问某些内存区域会暂停程序并允许操作系统决定做什么(终止程序或给程序它似乎想要的东西)。
中断处理变得更加复杂。可以这么说,一般来说,如果用户程序发生软件中断,中断号不会作为向量进入中断表。而是生成一般保护异常,并且针对所述异常的操作系统处理程序可以(如果操作系统是这样设计的)计算出进程想要什么并为请求提供服务。我很确定 Linux 和 Windows 过去(如果不是现在)使用这种机制进行系统调用。但是还有其他方法可以实现这一点,例如 SYSENTER 指令。
Ralph Brown 的中断列表包含很多关于哪个中断做什么的信息。int 21和所有其他的一样,根据寄存器值支持广泛的功能。
还提供了 Ralph Brown 列表的非 HTML 版本。
INT 指令是软件中断。它导致跳转到由中断向量指向的例程,该中断向量是内存中的固定位置。INT 指令的优点是只有 2 个字节长,而 JMP 可能需要 6 个字节,并且可以通过修改中断向量的内容轻松地重定向它。
这是来自关于中断的伟大的汇编语言编程艺术:
在 80x86 上,存在三种通常称为中断的事件:陷阱、异常和中断(硬件中断)。本章将描述每种形式并讨论它们对 80x86 CPU 和 PC 兼容机器的支持。
尽管术语陷阱和异常经常作为同义词使用,但我们将使用术语陷阱来表示程序员启动并期望将控制权转移到特殊的处理程序例程。在许多方面,陷阱只不过是一个专门的子程序调用。许多文本将陷阱称为软件中断。80x86 int 指令是执行陷阱的主要工具。请注意,陷阱通常是无条件的;也就是说,当您执行 int 指令时,控制总是转移到与陷阱相关的过程。由于陷阱通过显式指令执行,因此很容易准确地确定程序中的哪些指令将调用陷阱处理例程。
Int 0x21 是一个 x86 软件中断 - 基本上这意味着在内存中的固定点有一个中断表,列出了软件中断函数的地址。当 x86 CPU 接收到中断操作码(或以其他方式决定应该执行特定的软件中断)时,它会引用该表来执行对该点的调用(该点的函数必须使用iret
而不是ret
返回)。
可以重新映射 Int 0x21 和其他软件中断(即使在 DOS 内部,尽管这可能会产生负面影响)。要映射或链接的一个有趣的软件中断是 Int 0x1C(如果你小心的话,是 0x08),它是系统滴答中断,每秒调用 18.2 次。这可用于创建“后台”进程,即使在单线程实模式下(实模式进程将每秒中断 18.2 次以调用您的中断函数)。
在 DOS 操作系统(或提供某些 DOS 仿真的系统,例如 Windows 控制台)上,Int 0x21 映射到有效的 DOS 操作系统主“API”。通过向 AH 寄存器提供不同的值,可以执行不同的 DOS 功能,例如打开文件(AH=0x3D)或打印到屏幕(AH=0x09)。
(几乎)整个 DOS 界面作为 INT21h 命令提供,参数在各个寄存器中。这是一个小技巧,使用内置硬件表跳转到正确的代码。INT 33h 也适用于鼠标。
这是一个“软件中断”;所以根本不是硬件中断。
当应用程序调用软件中断时,这与调用子程序基本相同,只是(与子程序调用不同)不需要知道它正在调用的代码的确切内存地址。
系统软件(例如 DOS 和 BIOS)将它们的 API 作为软件中断暴露给应用程序。
因此,软件中断是一种动态链接。
其实这里有很多概念。让我们从基础开始。
中断是向 CPU 请求注意,中断当前程序流,跳转到中断处理程序(ISR - Interrupt Service Routine),做一些工作(通常由 OS 内核或设备驱动程序)然后返回的手段。
中断有哪些典型用途?
CPU 决定跳转到哪里查看表(异常向量、中断向量、x86 实模式下的 IVT、x86 保护模式下的 IDT,...)。一些 CPU 有一个用于硬件中断的向量,另一个用于异常等,ISR 必须做一些工作来识别中断的发起者。其他的有很多向量,直接跳转到非常具体的 ISR。
x86 有 256 个中断向量。在原始 PC 上,这些被分为几组:
00-04
CPU 异常,包括 NMI。随着后来的 CPU(80186、286、...),这个范围扩大了,与以下范围重叠。08-0F
这些是硬件中断,通常称为 IRQ0-7。PC-AT 添加了 IRQ8-1510-1F
BIOS 调用。从概念上讲,这些可以被认为是系统调用,因为 BIOS 是 DOS 的一部分,它依赖于具体的机器(这就是它在 CP/M 中定义的方式)。20-2F
DOS 调用。其中一些是多路复用的,并提供多种功能。主要的是 INT 21h,它提供了大部分的 DOS 服务。30-FF
其余部分供外部驱动程序和用户程序使用。