Dawaffleman
asked on
Hooking int 9h help
i need some help with my keyboard assembly interrupt 9h hooking procedure.I have a lot of experiance with assembler but not with hooking ints. im writing a music synth program that uses the keyboard as an interface. i tried to write a int 9h hook program, but it wouldnt work properly. every time i run it i get a new error. usually this ends up giving me a dos error, or the program goes into an endless loop that i cannot stop. i am using tasm v4.1... here is my code:
.model medium
.386
.stack 200h
.data ;data segment
down db "down$" ; down message
up db "up$" ;up message
ol9 dd ? old int 9h vector
escape db 0h ;escape flag
.code ;code segment
;------------------------- -new int 9 procedure----------------- ------
new9 proc
in al,60h ;get keyboard port status
cmp al,1h ;check if esc pressed
je esc1
cmp al,48h ;check if up scan code
je upsub ;yes goto up sub
cmp al,50h ;check if down scancode is pressed
je downsub ;if yes goto down sub
endofint: ;end interrupt routine
in al,61 ;this does something with a key release code?
mov ah,al ; not sure of what this does exactly
or al,80h ; i know it writes something to the keybrd port
out 61h,al ; but i dont know what or why
mov al,ah ;it just seems everyone uses this for thier hooking routines
out 61h,al
mov al,29h
out 20h,al ;i know this is the end of interrupt signal
iret ; i know this pops the cs:ip and flags, but i dont know where to put it
jmp endproc
upsub: ;prints up to the screen
pusha ;preseve regs
mov ax,seg up
mov ds,ax
mov dx,offset up
mov ax,0900h
int 21h
popa ;restore regs
jmp endofint
downsub: ;prints up to the screen
pusha ;preseve regs
mov ax,seg down
mov ds,ax
mov dx,offset down
mov ax,0900h
int 21h
popa ;restore regs
jmp endofint
esc1:
mov escape,1h ;set escape flag if pressed
jmp endofint
endproc:
jmp dword ptr cs:old9 ;jumps to old interrupt 9h
clrbuf: ;clear keyboard buffer
mov ah,01h
int 16h
jz bufclr
mov ah,00h
int 16h
jmp clrbuf
bufclr:
iret
endp
;------------------------- ---------- end of new int 9 procedure----------------
start:
mov ax,3h ;clear screen and set up segments
int 10h
mov ax,@data
mov ds,ax
mov es,ax
cli ;turn off ints
mov ax,0h ;set es to int vector segment
mov es,ax
mov bx,es:[9*4] ;get int 9h vector
mov word ptr old9,bx ;store int 9h offset
mov bx,es:[9*4+2]
mov word ptr old9+2,bx ;store int 9h seg
mov word ptr es:[9*4],offset new9 ; put new int 9h (mine) in place of old one
mov es:[9*4+2],CS
sti ;turn on ints
begin:
int 09h ;call int
cmp escape,1h ;check for esc press flag
je esc2
jmp begin ;go back to beginning if no esc
esc2:
lds dx,dword ptr old9 ; load ds:dx with old int 9h vector
mov ax,2509h ;reset it
int 21h
mov ax,0100h ;wait for keypress
int 21h
mov ax,3h ;clear screen
int 10h
mov ax,4c00h ;DOS terminate program
int 21h
end start
;------------------------- -----end of program------------------- ---------- ------
maybe i have the program right, but im just not calling the interrupt right,i dont know how to do that. Do i need to have my data in my code segment or something like that?
any help is appreciated
thanks
.model medium
.386
.stack 200h
.data ;data segment
down db "down$" ; down message
up db "up$" ;up message
ol9 dd ? old int 9h vector
escape db 0h ;escape flag
.code ;code segment
;-------------------------
new9 proc
in al,60h ;get keyboard port status
cmp al,1h ;check if esc pressed
je esc1
cmp al,48h ;check if up scan code
je upsub ;yes goto up sub
cmp al,50h ;check if down scancode is pressed
je downsub ;if yes goto down sub
endofint: ;end interrupt routine
in al,61 ;this does something with a key release code?
mov ah,al ; not sure of what this does exactly
or al,80h ; i know it writes something to the keybrd port
out 61h,al ; but i dont know what or why
mov al,ah ;it just seems everyone uses this for thier hooking routines
out 61h,al
mov al,29h
out 20h,al ;i know this is the end of interrupt signal
iret ; i know this pops the cs:ip and flags, but i dont know where to put it
jmp endproc
upsub: ;prints up to the screen
pusha ;preseve regs
mov ax,seg up
mov ds,ax
mov dx,offset up
mov ax,0900h
int 21h
popa ;restore regs
jmp endofint
downsub: ;prints up to the screen
pusha ;preseve regs
mov ax,seg down
mov ds,ax
mov dx,offset down
mov ax,0900h
int 21h
popa ;restore regs
jmp endofint
esc1:
mov escape,1h ;set escape flag if pressed
jmp endofint
endproc:
jmp dword ptr cs:old9 ;jumps to old interrupt 9h
clrbuf: ;clear keyboard buffer
mov ah,01h
int 16h
jz bufclr
mov ah,00h
int 16h
jmp clrbuf
bufclr:
iret
endp
;-------------------------
start:
mov ax,3h ;clear screen and set up segments
int 10h
mov ax,@data
mov ds,ax
mov es,ax
cli ;turn off ints
mov ax,0h ;set es to int vector segment
mov es,ax
mov bx,es:[9*4] ;get int 9h vector
mov word ptr old9,bx ;store int 9h offset
mov bx,es:[9*4+2]
mov word ptr old9+2,bx ;store int 9h seg
mov word ptr es:[9*4],offset new9 ; put new int 9h (mine) in place of old one
mov es:[9*4+2],CS
sti ;turn on ints
begin:
int 09h ;call int
cmp escape,1h ;check for esc press flag
je esc2
jmp begin ;go back to beginning if no esc
esc2:
lds dx,dword ptr old9 ; load ds:dx with old int 9h vector
mov ax,2509h ;reset it
int 21h
mov ax,0100h ;wait for keypress
int 21h
mov ax,3h ;clear screen
int 10h
mov ax,4c00h ;DOS terminate program
int 21h
end start
;-------------------------
maybe i have the program right, but im just not calling the interrupt right,i dont know how to do that. Do i need to have my data in my code segment or something like that?
any help is appreciated
thanks
SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
usually the error i get is one when i hold down a key for more than a second, this results in a ms-dos prompt illegal operation.
ive read most of the book on art of assembly (of course that is for masm, so maybe i lost something in the conversion)ill go back and take a look.
for now ill try what grg99 said, cause that sounds pretty practical. however when i go through other peoples int hooks i can never find the place where they call the routine.i think thats one of the biggest problems with my code; i dont know how to call the handler.
ive read most of the book on art of assembly (of course that is for masm, so maybe i lost something in the conversion)ill go back and take a look.
for now ill try what grg99 said, cause that sounds pretty practical. however when i go through other peoples int hooks i can never find the place where they call the routine.i think thats one of the biggest problems with my code; i dont know how to call the handler.
ASKER
ok i got it working...thanks guys
after going through the AOA again and 'baby stepping through my code i was able to fix it.
thanks
after going through the AOA again and 'baby stepping through my code i was able to fix it.
thanks
What errors do you get.
first get the orignal handler address,
mov ax, 0x3509
les bx, oldvect
int 0x21
then, set you interrupt handler,
mov ax, 0x2509
lds dx, myint
int 0x21
after all things done . restore the previous vector.
mov ax, 0x2509
lds dx, oldvect
int 0x21
regards manish