home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Power Programming
/
powerprogramming1994.iso
/
progtool
/
microcrn
/
issue_36.arc
/
C36.FIG
next >
Wrap
Text File
|
1987-05-21
|
3KB
|
60 lines
ASSEMBLY LANGUAGE VERSION OF A GENERIC INTERRUPT FUNCTION
interrupt(nn,ptr)
int nn
struct regs *ptr; /* In this case a long pointer: 32 bytes */
/**
In a short C the pointers would be words, not double words, and you'd use a
"mov bx,[bp+??]" rather than the "lds bx,[bp+???]." In all cases remember to
recover ds before using bx to point to the base of the structure being
reloaded with register values.
Also note the rather sneaky way of generating the machine code "CDnn" patch
that invokes nnth interrupt. Through a irritating omission in the Intel
instruction set, "int" command can only take an "immediate" or numerical
argument; and therefore the assembly language programmer must modify the code
@un(in situ). Not very nice, and certainly not ROM-able, but necessary. What
I do below is load CD into the AL register, nn into the AH, and then poke the
word into the code at the proper location. Since the Intel chips use byte-
reverse layout, the code becomes CDnn. Blush . . . but it works.
**/
ASSUME PROPER SEGMENT DECLARATIONS
push bp ;Save bp
mov bp,sp ;Establish a pointer to the stack
push ds ;Push whatever other registers need to be saved
mov al,0cdh ;0CDh into low byte, int # into high
mov ah,[bp+6] ;This displacement will vary with the compiler
mov cs:intcall[0],ax ;Stuff CDNN into the instruction site
lds bx,[bp+8] ;Load seg:ofs of pointer to structure into ds:bx
mov ax,[bx+0] ;Move first slot of structure into ax
push [bx+2] ;Push final bx onto stack, since bx needed as
; pointer right now.
mov cx,[bx+4] ;Load the rest of the registers, skipping bp
mov dx,[bx+6] ; since bp is never used by interrupts and is
mov di,[bx+8] ; needed to point to stack.
mov si,[bx+10] ;We can ignore flags on the way IN, not OUT
mov es,[bx+14]
mov ds,[bx+16] ;There goes the pointer
pop bx ;Pop bx off stack
push bp ;Save bp across interrupt
intcall:
dw 00 ;Scene of the crime of self-modifying code
pop bp ;Recover bp
push bx ;Save ds & bx so we can use a pointer again
push ds
lds bx,[bp+8] ;Reload pointer
mov [bx+0],ax ;Inverse of above: fill struct with values
mov [bx+4],cx
mov [bx+4],cx
mov [bx+6],dx
mov [bx+8],di
mov [bx+10],si
mov [bx+14],es
pushf ;Preserve flag value this time
pop [bx+18] ;When you can't point, pop
pop [bx+16]
pop [bx+2]
pop ds ;Recover saved registers
pop bp