什么是INT 21h?

5

受到这个问题的启发

如何强制GDB反汇编?

我对INT 21h这个概念很好奇。现在,我有一些关于内部工作原理的生疏知识,但是没有太多细节。我记得在C64中,你有常规中断和不可屏蔽中断,但我的知识就止步于此了。请问您能给我一些线索吗?这是DOS相关的策略吗?


你链接的另一篇文章实际上与 INT 21h 没有太多关系 - 除非你在搞16位DOS代码,否则不会遇到它。其他操作系统也使用中断进行系统调用,尽管不是21h - 而非古老的操作系统和CPU使用更新的 SYSCALL 指令。 - snemarch
9个回答

12

这里: 一种多用途的DOS中断,用于各种功能,包括读取键盘、向控制台和打印机写入内容。它也被用于使用更早的文件控制块(FCB)方法读写磁盘。


10

DOS可以被认为是一个用于为个人计算机提供文件/目录抽象的库(还有更多)。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指令。


1
事实上,Linux支持int 0x80作为调用32位ABI的缓慢但可移植的方式,即使在64位模式下也是如此。https://blog.packagecloud.io/eng/2016/04/05/the-definitive-guide-to-linux-system-calls/ - Peter Cordes

8

3

INT指令是一种软中断。它会导致跳转到由中断向量指向的例程,该向量是内存中的一个固定位置。 INT指令的优点是它只有2个字节长,而不像JMP可能有6个字节长,并且可以通过修改中断向量的内容轻松地重新定向。


2
这是来自伟大的汇编语言编程艺术关于中断的内容:

在80x86上,通常被称为中断的事件有三种类型:陷阱、异常和中断(硬件中断)。本章将描述这些形式并讨论它们在80x86 CPU和PC兼容机器上的支持。

虽然陷阱和异常的术语经常被用作同义词,但我们将使用术语“陷阱”来表示程序员启动并期望向特殊处理程序例程的控制传输。在许多方面,陷阱只是一次专门的子程序调用。许多文本将陷阱称为软件中断。 80x86 int指令是执行陷阱的主要手段。请注意,陷阱通常是无条件的;也就是说,当您执行int指令时,控制始终转移到与陷阱关联的过程。由于陷阱通过显式指令执行,因此很容易确定程序中哪些指令将调用陷阱处理例程。

第17章 - 中断结构和中断服务例程


2

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)。


1
Windows控制台不执行DOS仿真 - 控制台模式应用程序是完整的32位Windows应用程序。 command.com!= cmd.exe :) - 32位Windows版本具有NTVDM,它提供DOS仿真。 - snemarch

1
(几乎)整个DOS界面都可以通过INT21h命令进行访问,各种参数存储在不同的寄存器中。这是一个小技巧,使用内置硬件表来跳转到正确的代码。另外,INT 33h用于鼠标。

1

这是一个“软件中断”,因此根本不是硬件中断。

当应用程序调用软件中断时,这基本上与其进行子例程调用相同,只是(与子例程调用不同)它不需要知道所调用代码的确切内存地址。

系统软件(例如DOS和BIOS)将其API公开为软件中断,供应用程序使用。

因此,软件中断是一种动态链接。


0

实际上,这里有很多概念。让我们从基础知识开始。

中断是一种请求CPU注意的方式,以“中断”当前程序流程,跳转到中断处理程序(ISR-中断服务例程),执行一些工作(通常由操作系统内核或设备驱动程序完成),然后返回。

中断的一些典型用途是什么?

  • 硬件中断:设备通过发出中断请求来请求CPU的注意。
  • CPU异常:如果发生某些异常的CPU条件,例如除以零,页面错误等,CPU会跳转到相应的中断处理程序,以便操作系统可以执行必要的操作(向进程发送信号,从交换中加载页面并更新TLB /页面表等)。
  • 软件中断:由于中断最终会调用操作系统内核,因此实现系统调用的简单方法是使用中断。但是您不需要在x86中使用调用指令来调用某个结构(某种TSS IIRC),在较新的x86上有SYSCALL / SYSENTER指令。

CPU通过查看表格(异常向量、中断向量、x86实模式下的IVT、x86保护模式下的IDT等)来决定跳转到哪里。一些CPU有一个硬件中断向量,另一个用于异常等,ISR必须做一些工作来识别中断的发起者。其他CPU有很多向量,并直接跳转到非常特定的ISR。

x86有256个中断向量。在原始PC上,它们被分成几组:

  • 00-04 CPU异常,包括NMI。随着后来的CPU(80186、286等)的出现,这个范围扩大了,与下面的范围重叠。
  • 08-0F 这些是硬件中断,通常称为IRQ0-7。PC-AT添加了IRQ8-15。
  • 10-1F BIOS调用。从概念上讲,这些可以被视为系统调用,因为BIOS是依赖于具体机器的DOS的一部分(这就是在CP/M中定义的方式)。
  • 20-2F DOS调用。其中一些是多路复用的,并提供多种功能。主要的是INT 21h,它提供了大部分的DOS服务。
  • 30-FF 剩余的部分,供外部驱动程序和用户程序使用。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接