Example 21H/42H:
#include
#include
#include
unsigned int handle;
void main()
union REGS regs;
handle = open("c:\\abc.txt",O_RDONLY);
regs.x.bx = handle;
regs.h.ah = 0x42;
regs.h.al = 0x02; //correction
regs.x.cx = 0;
regs.x.dx = 0;
*((int*)(&size)) = regs.x.ax;
*(((int*)(&size))+1) =regs.x.dx;
}
Lets now illustrate how ISR can be invoked by means of another example of BIOS service. Here we are choosing the ISR 10h/01h. This interrupt is used to perform I/O on the monitor. Moreover this service is used to change the size of cursor in text mode. The description of this service is given as under.
AH = 01
CL = Ending Scan Line
On Exit
Unchanged
{
char st[80];
union REGS regs;
regs.h.ah = 0x01;
regs.h.cl = 0x00;
int86(0x10,®s,®s); //corrected
}
The program is quite self explanatory as it puts the starting scan line to be 1 and the ending scan line to be 0. Henceforth when the service execute the cursor will disappear.
Use of ISRs for C Library functions
There are various library function that a program
Writing S/W ISRs
Lets now see how can a programmer write an ISR
Getting interrupt vector
As we have discussed earlier IVT is a table contai
Getting interrupt vector refers to the operation which used to reading the far address stored within the vector. The vector is double word, the lower word of it being the offset address and the higher word being the segment address. Moreover the address read from a vector can be used as a function pointer. The C library function used to do the exactly
Another thing required to be understood are the function pointers. C language is a very flexible language just like there are pointers for integers, characters and other data types there are pointers for functions as well as illustrated by the following example
void myfunc()
{
}
void (*funcptr) ( )
funcptr = myfunc;
myfunc();
There are three fragments of code in this example. The first fragment shows the declaration of a function myfunc()
The second fragment show declaration of a pointer to function named funcptr which is a pointer to a function that returns void.
Interrupt pointers and functions
void interrupt newint ( )
{
...
...
}
Similarly a pointer to such interrupt type function can also be declared as following
void interrupt (*intptr) ( );
where intptr is the interrupt pointer and it can be assigned an address using the getvect() function
Now interrupt number 8 can be invoked using the interrupt vector as following
(*intptr) ( );
Setting Interrupt Vector
void interrupt newint ( )
{
…
…
}
setvect(0x08, newint);
C program making use of Int 65H
Here is a listing of a program that makes use of int 65H to exhibit how software interrupts needs to be programmed.
void interrupt (*oldint65)( );
char st[80] = {“Hello World$”};
void interrupt newint65(void);
void main()
{
oldint65 = getvect(0x65);
setvect(0x65, newint65);
geninterrupt (0x65);
geninterrupt (0x65);
geninterrupt (0x65);
setvect(0x65, oldint65);
}
void interrupt newint65( )
{
_AH = 0x09;
_DX=(unsigned int)st;
geninterrupt (0x21);
}
The above listing saves the address of original int 65H in the pointer oldint65. It then places the address of its own function newint65 at the vector of interrupt number 65H. From this point onwards whenever int 65H is invokes the function newint65 will be invoked. Int 65 is invoked thrice which will force the newint65 function to be invoked thrice accordingly. After this the original value of the vector stored in oldint65 is restored. The newint65 function only displays the string st. As the interrupt 65 is invoked thrice this string will be printed thrice.
The Keep function
One deficiency in the above listing is that it is not good enough for other application i.e. after the termination of this program the newint65 function is de-allocated from the memory and the interrupt vector needs to be restored otherwise it will act as a dangling pointer (pointing to a place where there is garbage or where there is no meaningful function). To make the effect of this program permanent the newint65 function need to be memory resident. This can be achieved by the function keep() which is quite similar to exit() function. The exit() function returns the execution to the parent shell program and de-allocates the memory allocated to the program whereas the keep() function also returns the execution to the parent program but the memory allocated to the process may still remain allocated.
keep (return code, no. of paras);
the keep() function requires the return code which is usually zero for normal termination and the number of paragraphs required to be allocated. Each paragraph is 16 bytes in size.
TSR Programs
Following is a listing of a TSR (Terminate and Stay Resident) program which programs the interrupt number 65H but in this case the new interrupt 65H function remains in memory even after the termination of the program and hence the vector of int 65h does not become a dangling pointer.
#include
#include
char st[80] ={"Hello World$"};
void interrupt (*oldint65)( );
void interrupt newint65( );
void main()
{
oldint65 = getvect(0x65);
setvect(0x65, newint65);
keep(0, 1000);
}
void interrupt newint65( )
{
_AH = 0x09;
_DX=(unsigned int)st;
geninterrupt (0x21);
}
The main()function gets and sets the vector of int 65H such that the address of newint65 is placed at its vector. In this case the program is made memory resident using the keep function and 1000 paragraphs of memory is reserved for the program (the amount of paragraphs is just a calculated guess work based upon the size of application). Now if any application as in the following case invokes int 65H the string st which is also now memory resident will be displayed.
#include
#include
void main()
{
geninterrupt (0x65);
geninterrupt (0x65);
}
This program invokes the interrupt 65H twice which has been made resident.
Tidak ada komentar:
Posting Komentar