home *** CD-ROM | disk | FTP | other *** search
/ Power Programming / powerprogramming1994.iso / progtool / microcrn / issue_36.arc / C36.FIG next >
Text File  |  1987-05-21  |  3KB  |  60 lines

  1.      ASSEMBLY LANGUAGE VERSION OF A GENERIC INTERRUPT FUNCTION
  2.  
  3. interrupt(nn,ptr)
  4.    int nn
  5.    struct regs *ptr;    /* In this case a long pointer: 32 bytes */
  6. /**
  7. In a short C the pointers would be words, not double words, and you'd use a
  8. "mov bx,[bp+??]" rather than the "lds bx,[bp+???]." In all cases remember to
  9. recover ds before using bx to point to the base of the structure being
  10. reloaded with register values.
  11.  
  12. Also note the rather sneaky way of generating the machine code "CDnn" patch
  13. that invokes nnth interrupt. Through a irritating omission in the Intel
  14. instruction set, "int" command can only take an "immediate" or numerical
  15. argument; and therefore the assembly language programmer must modify the code
  16. @un(in situ). Not very nice, and certainly not ROM-able, but necessary. What
  17. I do below is load CD into the AL register, nn into the AH, and then poke the
  18. word into the code at the proper location. Since the Intel chips use byte-
  19. reverse layout, the code becomes CDnn.  Blush . . . but it works.
  20. **/
  21.      ASSUME        PROPER SEGMENT DECLARATIONS
  22.  
  23.   push  bp                 ;Save bp
  24.   mov   bp,sp              ;Establish a pointer to the stack
  25.   push  ds                 ;Push whatever other registers need to be saved
  26.   mov   al,0cdh            ;0CDh into low byte, int # into high
  27.   mov   ah,[bp+6]          ;This displacement will vary with the compiler
  28.   mov   cs:intcall[0],ax   ;Stuff CDNN into the instruction site
  29.   lds   bx,[bp+8]          ;Load seg:ofs of pointer to structure into ds:bx
  30.   mov   ax,[bx+0]          ;Move first slot of structure into ax
  31.   push  [bx+2]             ;Push final bx onto stack, since bx needed as
  32.                            ;   pointer right now.
  33.   mov   cx,[bx+4]          ;Load the rest of the registers, skipping bp
  34.   mov   dx,[bx+6]          ;   since bp is never used by interrupts and is
  35.   mov   di,[bx+8]          ;   needed to point to stack.
  36.   mov   si,[bx+10]         ;We can ignore flags on the way IN, not OUT
  37.   mov   es,[bx+14]
  38.   mov   ds,[bx+16]         ;There goes the pointer         
  39.   pop   bx                 ;Pop bx off stack
  40.   push  bp                 ;Save bp across interrupt
  41. intcall:
  42.   dw    00                 ;Scene of the crime of self-modifying code
  43.   pop   bp                 ;Recover bp
  44.   push  bx                 ;Save ds & bx so we can use a pointer again
  45.   push  ds
  46.   lds   bx,[bp+8]          ;Reload pointer
  47.   mov   [bx+0],ax          ;Inverse of above: fill struct with values
  48.   mov   [bx+4],cx
  49.   mov   [bx+4],cx
  50.   mov   [bx+6],dx
  51.   mov   [bx+8],di
  52.   mov   [bx+10],si
  53.   mov   [bx+14],es
  54.   pushf                    ;Preserve flag value this time
  55.   pop   [bx+18]            ;When you can't point, pop
  56.   pop   [bx+16]
  57.   pop   [bx+2]
  58.   pop   ds                 ;Recover saved registers
  59.   pop   bp
  60.