I have submitted my bug report associated with Bochs at the following link:
And write a program to support my opinion. But the developers seem to
can still cause int 0x08 or int 0x0F to happen. I really wonder why they
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