int 指令如何知道运行时使用哪些寄存器?

Guf*_*r07 3 x86 assembly bios nasm system-calls

我是一名学习汇编语言(NASM)的学生,我需要一些关于中断“功能”或 int 如何知道要“运行”的寄存器的澄清。我发现一个声明

mov ah, 0x0e
mov al, "A"
int 0x10  
Run Code Online (Sandbox Code Playgroud)

打印A并且0x0eand A( ) 像( ) 一样0x41形成寄存器,但是 int “函数”如何知道寄存器应该“运行”而不是or ?仅仅是因为和 的语句位于 int 之上吗?ax0x0e, 0x41axbxcxahal0x10

小智 5

int指令实际上并不执行任何打印。它的作用是跳转到另一段代码。代码执行打印,并在 AH 中获取函数编号(以及根据函数在其他寄存器中获取参数)是IBM PC BIOS 作者的 软件设计选择。https://en.wikipedia.org/wiki/BIOS_interrupt_call


具体来说,int 0x10就是这样做的(https://www.felixcloutier.com/x86/intn:into:int3:int1):

  1. 将 FLAGS 压入堆栈
  2. 禁用中断和单步模式(由 FLAGS 中的位控制)
  3. 将下一条指令的完整分段地址压入堆栈(返回地址)
  4. 从 RAM 位置 [0x10*4]=[64] 处读取完整分段地址(4 字节)。请注意,这0x10是您提供给 的操作数int。这是 IVT(中断向量表)的索引,是逻辑 seg:off 地址的数组。
  5. 跳转到该地址

仅修改 CS、IP、FLAGS 和 SP 寄存器。所有其他寄存器保持原样,目标代码可以检查它们。目标代码决定寄存器的含义。当代码完成时,它执行iret(中断返回)指令,该指令执行相反的操作int并跳回您的程序。

目标代码很可能是 BIOS 的一部分,尽管它也可以是视频适配器 ROM 的一部分。

您也可以在[64]位置写入新地址,并将其重定向int 0x10到您自己的代码。您必须在[64]处写入一个偏移字,在[64+2]=[66]处写入一个代码段字。