Upload
pearl-west
View
223
Download
0
Tags:
Embed Size (px)
Citation preview
More on InterruptsMore on Interrupts
Interrupt service routinesInterrupt service routines
o DOS facilities to install ISRs
o Restrictions on ISRso Currently running program should have no
idea that it was interrupted. o ISRs should be as short as possible
because lower priority interrupts are blocked from executing until the higher priority ISR completes
Function Action
INT 21h Function 25h Set Interrupt vectorINT 21h Function 35h Get Interrupt vectorINT 21h Function 31h Terminate and stay resident
Installing ISRsInstalling ISRs
Let N be the interrupt to serviceo Read current function pointer in vector table
o Use DOS function 35h o Set AL = N o Call DOS Function AH = 35h, INT 21h o Returns: ES:BX = Address stored at vector N
o Set new function pointer in vector tableo Use DOS function 25h o Set DS:DX = New Routine o Set AL = N o DOS Function AH = 25h, INT 21h
Installing ISRInstalling ISRo Interrupts can be
installed, chained, or called
o Install New interruptreplace old interrupt
o Chain into interruptService myCode first
MyIntVector Save Registers Service Hardware Reset PIC Restore Registers IRET
MyIntVector Save Registers MyCode Restore Registers JMP CS:Old_Vector
MyIntVector PUSHF CALL CS:Old_Vector Save Registers MyCode Restore Registers IRET
oCall Original InterruptService MyCode last
Timer interrupt exampleTimer interrupt example
o In this example we will patch the ISR for the Timer Interrupt
o Our ISR will count the number of timer interrupts received
o Our main program will use this count to display elapsed time in minutes and seconds
About the PC timerAbout the PC timero We’ll examine it in detail when we look at the
8253o You can view it as a clock that ticks and sends
a signal to your processor approximately every 1/18.2 seconds
o It is also called the “eighteenth of a second” o We’ll find out where this 18.2 comes from latero You can approximately count minutes and
seconds as followso For every 18 ticks of the timer we add 1
secondo For every 60 seconds we add one minute
and reset the counters for seconds
ISR overviewISR overview
o Install the ISR for vector 08ho Call original timer interrupto Increment a counter on every interrupt from
the timer (count)o Increment a second counter (scount) when
count=18 and reset counto Increment a minute counter (mcount) when
scount=60 and reset the second countero The program will print the scount, mcount
and count values in red, green and blue colors
o It will look as a (somewhat low-resolution) timer printed in your screen
Timer interrupt – Timer interrupt – main proc skeletonmain proc skeleton
;====== Variables ===================
; Old Vector (far pointer to old interrupt function)
oldv RESW 2count DW 0 ;Interrupt
counter (1/18 sec)scount DW 0 ;Second counter
mcount DW 0 ;Minute counterpbuf DB 8 ;Minute counter;====== Main procedure =====..start…;----Install Interrupt Routine-----call Install ;Main program (print count values) .showcMov ax, [mcount] ;Minute Count…
call pxymov ax, [scount] ;Second Count…call pxymov ax,[count] ;Interrupt Count
(1/18 sec)… call pxymov ah,1int 16h ;Check for key
press jz .showc ;Quit on any key
;---- Uninstall Interrupt Routine-----call UnInst ;Restore original INT8…call mpxit
Timer interrupt – complete main Timer interrupt – complete main procproc
..startmov ax, cs ;Initialize DS=CS mov ds, axmov ax, 0B800h;ES=VideoTextSegmentmov es, axcall install ;Insert my ISR
showc:
mov di,12 ;Column 6 (DI=12/2)mov ah,00001010b;Intense Green call pxy
mov ax,[count] ;Int Count (1/18th sec)mov bx,pbufcall binasc mov bx, pbuf
Contd…
Timer interrupt – complete main Timer interrupt – complete main procproc
.. mov ax, [mcount];Minute Countmov bx, pbufcall binascmov bx, pbuf mov di,0 ;Column 0mov ah,00001100b;Intense Redcall pxymov ax,[scount];Second Countmov bx,pbufcall binascmov bx, pbuf
mov ah,00000011b;Cyanmov di,24 ;Column 12 (DI=24/2)call pxymov ah,1int 16h ;Key Pressed ?jz showc
Call UnInst ;Restore original INT8mov ax,4c00h;Normal DOS Exitint 21h
Timer interrupt – PXY Timer interrupt – PXY and Install interruptand Install interrupt
;pxy (bx = *str, ah = color, di = column)
pxymov al, [bx]cmp al, ‘$'je .pxydonemov es:[di+2000], axinc bxadd di,2jmp pxy
.pxydoneret
mov al, 8 ;INT = 8
mov ah, 35h ;Read Vector Subfunction
int 21h ;DOS Service
mov word [oldv+0], bx
mov word [oldv+2], es
mov al, 8 ;INT = 8
Contd…
Timer interrupt – PXY Timer interrupt – PXY and Install interruptand Install interrupt
;====== Install Interrupt =====
install ;Install new INT 8 vector
push es
push dx
push ax
push bx
mov ah, 25h ;Set Vector Subfunction
mov dx, myint
;DS:DX point to functionint 21h ;DOS Service
pop bx pop axpop dxpop esret
Timer interrupt – uninstall interruptTimer interrupt – uninstall interrupt
;====== Uninstall Interrupt ===========UnInst ; Uninstall Routine (Reinstall old vector)
push dspush dxpush axmov dx, word [oldv+0]mov ds, word [oldv+2]
mov al, 8 ; INT = 8mov ah, 25h ; Subfunction = Set Vectorint 21h ; DOS Service
pop axpop dxpop dsret
Timer interrupt – ISR codeTimer interrupt – ISR code
;====== ISR Code =========
myintpush ds ;Save all registerspush axmov ax, cs ;Load default segmentmov ds, axpushf ;Call Orig Function w/flagscall far [oldv] ;Far Call to existing routine
inc word [count];Increment
Interrupt countcmp word [count],18jne .myintdone
inc word [scount] ;Next second mov word [count], 0cmp word [scount], 60jne .myintdoneinc word [mcount] ; Next minutemov word [scount], 0
.myintdonepop ax ;Restore all Registerspop dsiret ;Return from Interrupt
Replacing An Replacing An Interrupt HandlerInterrupt Handler
;install new interrupt vector
%macro setInt 3 ;Num, OffsetInt, SegmentInt
push ax
push dx
push ds
;store old interrupt vector
%macro getInt 3 ;Num, OffsetInt, SegmentInt
push bx
push es
mov al, %1
Contd…
Replacing An Replacing An Interrupt HandlerInterrupt Handler
mov dx, %2mov ax, %3mov ds, axmov al, %1mov ah, 25h ;set interrupt vectorint 21h
pop dspop dxpop ax
%endmacro
mov ah, 35h ;get interrupt vector
int 21h
mov %2, bx
mov %3, es
pop es
pop bx
%endmacro
Replacing An Interrupt Replacing An Interrupt HandlerHandler
CREQU 0dhLF EQU 0ah
SEGMENT stkseg STACK resb 8*64stacktop:
SEGMENT code
Warning DB “Overflow - Result Set to ZERO!!!!”,CR,LF,0
msgOK DB “Normal termination”, CR, LF, 0
old04hOffset RESWold04hSegment RESW
New04h ;our new ISR for int 04
;occurs on overflowsti ;re-enable interrupts
mov ax, Warningpush axcall putStr ;display
messagexor ax, ax ;set result to
zerocwd ;AX to DX:AX
iret
Replacing An Replacing An Interrupt HandlerInterrupt Handler
mov ax, msgOKpush axcall putStr
Error:;restore original int handlersetInt 04h, [old04hOffset], [old04hSegment]
mov ax, 4c00hint 21h
..startmov ax, csmov ds, ax
;store old vectorgetInt 04h, [old04hOffset], [old04hSegment]
;replace with address of new int handlersetInt 04h, New04h, cs
mov al, 100add al, alinto ;calls int 04 if an overflow occurredtest ax, 0FFhjz Error
Contd…
Replacing An Replacing An Interrupt HandlerInterrupt Handler
NOTESINTO is a conditional instruction that acts only when the overflow flag is setWith INTO after a numerical calculation the control can be automatically routed to a handler routine if the calculation results in a numerical overflow.By default Interrupt 04h consists of an IRET, so it returns without doing anything.
ReentrancyReentrancyo What happens if
o An ISR for some devices is executing and it has enabled interrupts
o Another interrupt from the same device comes along…The program may not behave correctly
o Assume that the ISRs modify some register and store its value in a memory location
o The previous ISR might have already modified the register but didn’t have the time to store the value in the memory locations
o The new ISR will save this register but it will try to update the memory location, which is in an inconsistent state
ReentrancyReentrancy
AnISR; assume scount=3, MSEC=950push dspush axmov ax, csmov ds, axmov ax, [MSEC] add ax, 55 ; ax=1005cmp ax, 1000jb SetMsec
Contd…
ReentrancyReentrancy
; Assume that another interrupt occurs at this pointinc [scount] ; the second interrupt will set scount=4 sub ax, 1000 ; mov [MSEC], ax; the second interrupt will set MSEC=5…; but the interrupted ISR will reexecute the inc so scount will be; set to 5 although the timer has not ticked 55 times!!!!pop axpop ds
ReentrancyReentrancy
o The code between the mov ax, [MSEC] and the mov [MSEC], ax must be executed atomically, without any interruptions
o This is called a critical regiono You can protect a critical region from being
interrupted by using:pushf ;preserve the current I flag statecli ; turn off interrupts… ; critical regionpopf ; restore the I flag state
Reentrancy in practiceReentrancy in practice
o First thing to remember: don’t call DOS from your ISRs, DOS is not reentranto DOS subroutines assume to be
entered by a single point at any timeo If you write an ISR and attempt to
call DOS you will most likely hang the machine forever
o Second thing to remember: BIOS is not reentrant
Contd…
Reentrancy in practiceReentrancy in practice
o There are ways to check if you’re executing inside DOS by testing a flag (function code 34h)o If the flag is 0 it is safe to call DOSo If the flag is 1 it might not be safe to call
DOSo You can also check if DOS is “idling”
(function code 28h), in that case it is safe to call DOS
DOS Memory UsageDOS Memory Usage
00000h
Interrupt vector003FFh
Various DOS/BIOS vars
Free memory area for use
by programs
0BFFFh
High memory area
Video, ROM, adapter memory
0FFFFh
Free memory pointer
DOS Memory UsageDOS Memory Usage
00000h
Interrupt vector003FFh
Various DOS/BIOS vars
Memory in use by your program
0BFFFh
High memory area
Video, ROM, adapter memory
0FFFFh
Free memory pointerFree memory area
Terminate and Stay Terminate and Stay Resident (TSR)Resident (TSR)
00000h
Interrupt vector003FFh
Various DOS/BIOS vars
Marked by the program as
resident and protected by DOS
0BFFFh
High memory area
Video, ROM, adapter memory
0FFFFh
Free memory pointer
Free memory area
Terminate and Stay Terminate and Stay Resident (TSR)Resident (TSR)
o Your program can have a resident portion and a transient portion
o The main program, normal data, support routines etc, are usually transient
o You can define ISRs and maintain them in memory after the program terminates using the resident portion
o Use DOS function 31h with the size of the resident portion passed in dx
Terminate and Stay Terminate and Stay Resident (TSR)Resident (TSR)
o If you want to use resident ISR’s you should define them in the lower parts of your memory address space
o You have to set your DS properlyo The resident code has no idea about the
values of the segment registerso You have to set the data segment to the
value of your code segmentpush dspush cspop ds ; this moves cs to ds…pop ds