x86int.asm

来自「windows下汇编语言 学习汇编语言好助手」· 汇编 代码 · 共 210 行

ASM
210
字号
;**************************
;文件:X86Int.asm		  *
;功能:中断/异常处理例子  *
;**************************
.386p
TestIntNum equ 021H
JUMP16 MACRO selector,offsetv
	DB 0EAH
	DW offsetv
	DW selector
	ENDM
;----------------------       
Descriptor STRUC
	limitl     dw 0
	basel	   dw 0
	basem 	   db 0
	attrib	   dw 0
	baseh      db 0
Descriptor ENDS       
;----------------------       
Gate STRUC
	offsetl  dw 0
	selector dw 0
	dcount   db 0
	gtype    db 0
	offseth  dw 0
Gate ENDS
;===============================
Data Segment use16
	gdt0 Descriptor <>

	DataSel = $-gdt0
	DataDes Descriptor <0ffffh,,,92H,>
	
	CodeSel = $-gdt0
	CodeDes Descriptor <0ffffh,,,98H,>

	VideoSel = $-gdt0
	VideoDes Descriptor <0ffffh,8000H,0BH,92H,0>
		
	Stack0Sel = $-gdt0
	Stack0Des Descriptor <0,,,97H,>

	IntProcSel = $-gdt0
	IntProcDes Descriptor <0ffffh,,,98H,>
	
	GdtLen  = $-gdt0
	
	GdtPtr  dw GdtLen-1 
		dd 0
;++++++++++++++++++++++++++++++++++++++++++++++
    IdtTable label byte
    Off=offset IntProcBegin
	REPT 256
		Gate <Off,IntProcSel,0,0eeH,0>
                Off=Off+(All-IntProcBegin)/256
	ENDM
    IdtLen	= $-IdtTable
    IdtPtr	dw IdtLen-1
	   		dd 0
    OldIdt	dw 0
	   		dd 0
;++++++++++++++++++++++++++++++++++++++++++++++
	OldSPSS dw 0,0
    Mess db 'Interrupt Example: Int '
      M1 db '  ',0
   Digit db '0123456789ABCDEF'
Data ends
;=============================================
Stack0 Segment use16
	db 1024 dup (0)
Stack0 ends
;=============================================
IntProc Segment use16		;中断处理程序
	assume cs:IntProc
IntProcBegin:
    COUNT = 0
    REPT 256
	push word ptr COUNT
	push ax
	mov  ax,offset All
	jmp  ax
	COUNT = COUNT+1
    ENDM
All:
	pop  ax
	push bp
	mov  bp,sp
	pusha
	push ds
	push es
	mov  ax,DataSel
	mov  ds,ax
	mov  ax,VideoSel
	mov  es,ax
	mov  ax,[bp+2]
	and  ax,0FFH
	push ax
	mov  bx,offset Digit
	mov  si,offset M1
	and  ax,0fh
	xlat
	mov  [si+1],al
	pop  ax
	shr  al,4
	xlat
	mov  [si],al

	mov  si,offset Mess	;显示"Interrupt Example: Int xx
	mov  di,80*2*10
	cld
	mov  ah,1eh
Load:
	lodsb
	cmp  al,0
	jz   OK
	stosw
	jmp  Load
OK:
	pop  es
	pop  ds
	popa
	pop  bp
	add  sp,2
	iretd
IntProc ends
;=============================================
Code segment use16
	assume cs:code,ds:data
Start:				      
	xor eax,eax		;Gdt
	mov ax,Data
	mov ds,ax
	shl eax,4
	mov dword ptr [GdtPtr+2],eax    
	xor eax,eax		;初始化 Idt 
	mov ax,Data
	shl eax,4
        xor ebx,ebx
        mov bx,offset IdtTable
        add eax,ebx
	mov dword ptr [IdtPtr+2],eax
	xor eax,eax		;初始化数据段描述符
	mov ax,Data
	shl eax,4
	mov DataDes.basel,ax
	shr eax,16
	mov DataDes.basem,al
	mov DataDes.baseh,ah
	xor eax,eax		;初始化代码段描述符
	mov ax,Code
	shl eax,4
	mov CodeDes.basel,ax
	shr eax,16
	mov CodeDes.basem,al
	mov CodeDes.baseh,ah
	xor eax,eax		;初始化堆栈段描述符
	mov ax,Stack0
	shl eax,4
	mov Stack0Des.basel,ax
	shr eax,16
	mov Stack0Des.basem,al
	mov Stack0Des.baseh,ah
	xor eax,eax		;初始化中断处理段的描述符
	mov ax,IntProc
	shl eax,4
	mov IntProcDes.basel,ax
	shr eax,16
	mov IntProcDes.basem,al
	mov IntProcDes.baseh,ah

	lgdt qword ptr GdtPtr	;载入 GDTR
	cli
	sidt qword ptr OldIdt	;保存 IDTR
	lidt qword ptr IdtPtr	;载入 IDTR
	mov  OldSPSS,sp
	mov  [OldSPSS+2],ss
	mov  eax,cr0		;转入保护模式
	or   eax,1
	mov  cr0,eax
	JUMP16 CodeSEL,<offset Protect>
Protect:
	mov ax,DataSel
	mov ds,ax
	mov fs,ax
	mov gs,ax
	mov ax,Stack0Sel
	mov ss,ax
	mov sp,1024
	mov ax,VideoSel
	mov es,ax

	int TestIntNum		;产生中断
ReadyToReal:			;返回实模式
	mov eax,cr0
	and eax,0fffffffeh
	mov cr0,eax
	JUMP16 <seg Real>,<offset Real>	
Real:
	mov  ax,Data
	mov  ds,ax
	mov  es,ax
	lss  sp,dword ptr OldSPSS
	lidt qword ptr OldIdt
	sti
	mov ax,4c00h
	int 21h
Code ends
        end Start

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?