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

3
我是一名学习汇编语言(NASM)的学生,我需要对中断“函数”或int如何知道要“运行”哪些寄存器进行一些澄清。我已经弄清楚了一个语句的含义。
mov ah, 0x0e
mov al, "A"
int 0x10  

打印 A0x0e 以及 A (0x41) 组成了 ax 寄存器,就像 (0x0e, 0x41),但是 int "function" 怎么知道 ax 寄存器应该 "运行" 而不是 bx 或者 cx?是因为 ahal 的语句在 int 0x10 之上吗?

6
没有自动机制。那个BIOS函数的作者(在这种情况下)_决定_接受alah作为参数。有文档列出了各种函数所期望的参数和返回值,以及它们的位置。 - undefined
答案是传统。 - undefined
4
int本身只是通过一个表格进行的夸张的call。它本身并不做任何事情,而是由调用的处理程序来完成。这默认是您的BIOS中的代码。您可以想象它看起来像cmp ah, 0x0e; je print_char,然后print_char查看al。因此,寄存器的加载位置和方式并不重要,只要适当的值在其中即可。 - undefined
1个回答

5
int指令实际上并不进行任何打印操作。它的作用是跳转到不同的代码段。而真正进行打印操作的是那段代码,根据IBM PC BIOS作者的软件设计选择,将函数号存储在AH寄存器中(其他寄存器根据函数的不同存储参数)。详情请参考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的操作数。这是一个逻辑seg:off地址数组,称为IVT(中断向量表)。
  5. 跳转到该地址
只有CS、IP、FLAGS和SP寄存器会被修改。所有其他寄存器保持不变,目标代码可以检查它们。目标代码决定寄存器的含义。当代码执行完毕时,它执行iret(中断返回)指令,该指令与int相反,并跳回到您的程序。
目标代码很可能是BIOS的一部分,尽管它也可以是视频适配器ROM的一部分。
您还可以在位置[64]处编写一个新的地址,并将int 0x10重定向到您自己的代码。您必须在[64]处写入一个偏移字,并在[64+2]=[66]处写入一个代码段字。

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