首页 > 应用开发 > IT综合 > 演示中断处理的实例(实例六)(转)
;名称:ASM6.ASM;功能:演示中断处理的实现;编译:TASM ASM6.ASM;连接:TLINK ASM6.OBJ;----------------------------------------------------------------------------INCLUDE 386SCD.INC;----------------------------------------------------------------------------;部分常量定义;----------------------------------------------------------------------------EOICOM = 20h ;外部中断处理结束命令ICREGP = 20h ;中断控制寄存器端口地址IMREGP = 21h ;中断屏蔽寄存器端口地址;----------------------------------------------------------------------------GDTSeg SEGMENT PARA USE16 ;全局描述符表数据段(16位);---------------------------------------------------------------------------- ;全局描述符表GDTGDT LABEL BYTE ;空描述符DUMMY Desc <> ;规范段描述符Normal Desc <0ffffh,,,ATDW,,> ;视频缓冲区段描述符(DPL=3)VideoBuf Desc <0ffffh,8000h,0bh,ATDW,,>;----------------------------------------------------------------------------EFFGDT LABEL BYTE ;临时代码段描述符TempCode Desc <0ffffh,TempCodeSeg,,ATCE,,> ;演示代码段描述符DemoCode Desc <DemoCodeLen-1,DemoCodeSeg,,ATCE,,> ;演示数据段描述符DemoData Desc <DemoDataLen-1,DemoDataSeg,,ATDW,,> ;演示堆栈段描述符DemoStack Desc <DemoStackLen-1,DemoStackSeg,,ATDWA,,> ;0feh号中断处理程序(显示程序)代码段描述符EchoCode Desc <EchoCodeLen-1,EchoCodeSeg,,ATCE,,> ;0feh号中断处理程序(显示程序)数据段描述符EchoData Desc <EchoDataLen-1,EchoDataSeg,,ATDW,,> ;8号中断处理程序代码段描述符TICode Desc <TICodeLen-1,TICodeSeg,,ATCE,,> ;8号中断处理程序数据段描述符TIData Desc <TIDataLen-1,TIDataSeg,,ATDW,,> ;其它中断或异常处理程序代码段描述符Other Desc <OtherCodeLen-1,OtherCodeSeg,,ATCE,,>;----------------------------------------------------------------------------GDTLen = $-GDT ;全局描述符表长度GDNum = ($-EFFGDT)/(SIZE Desc) ;需特殊处理的描述符数;----------------------------------------------------------------------------Normal_Sel = Normal-GDT ;规范段描述符选择子Video_Sel = VideoBuf-GDT ;视频缓冲区段描述符选择子;----------------------------------------------------------------------------TempCode_Sel = TempCode-GDT ;临时代码段的选择子DemoCode_Sel = DemoCode-GDT ;演示代码段的选择子DemoData_Sel = DemoData-GDT ;演示数据段的选择子DemoStack_Sel = DemoStack-GDT ;演示堆栈段的选择子EchoCode_Sel = EchoCode-GDT ;0feh号中断程序代码段选择子EchoData_Sel = EchoData-GDT ;0feh号中断程序数据段选择子TICode_Sel = TICode-GDT ;8号中断程序代码段选择子TIData_Sel = TIData-GDT ;8号中断程序数据段选择子Other_Sel = Other-GDT ;其它中断或异常代码段选择子;----------------------------------------------------------------------------GDTSeg ENDS ;全局描述符表段定义结束;----------------------------------------------------------------------------IDTSeg SEGMENT PARA USE16 ;中断描述符表数据段(16位);----------------------------------------------------------------------------IDT LABEL BYTE ;中断描述符表 ;0--7的8个陷阱门描述符 REPT 8 Gate <OtherBegin,Other_Sel,,AT386TGate,> ENDM ;对应8号(时钟)中断处理程序的门描述符 Gate <TIBegin,TICode_Sel,,AT386IGate,> ;从9--0fdh的245个陷阱门描述符 REPT 245 Gate <OtherBegin,Other_Sel,,AT386TGate,> ENDM ;对应0feh号中断处理程序的陷阱门描述符 Gate <EchoBegin,EchoCode_Sel,,AT386TGate,> ;对应0ffh号中断处理程序的陷阱门描述符 Gate <OtherBegin,Other_Sel,,AT386TGate,>;----------------------------------------------------------------------------IDTLen = $-IDT;----------------------------------------------------------------------------IDTSeg ENDS ;中断描述符表段定义结束;----------------------------------------------------------------------------;其它中断或异常处理程序的代码段;----------------------------------------------------------------------------OtherCodeSeg SEGMENT PARA USE16 ASSUME CS:OtherCodeSeg;----------------------------------------------------------------------------OtherBegin PROC FAR mov ax,Video_Sel mov es,ax mov ah,17h ;在屏幕左上角显示兰底白字 mov al,'!' ;符号"!" mov WORD PTR es:[0],ax jmp $ ;无限循环OtherBegin ENDP;----------------------------------------------------------------------------OtherCodeLen = $OtherCodeSeg ENDS;----------------------------------------------------------------------------;8号中断处理程序的数据段;----------------------------------------------------------------------------TIDataSeg SEGMENT PARA USE16Count DB 0 ;中断发生的计数器TIDataLen = $TIDataSeg ENDS;----------------------------------------------------------------------------;8号中断处理程序的代码段;----------------------------------------------------------------------------TICodeSeg SEGMENT PARA USE16 ASSUME CS:TICodeSeg,DS:TIDataSeg;----------------------------------------------------------------------------TIBegin PROC FAR push eax ;保护现场 push ds push fs push gs mov ax,TIData_Sel ;置中断处理程序数据段 mov ds,ax mov ax,EchoData_Sel ;置显示过程数据段 mov fs,ax mov ax,DemoData_Sel ;置演示程序数据段 mov gs,ax cmp Count,0 jnz TI2 ;计数非0表示未到1秒 mov Count,18 ;每秒约18次 int 0feh ;调用0FEH号中断处理程序显示 cmp BYTE PTR fs:Mess,'0' jnz TI1 mov BYTE PTR gs:Flag,1 ;显示符号'0'时置标记TI1: dec BYTE PTR fs:Mess ;调整显示符号TI2: dec Count ;调整计数 pop gs ;恢复现场 pop fs pop ds mov al,EOICOM ;通知中断控制器中断处理结束 out ICREGP,al pop eax iretd ;中断返回TIBegin ENDP;----------------------------------------------------------------------------TICodeLen = $TICodeSeg ENDS;----------------------------------------------------------------------------;0FEH号中断处理程序数据段;----------------------------------------------------------------------------EchoDataSeg SEGMENT PARA USE16Mess DB '8',4ehEchoDataLen = $EchoDataSeg ENDS;----------------------------------------------------------------------------;0FEH号中断处理程序(显示程序)的代码段;----------------------------------------------------------------------------EchoCodeSeg SEGMENT PARA USE16 ASSUME CS:EchoCodeSeg,DS:EchoDataSeg;----------------------------------------------------------------------------EchoBegin PROC FAR push ax ;保护现场 push ds push es mov ax,EchoData_Sel ;置显示过程数据段 mov ds,ax mov ax,Video_Sel ;置视频缓冲区数据段 mov es,ax mov ax,WORD PTR Mess mov WORD PTR es:[0],ax pop es pop ds pop ax iretdEchoBegin ENDP;----------------------------------------------------------------------------EchoCodeLen = $EchoCodeSeg ENDS;----------------------------------------------------------------------------;演示任务的堆栈段;----------------------------------------------------------------------------DemoStackSeg SEGMENT PARA USE16DemoStackLen = 1024 DB DemoStackLen DUP(0)DemoStackSeg ENDS;----------------------------------------------------------------------------;演示任务的数据段;----------------------------------------------------------------------------DemoDataSeg SEGMENT PARA USE16Flag DB 0DemoDataLen = $DemoDataSeg ENDS;----------------------------------------------------------------------------;演示任务的代码段;----------------------------------------------------------------------------DemoCodeSeg SEGMENT PARA USE16 ASSUME CS:DemoCodeSeg,DS:DemoDataSeg;----------------------------------------------------------------------------DemoBegin PROC FAR mov ax,DemoStack_Sel ;置堆栈 mov ss,ax mov sp,DemoStackLen ;置数据段 mov ax,DemoData_Sel mov ds,ax mov es,ax mov fs,ax mov gs,ax mov al,11111110b ;置中断屏蔽字 out IMREGP,al ;只开发时钟中断 sti ;开中断DemoConti: cmp BYTE PTR Flag,0 ;判标志 jz DemoConti ;直到不为0 cli ;关中断 ;转回临时代码段,准备回实方式 JUMP16 TempCode_Sel,<OFFSET ToDos>DemoBegin ENDP;----------------------------------------------------------------------------DemoCodeLen = $DemoCodeSeg ENDS;----------------------------------------------------------------------------TempCodeSeg SEGMENT PARA USE16 ;临时任务的代码段 ASSUME CS:TempCodeSeg;----------------------------------------------------------------------------Virtual PROC FAR JUMP16 DemoCode_Sel,DemoBegin ;转演示任务ToDos: mov ax,Normal_Sel ;恢复实方式段描述符高速缓存 mov ds,ax mov es,ax mov fs,ax mov gs,ax mov ss,ax mov eax,cr0 ;准备返回实模式 and al,11111110b mov cr0,eax JUMP16 <SEG Real>,<OFFSET Real>Virtual ENDP;----------------------------------------------------------------------------TempCodeSeg ENDS;============================================================================RDataSeg SEGMENT PARA USE16 ;实方式数据段VGDTR PDesc <GDTLen-1,> ;GDT伪描述符VIDTR PDesc <IDTLen-1,> ;IDT伪描述符NORVIDTR PDesc <3ffh,> ;用于保存原IDTR值SPVar DW ? ;用于保存实方式下的SPSSVar DW ? ;用于保存实方式下的SSIMaskRegV DB ? ;用于保存原中断屏蔽寄存器值RDataSeg ENDS;----------------------------------------------------------------------------RCodeSeg SEGMENT PARA USE16 ;实方式代码段 ASSUME CS:RCodeSeg,DS:RDataSeg;----------------------------------------------------------------------------Start PROC mov ax,RDataSeg mov ds,ax cld call InitGDT ;初始化全局描述符表GDT call InitIDT ;初始化中断描述符表IDT mov SSVar,ss ;保存堆栈指针 mov SPVar,sp sidt QWORD PTR NORVIDTR ;保存IDTR in al,IMREGP mov BYTE PTR IMaskRegV,al lgdt QWORD PTR VGDTR ;装载GDTR cli ;关中断 lidt QWORD PTR VIDTR ;装载IDTR mov eax,cr0 or al,1 mov cr0,eax JUMP16 <TempCode_Sel>,<OFFSET Virtual>Real: mov ax,RDataSeg mov ds,ax lss sp,DWORD PTR SPVar ;又回到实方式 lidt QWORD PTR NORVIDTR mov al,IMaskRegV out IMREGP,al sti mov ax,4c00h int 21hStart ENDP;----------------------------------------------------------------------------InitGDT PROC push ds mov ax,GDTSeg mov ds,ax mov cx,GDNum mov si,OFFSET EFFGDTInitG: mov ax,[si].BaseL movzx eax,ax shl eax,4 shld edx,eax,16 mov WORD PTR [si].BaseL,ax mov BYTE PTR [si].BaseM,dl mov BYTE PTR [si].BaseH,dh add si,SIZE Desc loop InitG pop ds mov bx,16 mov ax,GDTSeg mul bx mov WORD PTR VGDTR.Base,ax mov WORD PTR VGDTR.Base+2,dx retInitGDT ENDP;----------------------------------------------------------------------------InitIDT PROC mov bx,16 mov ax,IDTSeg mul bx mov WORD PTR VIDTR.Base,ax mov WORD PTR VIDTR.Base+2,dx retInitIDT ENDP;----------------------------------------------------------------------------RCodeSeg ENDS END Start
sidt QWORD PTR NORVIDTR
lidt QWORD PTR VIDTR lidt QWORD PTR NORVIDTR
来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/10172717/viewspace-928727/ ,如需转载,请注明出处,否则将追究法律责任。