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

gc0ot86w  于 2023-10-19  发布在  其他
关注(0)|答案(1)|浏览(100)

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

mov ah, 0x0e
mov al, "A"
int 0x10

打印A0x0eA0x41)形成ax寄存器,如(0x0e, 0x41),但int“函数”如何知道ax寄存器应该“运行”,而不是bxcx?仅仅是因为ahal的语句在int 0x10之上吗?

u5rb5r59

u5rb5r591#

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压入堆栈
1.禁用中断和单步模式(由FLAGS中的位控制)
1.将下一条指令的完整分段地址压入堆栈(返回地址)
1.从RAM的位置[0x10*4]=[64]读取完整的分段地址(4字节)。注意,这里的0x10是您提供给int的操作数。这是一个索引到IVT,EVM向量表,一个数组的逻辑seg:off地址。
1.跳转到该地址
仅修改CS、IP、FLAGS和SP寄存器。所有其他寄存器保持原样,目标代码可以检查它们。它是目标代码,谁决定什么寄存器意味着什么。当代码完成时,它执行iret(中断返回)指令,这与int相反,并跳回到您的程序。
目标代码很可能是BIOS的一部分,尽管它也可以是视频适配器ROM的一部分。
您也可以在位置[64]处写入新地址,并将int 0x10重定向到您自己的代码。你必须在[64]处写一个偏移字,在[64+2]=[66]处写一个代码段字。

相关问题