BlackWhite |
03-19-2021 22:53 |
Can the bit0 mask in port 0x21 stop generating int 0x08?
I have submitted my bug report associated with Bochs at the following link:
https://sourceforge.net/p/bochs/patches/558/
And write a program to support my opinion. But the developers seem to
believe that when int 0x08 is masked in port 0x21, an STI instruction
can still cause int 0x08 or int 0x0F to happen. I really wonder why they
insist on PIC's generating interrupt even the associated mask is set in
port 0x21?
Here is my code to reveal the bug in Bochs:
Code:
;--------------------------------------------
;This program is written by iceman@zju.edu.cn
;and is for the purpose of revealing the bug
;in Bochs.
;--------------------------------------------
code segment
assume cs:code, ds:code
old_01h dw 0, 0
old_08h dw 0, 0
old_09h dw 0, 0
old_0Ah dw 0, 0
old_0Fh dw 0, 0
stop db 0
y dw 0; y-coordiate for current output
int_08h_msg db "int_08h occurred!", 0
int_0Ah_msg db "int_0Ah occurred!", 0
int_0Fh_msg db "int_0Fh occurred!", 0
begin_msg db "Press Esc to stop", 0
esc_msg db "Esc is pressed.", 0
end_msg db "Done!", 0
old_mask db 0; original mask in port 21h
save_set_interrupts proc
push es
push bx
xor bx, bx
mov es, bx
mov bx, 1*4
mov ax, es:[bx]
mov dx, es:[bx+2]
mov old_01h[0], ax; save int_01h's interrupt vector
mov old_01h[2], dx;
mov word ptr es:[bx], offset int_01h
mov es:[bx+2], cs ; set int_01h's interrupt vector
;
mov bx, 8*4
mov ax, es:[bx]
mov dx, es:[bx+2]
mov old_08h[0], ax; save int_08h's interrupt vector
mov old_08h[2], dx;
mov word ptr es:[bx], offset int_08h
mov es:[bx+2], cs ; set int_08h's interrupt vector
;
mov bx, 9*4
mov ax, es:[bx]
mov dx, es:[bx+2]
mov old_09h[0], ax; save int_09h's interrupt vector
mov old_09h[2], dx;
mov word ptr es:[bx], offset int_09h
mov es:[bx+2], cs ; set int_09h's interrupt vector
;
mov bx, 0Ah*4
mov ax, es:[bx]
mov dx, es:[bx+2]
mov old_0Ah[0], ax; save int_0Ah's interrupt vector
mov old_0Ah[2], dx;
mov word ptr es:[bx], offset int_0Ah
mov es:[bx+2], cs ; set int_0Ah's interrupt vector
;
mov bx, 0Fh*4
mov ax, es:[bx]
mov dx, es:[bx+2]
mov old_0Fh[0], ax; save int_0Fh's interrupt vector
mov old_0Fh[2], dx;
mov word ptr es:[bx], offset int_0Fh
mov es:[bx+2], cs ; set int_0Fh's interrupt vector
pop bx
pop es
ret
save_set_interrupts endp
recover_interrupts proc
push es
push bx
xor bx, bx
mov es, bx
mov bx, 1*4
mov ax, old_01h[0]
mov dx, old_01h[2]
mov es:[bx], ax
mov es:[bx+2], dx ; recover int_01h's interrupt vector
;
mov bx, 8*4
mov ax, old_08h[0]
mov dx, old_08h[2]
mov es:[bx], ax
mov es:[bx+2], dx ; recover int_08h's interrupt vector
;
mov bx, 9*4
mov ax, old_09h[0]
mov dx, old_09h[2]
mov es:[bx], ax
mov es:[bx+2], dx ; recover int_09h's interrupt vector
;
mov bx, 0Ah*4
mov ax, old_0Ah[0]
mov dx, old_0Ah[2]
mov es:[bx], ax
mov es:[bx+2], dx ; recover int_0Ah's interrupt vector
;
mov bx, 0Fh*4
mov ax, old_0Fh[0]
mov dx, old_0Fh[2]
mov es:[bx], ax
mov es:[bx+2], dx ; recover int_0Fh's interrupt vector
;
pop bx
pop es
ret
recover_interrupts endp
output proc
push ds
push es
push si
push di
push ax
push dx
;
push cs
pop ds
mov si, ax; ds:si->msg
mov ax, 0B800h
mov es, ax
mov ax, 80*2
mul cs:[y]
mov di, ax; es:di->text on the screen
output_next_char:
lodsb
or al, al
jz output_done
stosb
mov al, 17h; background color=blue, foreground color=white
stosb
jmp output_next_char
output_done:
inc cs:[y]
cmp cs:[y], 25
jne screen_not_full
mov cs:[y], 0
screen_not_full:
pop dx
pop ax
pop di
pop si
pop es
pop ds
ret
output endp
int_01h:
;When this ISR is entered, TF & IF will be cleared automatically.
push ax
push cx
mov al, 00h
out 21h, al ; First we unmask all interrupts
;
mov cx, 20h
next_while:
push cx
xor cx, cx
a_while:
loop a_while
pop cx
loop next_while
; wait a while for the timer
mov al, 0F9h; mask all interrupts except int_09h & int_0Ah
out 21h, al
sti ; The unfixed Bochs will generate an int_08h interrupt
; immediately after STI is executed, while Ruppert's
; patching will generate an int_0Fh interrupt instead of
; int_08h. But on a physical machine, neither int_08h
; nor int_0Fh will be generated.
wait_key_press:
cmp cs:[stop], 1
nop
jne wait_key_press
mov ax, offset esc_msg
call output
mov cs:[stop], 0; reset it for next int_01h
pop cx
pop ax
iret
int_08h:
push ax
mov ax, offset int_08h_msg
call output
mov al, 20h
out 20h, al
pop ax
iret
int_09h:
push ax
in al, 60h; read key
cmp al, 1
jne not_esc_key
mov cs:[stop], 1; set the signal to stop int_01h
not_esc_key:
mov al, 20h
out 20h, al; send EOI to PIC
pop ax
iret
int_0Ah:
push ax
mov ax, offset int_0Ah_msg
call output
mov al, 20h
out 20h, al
pop ax
iret
int_0Fh:
push ax
mov ax, offset int_0Fh_msg
call output
mov al, 20h
out 20h, al
pop ax
iret
main:
cli
cld
push cs
pop ds
in al, 21h
mov old_mask, al; save mask in port 21h
;
mov ax, offset begin_msg
call output
;
call save_set_interrupts
;
pushf; backup FL
;
pushf
pop ax
or ax, 0100h; TF=1
push ax
popf
nop ; There will be an int_01h after this nop.
;int_01h
popf ; recover FL, TF=0
;int_01h
nop
;no more int_01h
cli
call recover_interrupts
sti
mov ax, offset end_msg
call output
mov al, old_mask
out 21h, al; recover mask in port 21h
mov ah, 4Ch
int 21h
code ends
end main
|