微机接口技术实验.docx
- 文档编号:3933682
- 上传时间:2022-11-26
- 格式:DOCX
- 页数:15
- 大小:147.13KB
微机接口技术实验.docx
《微机接口技术实验.docx》由会员分享,可在线阅读,更多相关《微机接口技术实验.docx(15页珍藏版)》请在冰豆网上搜索。
微机接口技术实验
微机接口技术实验
实验五保护模式下的中断处理
姓名:
胡诣嵩
学号:
20053449
日期:
2008-5-30
一实验名称
保护模式下的中断处理
二实验目的
1.通过本实验了解、熟悉保护模式下的中断以及它的处理方式。
2.巩固微机接口课程学习的80386DX在保护模式下相关的知识点。
三简述程序执行过程
1、作切换到保护方式的准备
2、切换到保护方式
3、程序循环等待,当有键盘和时钟中断时,调用中断服务程序显示字符
4、切换回实模式
四实验源程序
;功能:
演示保护方式下的中断处理过程
.386P
;----------------------------------------------------------------------------
;存储段描述符结构类型定义
;----------------------------------------------------------------------------
DescSTRUC
LimitLDW0;段界限(BIT0-15)
BaseLDW0;段基地址(BIT0-15)
BaseMDB0;段基地址(BIT16-23)
AttributesDB0;段属性
LimitHDB0;段界限(BIT16-19)(含段属性的高4位)
BaseHDB0;段基地址(BIT24-31)
DescENDS
;----------------------------------------------------------------------------
;伪描述符结构类型定义(用于装入全局或中断描述符表寄存器)
;----------------------------------------------------------------------------
PDescSTRUC
LimitDW0;16位界限
BaseDD0;32位基地址
PDescENDS
;----------------------------------------------------------------------------
;门描述符结构类型定义
;----------------------------------------------------------------------------
GateSTRUC
OffsetLDW0;32位偏移的低16位
SelectorDW0;选择子
DCountDB0;双字计数
GTypeDB0;类型
OffsetHDW0;32位偏移的高16位
GateENDS
;----------------------------------------------------------------------------
;存储段描述符类型值说明
;----------------------------------------------------------------------------
ATDREQU90h;存在的只读数据段类型值
ATDWEQU92h;存在的可读写数据段属性值
ATDWAEQU93h;存在的已访问可读写数据段类型值
ATCEEQU98h;存在的只执行代码段属性值
ATCEREQU9ah;存在的可执行可读代码段属性值
ATCCOEQU9ch;存在的只执行一致代码段属性值
ATCCOREQU9eh;存在的可执行可读一致代码段属性值
DA_386IGateEQU8Eh;386中断门类型值
;----------------------------------------------------------------------------
DSEGSEGMENTUSE16;16位数据段
;----------------------------------------------------------------------------
_SavedIMREG_Mdb0;中断屏蔽寄存器值
_SavedIMREG_Sdb0;
DB512dup(0)
TopOfStackLABELBYTE
GDTLABELBYTE;全局描述符表
DUMMYDesc<>;空描述符
CodeDesc<0ffffh,,,ATCER,,>;代码段描述符
DataVDesc<0ffffh,,,ATDW,,>;源数据段描述符
DataPDesc<0ffffh,,,ATDWA,,>;目标数据段描述符
Code32Desc<0ffffh,,,ATCER,40h,>;代码段描述符
;----------------------------------------------------------------------------
GDTLen=$-GDT;全局描述符表长度
VGDTRPDesc
;----------------------------------------------------------------------------
Code_Sel=Code-GDT;代码段选择子
DataV_Sel=DataV-GDT;源数据段选择子
DataP_Sel=DataP-GDT;目标数据段选择子
Code32_Sel=Code32-GDT;目标数据段选择子
;----------------------------------------------------------------------------
;IDT
ALIGN32
IDTLABELBYTE
IDT_00_1FGate32dup(
IDT_20Gate1dup(
IDT_21Gate1dup(
IDT_21_7FGate94dup(
IDT_80Gate1dup(
IDTLen=$-IDT;中断描述符表长度
VIDTRPDesc
_wSSValueInRealModedw0
_wSPValueInRealModedw0
_SavedIDTRdd0;用于保存IDTR
dd0
;----------------------------------------------------------------------------
DSEGENDS;数据段定义结束
;----------------------------------------------------------------------------
;打开A20地址线
;----------------------------------------------------------------------------
EnableA20MACRO
pushax
inal,92h
oral,00000010b
out92h,al
popax
ENDM
;----------------------------------------------------------------------------
;关闭A20地址线
;----------------------------------------------------------------------------
DisableA20MACRO
pushax
inal,92h
andal,11111101b
out92h,al
popax
ENDM
;----------------------------------------------------------------------------
;16位偏移的段间直接转移指令的宏定义(在16位代码段中使用)
;----------------------------------------------------------------------------
JUMP16MACROSelector,Offset
DB0eah;操作码
DWOffset;16位偏移量
DWSelector;段值或段选择子
ENDM
;----------------------------------------------------------------------------
CSEGSEGMENTUSE16;16位代码段
ASSUMECS:
CSEG,DS:
DSEG
;----------------------------------------------------------------------------
StartPROC
movax,DSEG
movds,ax
mov_wSSValueInRealMode,ss;堆栈段
mov_wSPValueInRealMode,sp;堆栈指针
;准备要加载到GDTR的伪描述符
movbx,16
mulbx
addax,OFFSETGDT;计算并设置基地址
adcdx,0;界限已在定义时设置好
movWORDPTRVGDTR.Base,ax
movWORDPTRVGDTR.Base+2,dx
;准备要加载到IDTR的伪描述符
movax,SEGIDT
movbx,16
mulbx
addax,OFFSETIDT;计算并设置基地址
adcdx,0;界限已在定义时设置好
movWORDPTRVIDTR.Base,ax
movWORDPTRVIDTR.Base+2,dx
;设置代码段描述符
movax,cs
mulbx
movWORDPTRCode.BaseL,ax;代码段开始偏移为0
movBYTEPTRCode.BaseM,dl;代码段界限已在定义时设置好
movBYTEPTRCode.BaseH,dh
movax,segSpuriousHandler
mulbx
movWORDPTRCode32.BaseL,ax;代码段开始偏移为0
movBYTEPTRCode32.BaseM,dl;代码段界限已在定义时设置好
movBYTEPTRCode32.BaseH,dh
movax,8000h
movdx,000BH
movWORDPTRDataV.BaseL,ax
movBYTEPTRDataV.BaseM,dl
movBYTEPTRDataV.BaseH,dh
;设置目标数据段描述符
movax,ds
mulbx;计算并设置目标数据段基址
movWORDPTRDataP.BaseL,ax
movBYTEPTRDataP.BaseM,dl
movBYTEPTRDataP.BaseH,dh
;保存中断屏蔽寄存器(IMREG)值
inal,21h
mov_SavedIMREG_M,al;主片IMR=21h
inal,0A1h
mov_SavedIMREG_S,al;从片IMR=A1h
;保存IDTR
sidtQWORDPTR_SavedIDTR
;加载GDTR
lgdtQWORDPTRVGDTR
cli;关中断
EnableA20;打开地址线A20
lidtQWORDPTRVIDTR;加载IDT
;切换到保护方式
moveax,cr0
oreax,1
movcr0,eax
;清指令预取队列,并真正进入保护方式
JUMP16Code_Sel,
ALIGN32
Virtual:
;现在开始在保护方式下运行
movax,DataV_Sel
movgs,ax;加载源数据段描述符
movax,DataP_Sel
movds,ax;加载源数据段描述符
movss,ax;堆栈段选择子
movsp,offsetTopOfStack
callInit8259A
movah,0Ch;0000黑底1100红字
moval,'!
'
movgs:
[((80*0+72)*2)],ax;屏幕第0行,第72列。
;x:
jmpx
int080h
sti
movebx,0
xorecx,ecx
WaitLoop:
;cmpebx,100
;jbWaitLoop
cmpecx,1;等到Esc
jnzWaitLoop
cli
callSetRealmode8259A
;切换回实模式
moveax,cr0
andal,11111110b
movcr0,eax
;清指令预取队列,进入实方式
JUMP16
;Init8259A---------------------------------------------------------------------------------------------
Init8259A:
moval,011h
out020h,al;主8259,ICW1.
callio_delay
out0A0h,al;从8259,ICW1.
callio_delay
moval,020h;IRQ0对应中断向量0x20
out021h,al;主8259,ICW2.
callio_delay
moval,028h;IRQ8对应中断向量0x28
out0A1h,al;从8259,ICW2.
callio_delay
moval,004h;IR2对应从8259
out021h,al;主8259,ICW3.
callio_delay
moval,002h;对应主8259的IR2
out0A1h,al;从8259,ICW3.
callio_delay
moval,001h
out021h,al;主8259,ICW4.
callio_delay
out0A1h,al;从8259,ICW4.
callio_delay
moval,11111100b;<同时开启定时器和键盘中断>
out021h,al;主8259,OCW1.
callio_delay
moval,11111111b;屏蔽从8259所有中断
out0A1h,al;从8259,OCW1.
callio_delay
ret
;Init8259A---------------------------------------------------------------------------------------------
;SetRealmode8259A---------------------------------------------------------------------------------------------
SetRealmode8259A:
moval,011h
out020h,al;主8259,ICW1.
callio_delay
out0A0h,al;从8259,ICW1.
callio_delay
moval,08h;IRQ0对应中断向量0x20
out021h,al;主8259,ICW2.
callio_delay
moval,70h;IRQ8对应中断向量0x28
out0A1h,al;从8259,ICW2.
callio_delay
moval,004h;IR2对应从8259
out021h,al;主8259,ICW3.
callio_delay
moval,002h;对应主8259的IR2
out0A1h,al;从8259,ICW3.
callio_delay
moval,001h
out021h,al;主8259,ICW4.
callio_delay
out0A1h,al;从8259,ICW4.
callio_delay
moval,11111111b;屏蔽从8259所有中断
out0A1h,al;从8259,OCW1.
callio_delay
moval,_SavedIMREG_M;恢复中断屏蔽寄存器(IMREG)的原值
out021h,al;
callio_delay
;moval,_SavedIMREG_S;恢复中断屏蔽寄存器(IMREG)的原值
;out0A1h,al;
;callio_delay
ret
;SetRealmode8259A---------------------------------------------------------------------------------------------
io_delay:
nop
nop
nop
nop
ret
Real:
;现在又回到实方式
DisableA20
lidtQWORDPTR_SavedIDTR
movax,DSEG
movds,ax
movss,_wSSValueInRealMode
movsp,_wSPValueInRealMode
sti
movax,4c00h
int21h
StartENDP
;----------------------------------------------------------------------------
CSEGENDS;代码段定义结束
;----------------------------------------------------------------------------
CSEG32SEGMENTUSE32
;interrupthandler---------------------------------------------------------------
ASSUMECS:
CSEG32,DS:
DSEG
ClockHandler:
incebx
incbyteptrgs:
[((80*0+70)*2)];屏幕第0行,第70列。
moval,20h
out20h,al;发送EOI
iretd
EscHandler:
;<键盘中断服务程序,用来在屏幕第1行,第70列显示响按键的不断跳动的字符>
inal,60h
cmpal,1
jnzNesc
movecx,1
Nesc:
incbyteptrgs:
[((80*1+70)*2)]
moval,20h
out20h,al
iretd
UserIntHandler:
movah,0Ch;0000黑底1100红字
moval,'I'
movgs:
[((80*0+71)*2)],ax;屏幕第0行,第71列。
iretd
SpuriousHandler:
movah,0Ch;0000黑底1100红字
moval,'!
'
movgs:
[((80*0+72)*2)],ax;屏幕第0行,第72列。
iretd
;---------------------------------------------------------------------------
CSEG32ENDS
ENDStart
此代码在原先老师所给的代码基础上做了如下的修改:
IDT_21Gate1dup(
IDT_21_7FGate94dup(
加入esc的中断处理
EscHandler:
inal,60h
cmpal,1
jnzNesc
movecx,1
Nesc:
incbyteptrgs:
[((80*1+70)*2)]
moval,20h
out20h,al;发送EOI
iretd
如果键入非esc建则在第二行加一显示字符
五实验结果
刚开始运行时
在屏幕的第一行第70列字符ASCLL码加一并显示,实现字符的跳动.
当输入非esc键时
在屏幕的第二行第70列字符ASCLL码加一并显示
当输入esc键时
退出循环.
六心得体会
1、键入非ESC键时,运行时发现按下一次后ascll码却加了2,因为程序中设计成非esc键入就加一,因此是键盘按下时发出一个信号,键盘弹回时又发出一个信号,致使ASCLL码加了两次.
2、通过实验对8259的初始化有了新的认识,对两片8259A的级联有了具体的了解.
3、又重新翻了一遍接口的教材,对全局描述符表GDT,中断
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 微机 接口 技术 实验