1、微机接口技术实验微机接口技术实验实验五 保护模式下的中断处理姓名:胡诣嵩 学号:20053449日期:2008-5-30一 实验名称保护模式下的中断处理二 实验目的1通过本实验了解、熟悉保护模式下的中断以及它的处理方式。2巩固微机接口课程学习的80386DX在保护模式下相关的知识点。三 简述程序执行过程1、作切换到保护方式的准备2、切换到保护方式3、程序循环等待,当有键盘和时钟中断时,调用中断服务程序显示字符4、切换回实模式四 实验源程序;功能:演示保护方式下的中断处理过程.386P;-;存储段描述符结构类型定义;-Desc STRUCLimitL DW 0 ;段界限(BIT0-15)Base
2、L DW 0 ;段基地址(BIT0-15)BaseM DB 0 ;段基地址(BIT16-23)Attributes DB 0 ;段属性LimitH DB 0 ;段界限(BIT16-19)(含段属性的高4位)BaseH DB 0 ;段基地址(BIT24-31)Desc ENDS;-;伪描述符结构类型定义(用于装入全局或中断描述符表寄存器);-PDesc STRUCLimit DW 0 ;16位界限Base DD 0 ;32位基地址PDesc ENDS;-;门描述符结构类型定义;-Gate STRUCOffsetL DW 0 ;32位偏移的低16位Selector DW 0 ;选择子DCount
3、DB 0 ;双字计数GType DB 0 ;类型OffsetH DW 0 ;32位偏移的高16位Gate ENDS;-;存储段描述符类型值说明;-ATDR EQU 90h ;存在的只读数据段类型值ATDW EQU 92h ;存在的可读写数据段属性值ATDWA EQU 93h ;存在的已访问可读写数据段类型值ATCE EQU 98h ;存在的只执行代码段属性值ATCER EQU 9ah ;存在的可执行可读代码段属性值ATCCO EQU 9ch ;存在的只执行一致代码段属性值ATCCOR EQU 9eh ;存在的可执行可读一致代码段属性值DA_386IGate EQU 8Eh ;386 中断门类型
4、值;-DSEG SEGMENT USE16 ;16位数据段;-_SavedIMREG_M db 0 ; 中断屏蔽寄存器值_SavedIMREG_S db 0 ; DB 512 dup (0)TopOfStack LABEL BYTEGDT LABEL BYTE ;全局描述符表DUMMY Desc ;空描述符Code Desc ;代码段描述符DataV Desc ;源数据段描述符DataP Desc ;目标数据段描述符Code32 Desc ;代码段描述符;-GDTLen = $-GDT ;全局描述符表长度VGDTR PDesc ;伪描述符;-Code_Sel = Code-GDT ;代码段选择
5、子DataV_Sel = DataV-GDT ;源数据段选择子DataP_Sel = DataP-GDT ;目标数据段选择子Code32_Sel = Code32-GDT ;目标数据段选择子;-; IDTALIGN 32IDT LABEL BYTEIDT_00_1F Gate 32 dup ()IDT_20 Gate 1 dup ()IDT_21 Gate 1 dup () ;IDT_21_7F Gate 94 dup ()IDT_80 Gate 1 dup ()IDTLen = $-IDT ;中断描述符表长度VIDTR PDesc ;伪描述符_wSSValueInRealMode dw 0_
6、wSPValueInRealMode dw 0_SavedIDTR dd 0 ; 用于保存 IDTR dd 0;-DSEG ENDS ;数据段定义结束;-;打开A20地址线;-EnableA20 MACRO push ax in al,92h or al,00000010b out 92h,al pop ax ENDM;-;关闭A20地址线;-DisableA20 MACRO push ax in al,92h and al,11111101b out 92h,al pop ax ENDM;-;16位偏移的段间直接转移指令的宏定义(在16位代码段中使用);-JUMP16 MACRO Selec
7、tor,Offset DB 0eah ;操作码 DW Offset ;16位偏移量 DW Selector ;段值或段选择子 ENDM;-CSEG SEGMENT USE16 ;16位代码段 ASSUME CS:CSEG,DS:DSEG;-Start PROC mov ax,DSEG mov ds,ax mov _wSSValueInRealMode,ss ;堆栈段 mov _wSPValueInRealMode,sp ;堆栈指针 ;准备要加载到GDTR的伪描述符 mov bx,16 mul bx add ax,OFFSET GDT ;计算并设置基地址 adc dx,0 ;界限已在定义时设置好
8、 mov WORD PTR VGDTR.Base,ax mov WORD PTR VGDTR.Base+2,dx ;准备要加载到IDTR的伪描述符 mov ax,SEG IDT mov bx,16 mul bx add ax,OFFSET IDT ;计算并设置基地址 adc dx,0 ;界限已在定义时设置好 mov WORD PTR VIDTR.Base,ax mov WORD PTR VIDTR.Base+2,dx ;设置代码段描述符 mov ax,cs mul bx mov WORD PTR Code.BaseL,ax ;代码段开始偏移为0 mov BYTE PTR Code.BaseM,
9、dl ;代码段界限已在定义时设置好 mov BYTE PTR Code.BaseH,dh mov ax,seg SpuriousHandler mul bx mov WORD PTR Code32.BaseL,ax ;代码段开始偏移为0 mov BYTE PTR Code32.BaseM,dl ;代码段界限已在定义时设置好 mov BYTE PTR Code32.BaseH,dh mov ax,8000h mov dx,000BH mov WORD PTR DataV.BaseL,ax mov BYTE PTR DataV.BaseM,dl mov BYTE PTR DataV.BaseH,d
10、h ;设置目标数据段描述符 mov ax,ds mul bx ;计算并设置目标数据段基址 mov WORD PTR DataP.BaseL,ax mov BYTE PTR DataP.BaseM,dl mov BYTE PTR DataP.BaseH,dh ; 保存中断屏蔽寄存器(IMREG)值 in al, 21h mov _SavedIMREG_M, al ;主片IMR=21h in al, 0A1h mov _SavedIMREG_S, al ;从片IMR=A1h ; 保存 IDTR sidt QWORD PTR _SavedIDTR ;加载GDTR lgdt QWORD PTR VGD
11、TR cli ;关中断 EnableA20 ;打开地址线A20 lidt QWORD PTR VIDTR ;加载IDT ;切换到保护方式 mov eax,cr0 or eax,1 mov cr0,eax ;清指令预取队列,并真正进入保护方式 JUMP16 Code_Sel,ALIGN 32Virtual: ;现在开始在保护方式下运行 mov ax,DataV_Sel mov gs,ax ;加载源数据段描述符 mov ax,DataP_Sel mov ds,ax ;加载源数据段描述符 mov ss,ax ; 堆栈段选择子 mov sp,offset TopOfStack call Init825
12、9A mov ah, 0Ch ; 0000 黑底 1100 红字 mov al, ! mov gs:(80 * 0 + 72) * 2), ax ; 屏幕第 0 行, 第 72 列。 ; x: jmp x int 080h sti mov ebx,0 xor ecx,ecxWaitLoop: ; cmp ebx, 100 ;jb WaitLoop cmp ecx,1 ;等到Esc jnz WaitLoop cli call SetRealmode8259A ;切换回实模式 mov eax,cr0 and al,11111110b mov cr0,eax ;清指令预取队列,进入实方式 JUMP1
13、6 ,; Init8259A -Init8259A: mov al, 011h out 020h, al ; 主8259, ICW1. call io_delay out 0A0h, al ; 从8259, ICW1. call io_delay mov al, 020h ; IRQ0 对应中断向量 0x20 out 021h, al ; 主8259, ICW2. call io_delay mov al, 028h ; IRQ8 对应中断向量 0x28 out 0A1h, al ; 从8259, ICW2. call io_delay mov al, 004h ; IR2 对应从8259 o
14、ut 021h, al ; 主8259, ICW3. call io_delay mov al, 002h ; 对应主8259的 IR2 out 0A1h, al ; 从8259, ICW3. call io_delay mov al, 001h out 021h, al ; 主8259, ICW4. call io_delay out 0A1h, al ; 从8259, ICW4. call io_delay mov al, 11111100b ; out 021h, al ; 主8259, OCW1. call io_delay mov al, 11111111b ; 屏蔽从8259所有中
15、断 out 0A1h, al ; 从8259, OCW1. call io_delay ret; Init8259A -; SetRealmode8259A -SetRealmode8259A: mov al, 011h out 020h, al ; 主8259, ICW1. call io_delay out 0A0h, al ; 从8259, ICW1. call io_delay mov al, 08h ; IRQ0 对应中断向量 0x20 out 021h, al ; 主8259, ICW2. call io_delay mov al, 70h ; IRQ8 对应中断向量 0x28 o
16、ut 0A1h, al ; 从8259, ICW2. call io_delay mov al, 004h ; IR2 对应从8259 out 021h, al ; 主8259, ICW3. call io_delay mov al, 002h ; 对应主8259的 IR2 out 0A1h, al ; 从8259, ICW3. call io_delay mov al, 001h out 021h, al ; 主8259, ICW4. call io_delay out 0A1h, al ; 从8259, ICW4. call io_delay mov al, 11111111b ; 屏蔽从
17、8259所有中断 out 0A1h, al ; 从8259, OCW1. call io_delay mov al, _SavedIMREG_M ; 恢复中断屏蔽寄存器(IMREG)的原值 out 021h, al ; call io_delay ;mov al, _SavedIMREG_S ; 恢复中断屏蔽寄存器(IMREG)的原值 ;out 0A1h, al ; ;call io_delay ret; SetRealmode8259A -io_delay: nop nop nop nop ret Real: ;现在又回到实方式 DisableA20 lidt QWORD PTR _Save
18、dIDTR mov ax,DSEG mov ds,ax mov ss,_wSSValueInRealMode mov sp,_wSPValueInRealMode sti mov ax,4c00h int 21hStart ENDP;-CSEG ENDS ;代码段定义结束;-CSEG32 SEGMENT USE32; interrupt handler -ASSUME CS:CSEG32,DS:DSEGClockHandler: inc ebx inc byte ptr gs:(80 * 0 + 70) * 2) ; 屏幕第 0 行, 第 70 列。 mov al, 20h out 20h,
19、al ; 发送 EOI iretdEscHandler: ; in al,60h cmp al,1 jnz Nesc mov ecx,1Nesc: inc byte ptr gs:(80*1+70)*2) mov al,20h out 20h,al iretdUserIntHandler: mov ah, 0Ch ; 0000 黑底 1100 红字 mov al, I mov gs:(80 * 0 + 71) * 2), ax ; 屏幕第 0 行, 第 71 列。 iretdSpuriousHandler: mov ah, 0Ch ; 0000 黑底 1100 红字 mov al, ! mov
20、 gs:(80 * 0 + 72) * 2), ax ; 屏幕第 0 行, 第 72 列。 iretd; -CSEG32 ENDS END Start此代码在原先老师所给的代码基础上做了如下的修改:IDT_21 Gate 1 dup () ;IDT_21_7F Gate 94 dup ()加入esc的中断处理EscHandler: in al,60h cmp al,1 jnz Nesc mov ecx,1Nesc: inc byte ptr gs:(80*1+70)*2) mov al,20h out 20h,al ; 发送 EOI iretd如果键入非esc建则在第二行加一显示字符五 实验结果刚开始运行时在屏幕的第一行第70列字符ASCLL码加一并显示,实现字符的跳动.当输入非esc键时在屏幕的第二行第70列字符ASCLL码加一并显示当输入esc键时退出循环.六 心得体会1、键入非ESC键时,运行时发现按下一次后ascll码却加了2,因为程序中设计成非esc键入就加一,因此是键盘按下时发出一个信号,键盘弹回时又发出一个信号,致使ASCLL码加了两次.2、通过实验对8259的初始化有了新的认识,对两片8259A的级联有了具体的了解.3、又重新翻了一遍接口的教材,对全局描述符表GDT,中断
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1