自学内容网 自学内容网

中断和异常

中断和异常

中断产生的原因

  1. 外部中断:由硬件产生的中断
    1. 不可屏蔽中断: 由CPU的引脚NMI产生
    2. 可屏蔽中断: 由8259的INTR引脚产生
  2. 指令中断
    1. int n指令产生的中断

指令中断

在保护模式下,无法使用实模式下使用的BIOS中断,需要使用IDT描述符设置保护模式中断

IDT结构

IDT

中断向量到中断处理程序

中断向量到中断处理程序

  1. 首先由中断向量对应的IDT描述符的选择子找到对应的段描述符GDT,并根据GDT找到对应的段基址
  2. 然后根据中断向量对应的IDT描述符的选择子找到对应的偏移量,结合段基址定位到中断程序的入口地址
  3. 执行中断处理程序

IDT设置

; IDT
[SECTION .idt]
ALIGN32
[BITS32]
LABEL_IDT:
; 门                        目标选择子,            偏移, DCount, 属性
%rep 128
GateSelectorCode32, SpuriousHandler, 0, DA_386IGate
%endrep
.080h:GateSelectorCode32, UserIntHandler,  0, DA_386IGate

IdtLenequ$ - LABEL_IDT
IdtPtrdwIdtLen - 1; 段界限
dd0; 基地址
; END of [SECTION .idt]

这里定义了前129号中断的内容(128+1): 其中,前128号中断对应的中断处理函数都是SpuriousHandler,第129号中断(0x80)对应的中断处理函数为UserIntHandler. 下面是两个中断处理函数的定义

_UserIntHandler:
UserIntHandlerequ_UserIntHandler - $$
movah, 0Ch; 0000: 黑底    1100: 红字
moval, 'I'
mov[gs:((80 * 0 + 70) * 2)], ax; 屏幕第 0 行, 第 70 列。
iretd

_SpuriousHandler:
SpuriousHandlerequ_SpuriousHandler - $$
movah, 0Ch; 0000: 黑底    1100: 红字
moval, '!'
mov[gs:((80 * 0 + 75) * 2)], ax; 屏幕第 0 行, 第 75 列。
jmp$
iretd

_SpuriousHandler中断处理函数会让程序陷入死循环,而_UserIntHandler中断处理函数可以正常的结束中断

下面的程序实现了如何加载IDT

...
; 为加载 IDTR 作准备
xoreax, eax
movax, ds
shleax, 4
addeax, LABEL_IDT; eax <- idt 基地址
movdword [IdtPtr + 2], eax; [IdtPtr + 2] <- idt 基地址
...
; 关中断
cli
; 加载 IDTR
lidt[IdtPtr]

加载IDT的方法与加载GDT类似,其中cli关中断是为了暂时不响应可屏蔽中断

在保护模式下执行int 80h后会成功调用_UserIntHandler函数,在屏幕第0行第70列打出'I'

外部中断

下图为外部中断的构成:

外部中断

其中,非屏蔽中断对应的中断号为2,8259A对应的中断号由用户设置

8259A设置

8259A是可编程中断控制器,对它的设置并不复杂,是通过向相应的端口写入特定的ICW来实现的。主8259A对应的端口地址是20h和21h,从8259A对应的端口地址是A0h和A1h。ICW共有4个,每一个都是具有特定格式的字节。

  1. 向主\从片写入ICW1

    ICW1

    • 0: 1=需要ICW4, 0=不需要ICW4
    • 1: 1=单个8259, 0=级联8259
    • 2: 1=4字节中断向量, 0=8字节中断向量
    • 3: 1=level triggered模式, 0=edge triggered模式
    • 4: 对于ICW1必须为1
    • 5-7:对于PC系统必须为1
  2. 向主\从片写入ICW2

    ICW1

    • 0-2: 000=80x86系统
    • 3-7:对应开始的中断向量号
  3. 向主片写入ICW3

    ICW1

    • 0: 1=IR0级联从片, 0=无从片
    • 1: 1=IR1级联从片, 0=无从片
    • 2: 1=IR2级联从片, 0=无从片
    • 3: 1=IR3级联从片, 0=无从片
    • 4: 1=IR4级联从片, 0=无从片
    • 5: 1=IR5级联从片, 0=无从片
    • 6: 1=IR6级联从片, 0=无从片
    • 7: 1=IR7级联从片, 0=无从片
  4. 向从片写入ICW3

    ICW1

    • 0-2: 从片连接的主片IR号(二进制表示)
    • 3-7:必须为0
  5. 向主\从片写入ICW4

    ICW1

    • 0: 1=80x86模式, 0=MCS 80/85
    • 1: 1=自动EOI, 0=正常EOI
    • 2-3: 主从缓冲模式
    • 4: 1=SFNM模式, 0=sequential模式
    • 5-7: 未使用
  6. 写OCW1(屏蔽外部中断)

    ICW1

    • 0: 1=IR0打开, 0=关闭
    • 1: 1=IR1打开, 0=关闭
    • 2: 1=IR2打开, 0=关闭
    • 3: 1=IR3打开, 0=关闭
    • 4: 1=IR4打开, 0=关闭
    • 5: 1=IR5打开, 0=关闭
    • 6: 1=IR6打开, 0=关闭
    • 7: 1=IR7打开, 0=关闭

原文地址:https://blog.csdn.net/Yosh1n0/article/details/142692137

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!