中断和异常的建立
来源:互联网 发布:耐药监测数据处理软件 编辑:程序博客网 时间:2024/04/30 23:20
中断和异常比较相似,它们的区别是当CPU处理完中断后还会继续执行触发中断后的语句;而异常是CPU在执行时碰到了错误,转而去执行错误处理程序,执行完后,按照异常的不同可能会继续执行触发异常后的第一条语句,也可能会继续执行触发异常的语句或者退出执行。在实模式下,对于中断或异常号和处理程序的对应由中断向量表完成,而在保护模式下,对应由IDT完成。IDT是中断描述符表,即实模式下的中断向量表,在它里面保存的是中断门(TYPE=e),陷阱门(TYPE=f)和任务门(TYPE=5)。
中断分为硬中断和软中断,软中断可以由int指令模拟,int指令也可以模拟异常的发生,它和中断之间的区别是如果用int触发异常,则CPU会保存一个错误码到堆栈,而如果用int指令触发中断,则不会保存错误码。中断执行总的过程是向量号-->IDT-->中断门-->GDT。需要注意的是中断门中低两字节的偏移是对GDT中描述符的基地址而言的,在执行时,CPU会将GDT中段描述符的基地址+中断门偏移地址得到处理程序的地址。
- ;8259A中的IRQ0~IRQ15的中断类型都是固定的
- org 0x7c00
- mov ax,cs
- mov ds,ax
- ;gdt
- xor eax,eax
- mov ax,cs
- shl eax,4
- add eax,display
- mov [SEG_CODE+2],ax
- shr eax,16
- mov byte [SEG_CODE+4],al
- mov byte [SEG_CODE+7],ah
- lgdt [gdtr]
- cli
- lidt [idtr]
- mov eax,[idt]
- mov eax,[idt+4]
- ;a20
- in al,0x92
- or al,00000010b
- out 0x92,al
- ;cr0
- mov eax,cr0
- or eax,0x1
- mov cr0,eax
- call Init8259A
- int 0x00
- ;创建GDT
- ;========================================================
- gdt:
- dw 0,0,0,0
- ;代码段
- SEG_CODE:
- dw 0x07ff
- dw 0x0000
- dw 0x9a00
- dw 0x00cf
- ;数据段
- SEG_DATA:
- dw 0x07ff
- dw 0x0000
- dw 0x9200
- dw 0x00cf
- SEG_VIDEO:
- ;视频段
- dw 0x07ff
- dw 0x8000
- dw 0x920B
- dw 0x00cf
- gdt_end:
- gdtr:
- dw gdt_end-gdt-1
- dw gdt,0
- ;创建IDT
- ;=========================================================
- idt:
- dw intr_handler-display;不是GDT的选择子 处理程序在代码段中的偏移
- ;代码段的基地址被赋为display,所以偏移为intr_handler-display
- dw CODE_SELECTOR;IDT中的选择子都是代码段选择子
- dw 0x8e00;TYPE=e为中断门
- dw 0x0000
- idt_end:
- idtr:
- dw idt_end-idt-1
- dw idt,0
- ;选择子
- ;==========================================================
- CODE_SELECTOR equ SEG_CODE-gdt
- DATA_SELECTOR equ SEG_DATA-gdt
- VIDEO_SELECTOR equ SEG_VIDEO-gdt
- CALL_GATESELECTOR equ CALL_GATE-gdt
- [BITS 32]
- ;已将display赋给GDT中的代码段描述符
- ;所以代码段的基地址是display的地址
- display:
- mov ax,VIDEO_SELECTOR
- mov gs,ax
- mov ah,0x0c;0000:黑底 1100:红字
- mov al,'A'
- mov edi,(80*0+0)*2
- mov [gs:edi],ax
- jmp $
- ;初始化8259A
- Init8259A:
- mov al,0x11
- out 0x20,al;主片ICW1
- call io_delay
- out 0xA0,al;从片ICW1
- call io_delay
- mov al,0x20
- out 0x21,al;0x21是8259A的主片的另一个端口
- call io_delay
- mov al,0x28
- out 0xA1,al
- call io_delay
- mov al,0x04;IR2(主片中的第三个角连着从片)
- out 0x21,al;ICW3
- call io_delay
- mov al,0x02
- out 0xA1,al
- call io_delay
- mov al,0x01
- out 0x21,al
- call io_delay
- out 0xA1,al
- call io_delay
- mov al,11111111b;主片8259A
- out 0x21,al;OCW1
- call io_delay
- mov al,11111111b;从片8259A
- out 0xA1,al;OCW1
- call io_delay
- ret
- io_delay:
- nop
- nop
- nop
- nop
- ret
- intr_handler:
- mov ax,VIDEO_SELECTOR
- mov gs,ax
- mov ah,0x0c
- mov al,'!'
- mov edi,(80*0+0)*2
- mov [gs:edi],ax
- jmp $
- times 510-($-$) db 0
- dw 0xaa55
上面的代码还没有打开8259A中的中断,如果要打开,则要设置相应的OCW1,如打开时钟中断,则
mov al,11111110b
out 0x21,al
同时,还要用sti指令设置IF=1。
现在还存在的问题是ret指令时,系统总会崩溃,应该是堆栈的问题,所以处理程序最后都死循环了。
0 0
- 中断和异常的建立
- 中断和异常的建立
- 【中断异常】中断的响应和服务
- ARM的异常和中断
- 中断和异常的区别
- 中断和异常的处理
- 80386的中断和异常
- 中断和异常的比较
- 中断和异常的区别
- 中断和异常的区别
- 中断和异常的处理
- 中断和异常的概念
- STM32的中断和异常
- TCP 连接的建立和中断
- Linux中断实现方法(一):中断注册方法及异常向量表的建立
- E500的异常和中断分析(1)
- 中断和异常的转移方法
- 对中断和异常的理解
- 特权级之间的转换
- codeforces 696B 树形dp+概率
- 国内外新潮巨擘git开源
- 很简单的JSP问题,<base href="<%=basePath%>">这句话什么意思?
- SUZUKI最新专利图流出,SX-R排量大猜想
- 中断和异常的建立
- caffe中HingeLossLayer层原理以及源码分析
- 堆排序
- Http网络框架的构建
- OkHttp学习(3)-->>同步、异步之上传文件至服务器(重写RequestBody方法,实现上传进度接口回调)
- Atitti.java exp ast java表达式语法ast构造器
- C/C++ 头文件作用
- 让div变为圆角
- json学习笔记