什么是 INT 21 小时?
受到这个问题的启发
我想知道关于 INT 21h 作为一个概念。 现在,我对内部结构有一些非常生疏的了解,但没有那么多细节。 我记得在 C64 中有常规中断和不可屏蔽中断,但我的知识仅限于此。 你能给我一些线索吗? 是DOS相关的策略吗?
Inspired by this question
How can I force GDB to disassemble?
I wondered about the INT 21h as a concept. Now, I have some very rusty knowledge of the internals, but not so many details. I remember that in C64 you had regular Interrupts and Non Maskable Interrupts, but my knowledge stops here. Could you please give me some clue ? Is it a DOS related strategy ?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(9)
(几乎)整个 DOS 接口都可作为 INT21h 命令使用,参数位于各个寄存器中。 这是一个小技巧,使用内置的硬件表来跳转到正确的代码。 INT 33h 也适用于鼠标。
(Almost) the whole DOS interface was made available as INT21h commands, with parameters in the various registers. It's a little trick, using a built-in-hardware table to jump to the right code. Also INT 33h was for the mouse.
这是一个“软件中断”; 所以根本不是硬件中断。
当应用程序调用软件中断时,本质上与调用子例程相同,只是(与子例程调用不同)不需要知道其调用的代码的确切内存地址。
系统软件(例如 DOS 和 BIOS)将其 API 作为软件中断暴露给应用程序。
因此,软件中断是一种动态链接。
It's a "software interrupt"; so not a hardware interrupt at all.
When an application invokes a software interrupt, that's essentially the same as its making a subroutine call, except that (unlike a subroutine call) the doesn't need to know the exact memory address of the code it's invoking.
System software (e.g. DOS and the BIOS) expose their APIs to the application as software interrupts.
The software interrupt is therefore a kind of dynamic-linking.
其实这里面有很多概念。 让我们从基础开始。
中断是请求 CPU 注意力的一种方式,可以中断当前的程序流程、跳转到中断处理程序(ISR - 中断服务例程)、执行一些工作(通常由操作系统内核或设备驱动程序)然后返回。
中断有哪些典型用途?
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
其余部分,供外部驱动程序和用户程序使用。Actually, there are a lot of concepts here. Let's start with the basics.
An interrupt is a mean to request attention from the CPU, to interrupt the current program flow, jump to an interrupt handler (ISR - Interrupt Service Routine), do some work (usually by the OS kernel or a device driver) and then return.
What are some typical uses for interrupts?
CPUs decide where to jump to looking at a table (exception vectors, interrupt vectors, IVT in x86 real mode, IDT in x86 protected mode, ...). Some CPUs have a single vector for hardware interrupts, another one for exceptions and so on, and the ISR has to do some work to identify the originator of the interrupt. Others have lots of vectors, and jump directly to very specific ISRs.
x86 has 256 interrupt vectors. On original PCs, these were divided into several groups:
00-04
CPU exceptions, including NMI. With later CPUs (80186, 286, ...), this range expanded, overlapping with the following ranges.08-0F
These are hardware interrupts, usually referred as IRQ0-7. The PC-AT added IRQ8-1510-1F
BIOS calls. Conceptually, these can be considered system calls, since the BIOS is the part of DOS that depends on the concrete machine (that's how it was defined in CP/M).20-2F
DOS calls. Some of these are multiplexed, and offer multitude of functions. The main one is INT 21h, which offers most of DOS services.30-FF
The rest, for use by external drivers and user programs.来自此处:
多用途 DOS 中断,用于各种功能,包括读取键盘以及写入控制台和打印机。 它还用于使用早期的文件控制块 (FCB) 方法来读写磁盘。
From here:
A multipurpose DOS interrupt used for various functions including reading the keyboard and writing to the console and printer. It was also used to read and write disks using the earlier File Control Block (FCB) method.
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 指令。
DOS can be thought of as a library used to provide a files/directories abstraction for the PC (-and a bit more).
int 21h
is a simple hardware "trick" that makes it easy to call code from this library without knowing in advance where it will be located in memory. Alternatively, you can think of this as the way to utilise the DOS API.Now, the topic of software interrupts is a complex one, partly because the concepts evolved over time as Intel added features to the x86 family, while trying to remain compatible with old software. A proper explanation would take a few pages, but I'll try to be brief.
The main question is whether you are in real mode or protected mode.
Real mode is the simple, "original" mode of operation for the x86 processor. This is the mode that DOS runs in (when you run DOS programs under Windows, a real mode processor is virtualised, so within it the same rules apply). The currently running program has full control over the processor.
In real mode, there is a vector table that tells the processor which address to jump to for every interrupt from 0 to 255. This table is populated by the BIOS and DOS, as well as device drivers, and sometimes programs with special needs. Some of these interrupts can be generated by hardware (e.g. by a keypress). Others are generated by certain software conditions (e.g. divide by 0). Any of them can be generated by executing the
int n
instruction.Programs can set/clear the "enable interrupts" flag; this flag affects hardware interrupts only and does not affect
int
instructions.The DOS designers chose to use interrupt number 21h to handle DOS requests - the number is of no real significance: it was just an unused entry at the time. There are many others (number 10h is a BIOS-installed interrupt routine that deals with graphics, for instance). Also note that all this is for IBM PC compatibles only. x86 processors in say embedded systems may have their software and interrupt tables arranged quite differently!
Protected mode is the complex, "security-aware" mode that was introduced in the 286 processor and much extended on the 386. It provides multiple privilege levels. The OS must configure all of this (and if the OS gets it wrong, you have a potential security exploit). User programs are generally confined to a "minimal privilege" mode of operation, where trying to access hardware ports, or changing the interrupt flag, or accessing certain memory regions, halts the program and allows the OS to decide what to do (be it terminate the program or give the program what it seems to want).
Interrupt handling is made more complex. Suffice to say that generally, if a user program does a software interrupt, the interrupt number is not used as a vector into the interrupt table. Rather a general protection exception is generated and the OS handler for said exception may (if the OS is design this way) work out what the process wants and service the request. I'm pretty sure Linux and Windows have in the past (if not currently) used this sort of mechanism for their system calls. But there are other ways to achieve this, such as the SYSENTER instruction.
Ralph Brown 的中断列表 包含大量关于哪个中断执行什么操作的信息。 int 21 与所有其他一样,根据寄存器值支持广泛的功能。
还提供非 HTML 版本的 Ralph Brown 列表。
Ralph Brown's interrupt list contains a lot of information on which interrupt does what. int 21, like all others, supports a wide range of functionality depending on register values.
A non-HTML version of Ralph Brown's list is also available.
INT 指令是软件中断。 它导致跳转到中断向量指向的例程,中断向量是内存中的固定位置。 INT 指令的优点是它只有 2 个字节长,而 JMP 可能有 6 个字节长,并且可以通过修改中断向量的内容轻松地重定向它。
The INT instruction is a software interrupt. It causes a jump to a routine pointed to by an interrupt vector, which is a fixed location in memory. The advantage of the INT instruction is that is only 2 bytes long, as oposed to maybe 6 for a JMP, and that it can easily be re-directed by modifying the contents of the interrupt vector.
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)。
Int 0x21 is an x86 software interrupt - basically that means there is an interrupt table at a fixed point in memory listing the addresses of software interrupt functions. When an x86 CPU receives the interrupt opcode (or otherwise decides that a particular software interrupt should be executed), it references that table to execute a call to that point (the function at that point must use
iret
instead ofret
to return).It is possible to remap Int 0x21 and other software interrupts (even inside DOS though this can have negative side effects). One interesting software interrupt to map or chain is Int 0x1C (or 0x08 if you are careful), which is the system tick interrupt, called 18.2 times every second. This can be used to create "background" processes, even in single threaded real mode (the real mode process will be interrupted 18.2 times a second to call your interrupt function).
On the DOS operating system (or a system that is providing some DOS emulation, such as Windows console) Int 0x21 is mapped to what is effectively the DOS operating systems main "API". By providing different values to the AH register, different DOS functions can be executed such as opening a file (AH=0x3D) or printing to the screen (AH=0x09).
这是来自关于中断的伟大<a href="http://www.artofasm.com" rel="nofollow noreferrer">汇编语言编程的艺术:
第 17 章 - 中断结构和中断服务例程< /a>
This is from the great The Art of Assembly Language Programming about interrupts:
Chapter 17 - Interrupt Structure and Interrupt Service Routines