?? basm.doc
字號:
which calls most DOS routines. But many of the
interrupt vectors are unused, which means, of course,
that you can write your own interrupt handler and put a
far pointer to it into one of the unused interrupt
vectors.
To write an interrupt handler in Turbo C++, you must
define the function to be of type interrupt; more
specifically, it should look like this:
void interrupt myhandler(bp, di, si, ds, es, dx,
- 9 -
cx, bx, ax, ip, cs, flags,
... );
As you can see, all the registers are passed as
parameters, so you can use and modify them in your code
without using the pseudovariables discussed earlier in
this online file. You can also pass additional
parameters (flags, ...) to the handler; those should be
defined appropriately.
A function of type interrupt will automatically save
(in addition to SI, DI, and BP) the registers AX
through DX, ES, and DS. These same registers are
restored on exit from the interrupt handler.
Interrupt handlers may use floating-point arithmetic in
all memory models. Any interrupt handler code that uses
an 80x87 must save the state of the chip on entry and
restore it on exit from the handler.
An interrupt function can modify its parameters.
Changing the declared parameters will modify the
corresponding register when the interrupt handler
returns. This may be useful when you are using an
interrupt handler to act as a user service, much like
the DOS INT 21 services. Also, note that an interrupt
function exits with an IRET (return from interrupt)
instruction.
So, why would you want to write your own interrupt
handler? For one thing, that's how most memory-resident
routines work. They install themselves as interrupt
handlers. That way, whenever some special or periodic
action takes place (clock tick, keyboard press, and so
on), these routines can intercept the call to the
routine handling the interrupt and see what action
needs to take place. Having done that, they can then
pass control on to the routine that was there.
Using low-level =======================================================
practices
You've already seen a few examples of how to use these
different low-level practices in your code; now it's
time to look at a few more. Let's start with an
interrupt handler that does something harmless but
tangible (or, in this case, audible): It beeps whenever
it's called.
- 10 -
First, write the function itself. Here's what it might
look like:
#include <dos.h>
void interrupt mybeep(unsigned bp, unsigned di,
unsigned si,
unsigned ds, unsigned es,
unsigned dx,
unsigned cx, unsigned bx,
unsigned ax)
{
int i, j;
char originalbits, bits;
unsigned char bcount = ax >> 8;
/* Get the current control port setting */
bits = originalbits = inportb(0x61);
for (i = 0; i <= bcount; i++){
/* Turn off the speaker for awhile */
outportb(0x61, bits & 0xfc);
for (j = 0; j <= 100; j++)
; /* empty statement */
/* Now turn it on for some more time */
outportb(0x61, bits | 2);
for (j = 0; j <= 100; j++)
; /* another empty statement */
}
/* Restore the control port setting */
outportb(0x61, originalbits);
}
Next, write a function to install your interrupt
handler. Pass it the address of the function and its
interrupt number (0 to 255 or 0x00 to 0xFF).
void install(void interrupt (*faddr)(), int inum)
{
setvect(inum, faddr);
}
Finally, call your beep routine to test it out. Here's
a function to do just that:
- 11 -
void testbeep(unsigned char bcount, int inum)
{
_AH = bcount;
geninterrupt(inum);
}
Your main function might look like this:
main()
{
char ch;
install(mybeep,10);
testbeep(3,10);
ch = getch();
}
You might also want to preserve the original interrupt
vector and restore it when your main program is
finished. Use the getvect and setvect functions to do
this.
- 12 -
INDEX
___________________________________________________________________________
A F
asm (keyword) 2 floating point
braces and 2 arithmetic
assembler interrupt functions and 10
built in 1 functions
assembly language calling
inline 1 in inline assembly code 6
braces and 2
C structure members and 7
restrictions 8 G
calling functions 6 goto statements
commenting 2 assembly language and 8
directives 6
goto in 8
jump instructions 5, 8 I
option (*B) 1 INT instruction 9
referencing data in 6 interrupt (keyword) 9
register variables in 7 interrupts
semicolons and 3 beep
size overrides in 7 example 11
syntax 2 functions
variable offsets in 7 example of 10
floating-point arithmetic in 10
handlers
B calling 11
braces installing 11
asm keyword and 2 programming 9
built-in assembler 1
J
C jump instructions, inline assembly language
command-line compiler table 5
options using 8
assembly language and 1
-B (inline assembler code) 1
inline assembler code 1 L
comments labels
inline assembly language code 2 in inline assembly code 8
Index 13
M repeat prefix opcodes 5
memory-resident routines 10
S
O size overrides in inline assembly
opcodes 3 code 7
defined 2 software interrupt instruction 9
mnemonics sounds
table 4 beep 11
repeat prefixes 5 structures
operands (assembly language) 2 members
in inline assembly code 7
restrictions 8
P syntax
prefix opcodes, repeat 5 inline assembly language 2
programs
terminate and stay resident
interrupt handlers and 10 T
terminate and stay resident
programs
R interrupt handlers and 10
referencing data in inline assembly Turbo Assembler 1
code 6
registers
DI V
assembly language and 7 variables
SI offsets in inline assembly code 7
assembly language and 7
variables
in inline assembly code 7
- 14 -
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -