为什么不能正确处理中断?

ryman 2007-10-05 07:30:46
参考80x86汇编语言程序设计教程,写了一个在保护模式下处理用户自定义中断80的程序,为什么INT 80后,会导致DOS崩溃呢?谢谢。
JUMP MACRO selector, offsetv
db 0eaH
dw offsetv
dw selector
ENDM

DEBUGPRINT MACRO ascii
mov ax, 0b800h
mov es, ax
mov di, (80 * 10 + 0) * 2
mov ah, 0Ch
mov al, ascii
mov word ptr es:[di], ax
ENDM

DESCRIPTOR STRUC
LIMITL DW 0
BASEL DW 0
BASEM DB 0
ATTRIBUTES DW 0
BASEH DB 0
DESCRIPTOR ENDS

INTERRUPTGATE STRUC
OFFSETL DW 0
SELECTOR DW 0
ATTRIBUTES DW 0
OFFSETH DW 0
INTERRUPTGATE ENDS

PDESC STRUC
LIMIT DW 0
BASE DD 0
PDESC ENDS

ATDW = 92H
ATDWA = 93H
ATCE = 98H

.386p
DSEG SEGMENT USE16
GDT LABEL BYTE
DUMMY DESCRIPTOR <>
CODE DESCRIPTOR <0FFFFH,,,ATCE,>
CODE_SEL = CODE - GDT
DATAS DESCRIPTOR <0FFFFH,0H,11H,ATDW,0>
DATAS_SEL = DATAS - GDT
DATAD DESCRIPTOR <0FFFFH,,,ATDW,>
DATAD_SEL = DATAD - GDT
VIDEO DESCRIPTOR <0FFFFH,8000h,0bh,ATDW,>
VIDEO_SEL = VIDEO - GDT
STACKS DESCRIPTOR <TopOfStack,,,ATDWA,>
STACK_SEL = STACKS - GDT
GDTLEN = $ - GDT

IDT LABEL BYTE
REPT 50h
INTERRUPTGATE <OFFSET CLOCKHANDLER,CODE_SEL,4600h,0>
ENDM
INTERRUPTGATE <OFFSET USERHANDLER,CODE_SEL,4600h,0>
IDTLEN = $ - IDT

VGDTR PDESC <GDTLEN-1,>
VIDTR PDESC <IDTLEN-1,>

BUFFERLEN = 256
BUFFER DB BUFFERLEN DUP(0)
DSEG ENDS

SSEG SEGMENT PARA STACK
LABEL_STACK LABEL BYTE
DB 256 DUP(0)
TopOfStack equ $ - LABEL_STACK - 1
SSEG ENDS

CSEG SEGMENT USE16
ASSUME CS:CSEG, DS:DSEG, SS:SSEG
START:
MOV AX, DSEG
MOV DS, AX

MOV BX, 16
MUL BX
ADD AX, OFFSET GDT
ADC DX, 0
MOV WORD PTR VGDTR.BASE, AX
MOV WORD PTR VGDTR.BASE+2, DX

MOV AX, CS
MUL BX
MOV CODE.BASEL, AX
MOV CODE.BASEM, DL
MOV CODE.BASEH, DH

MOV AX, SS
MUL BX
MOV STACKS.BASEL, AX
MOV STACKS.BASEM, DL
MOV STACKS.BASEH, DH

MOV AX, DS
MUL BX
ADD AX, OFFSET BUFFER
ADC DX, 0
MOV DATAD.BASEL, AX
MOV DATAD.BASEM, DL
MOV DATAD.BASEH, DH

;init idtr
MOV AX, DS
MUL BX
ADD AX, OFFSET IDT
ADC DX, 0
MOV WORD PTR VIDTR.BASE, AX
MOV WORD PTR VIDTR.BASE+2, DX

mov ax, 0b800h
mov es, ax
mov di, (80 * 10 + 0) * 2
mov ah, 0Ch
mov al, 'R'
mov word ptr es:[di], ax

LGDT FWORD PTR VGDTR
CLI
LIDT FWORD PTR VIDTR

CALL ENABLEA20

MOV EAX, CR0
OR EAX, 1
MOV CR0, EAX
JUMP <CODE_SEL>, <OFFSET VIRTUAL>

VIRTUAL:
mov ax, STACK_SEL
mov ss, ax
mov sp, TopOfStack
mov ax, VIDEO_SEL
mov es, ax
mov edi, (80 * 11 + 0) * 2
mov ah, 0Ch
mov al, 'P'
mov word ptr es:[edi], ax

CALL Init8259A
STI
INT 50H ; deadloop here
JMP $

MOV EAX, CR0
AND EAX, 0FFFFFFFEH
MOV CR0, EAX

JUMP <SEG REAL>, <OFFSET REAL>
REAL:
CALL DISABLEA20
STI

mov ax, 0b800h
mov es, ax
mov di, (80 * 12 + 0) * 2
mov ah, 0Ch
mov al, 'B'
mov word ptr es:[di], ax

MOV AX, 4C00H
INT 21H

TOASCII PROC


TOASCII ENDP

ENABLEA20 PROC
PUSH AX
IN AL, 92H
OR AL, 2
OUT 92H, AL
POP AX
RET
ENABLEA20 ENDP

DISABLEA20 PROC
PUSH AX
IN AL, 92H
AND AL, 0FDH
OUT 92H, AL
POP AX
RET
DISABLEA20 ENDP

CLOCKHANDLER PROC
mov ax, VIDEO_SEL
mov es, ax
inc byte ptr es:[(80 * 0 + 70) * 2]
mov al, 20h
out 20h, al ; ·¢ËÍ EOI
iret
CLOCKHANDLER ENDP

USERHANDLER PROC
mov ax, VIDEO_SEL
mov es, ax
mov edi, (80 * 11 + 0) * 2
mov ah, 0Ch
mov al, 'U'
mov word ptr es:[edi], ax
mov al, 20h
out 20h, al ; ·¢ËÍ EOI
iret
USERHANDLER ENDP

io_delay PROC
nop
nop
nop
nop
ret
io_delay ENDP

Init8259A PROC
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
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, 11111110b ; ½ö½ö¿ªÆô¶¨Ê±Æ÷ÖжÏ
mov al, 11111111b
out 021h, al ; Ö÷8259, OCW1.
call io_delay

mov al, 11111111b ; ÆÁ±Î´Ó8259ËùÓÐÖжÏ
out 0A1h, al ; ´Ó8259, OCW1.
call io_delay

ret
Init8259A ENDP

CSEG ENDS
END START
...全文
78 1 打赏 收藏 转发到动态 举报
写回复
用AI写文章
1 条回复
切换为时间正序
请发表友善的回复…
发表回复
ryman 2007-10-05
  • 打赏
  • 举报
回复
我在INT 50H后面加了jmp $,想看看中断执行的效果。

21,458

社区成员

发帖
与我相关
我的任务
社区描述
汇编语言(Assembly Language)是任何一种用于电子计算机、微处理器、微控制器或其他可编程器件的低级语言,亦称为符号语言。
社区管理员
  • 汇编语言
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧