|
Outra coisa interessante acerca de TSR: provavelmente não podes chamar rotinas de DOS e BIOS porque estas não são reentrantes (só podem ser activas uma de cada vez) e supõe que a interrup
ção interrompeu uma dessas rotinas ! Se precisares mesmo de chamar uma rotina do DOS ou do BIOS, instala ou "agarra" também essas interrupções e mantém uma flag para quando elas estão activas e não estão.
Tempo para um exemplo !
; Este exemplo de código vai "agarrar" a interrupção do relógio (
hardware, chamada 18.2 vezes por seg.). .MODEL TINY .386 .CODE &n
bsp; .STARTUP
jmp Install ; Salta por cima dos dados e do código residente
; Dad
os tem que estar no Segmento código para não serem desperdiçados com o código de Instalação OldHandler DWORD ?
; Endereço da rotina original do relógio
NewHandler PROC FAR push bx ; Estes dois re
gistos vão ser alterados push ds
mov bx, 0B800h ; 0B800h é o endereço do VGA display &n
bsp; mov ds, bx
mov bx, 1 ; O atributo da cor do primeiro caracter no écran &n
bsp; inc [bx] ; incementa-o (cor vai mudar 18.2 vezes por seg.)
pop ds &n
bsp; ; restaura os registos pop bx
jmp cs:OldHandler ; isto é o
mesmo de CALL CS:OldHandler + IRET NewHandler ENDP
Install PROC mov ax, 351Ch ; cha
ma função 35h int 21h ; obtém vector para o relógio(interrupt 08)
mov WORD PTR OldHandler[0], bx ; Guarda endereço do original mov WORD PTR O
ldHandler[2], es ; interrução do relógio mov ax, 251Ch ; requisita função 25h &nb
sp; mov dx, OFFSET NewHandler ; DS:DX aponta para novo handler do relógio int
21h ; estabelece vector com endereço de NewHandler
mov dx, OFFSET Install  
; ; DX = bytes na secção residente mov cl, 4 shr dx, cl ; converte para o número
de parágrafos inc dx ; mais um mov  
; ax, 3100h ; Requisita função 31h, código de erro=0 int 21h ; Terminate-and-S
tay-Resident Install ENDP
END A única maneira de realmente aprender a programar TSR é apenas experimentando. Divirtam-se !
|
|