我是一名学习汇编语言(NASM)的学生,我需要一些关于中断“函数”或int如何知道哪些寄存器要“运行”的澄清。我发现一份声明
mov ah, 0x0e mov al, "A" int 0x10
打印A,0x0e和A(0x41)形成ax寄存器,如(0x0e, 0x41),但int“函数”如何知道ax寄存器应该“运行”,而不是bx或cx?仅仅是因为ah和al的语句在int 0x10之上吗?
A
0x0e
0x41
ax
0x0e, 0x41
bx
cx
ah
al
0x10
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]处写一个代码段字。
int
int 0x10
iret
1条答案
按热度按时间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]处写一个代码段字。