soft interrupt

Soft interrupt:
Programming exceptions are often called softirqs
A soft interrupt is a signal communication method used to simulate a hard interrupt between communication processes.
After the interrupt source sends an interrupt request or a soft interrupt signal, the CPU or the receiving process automatically performs interrupt processing or completes the function corresponding to the soft interrupt signal at the appropriate time.
Soft interrupt is a software-implemented interrupt, that is, other programs interrupt it when the program is running; while a hard interrupt is a hardware-implemented interrupt, which is the device's interruption to it when the program is running.
 
1. The time when the soft interrupt occurs is controlled by the program, while the time when the hard interrupt occurs is random
2. Soft interrupts are generated by program calls, while hard interrupts are triggered by peripherals
3. The hardware interrupt handler must ensure that it can complete its task quickly, so that the program does not wait for a long time when executing
 
For general C language enthusiasts, the question of how to use interrupt routines in C should be very familiar. For example, we can directly operate on the physical sector of the disk by calling interrupt No. 13H through the int86 ( ) function, and also The mouse cursor can be displayed on the screen through the INT86 ( ) function calling interrupt No. 33H. In fact, the 13H number or the 33H number are just some functions, and the parameters of these functions are passed through the registers of the CPU. The interrupt number is just an indirect pointer to the starting memory unit of the function body, that is to say, it is indirect, that is to say, the starting segment address and offset of the function are calculated by the interrupt number through a method (specifically how operation, explained below). In this way, the programmer does not need to spend too much time writing the program to operate the hardware, as long as the parameters are set in their own program, and then the interrupt service routine provided by the BIOS or DOS can be called, which greatly reduces the program size. The difficulty of development shortens the program development cycle. Then, since the interrupt is a function, it can be called arbitrarily by the user and written arbitrarily by the user.
  The first 1024 bytes of computer memory (offsets 00000H to 003FFH) hold 256 interrupt vectors, each of which occupies 4 bytes, and the first two bytes hold the entry address offset of the interrupt service routine. The last two bytes save the entry segment address of the interrupt program. When using, as long as they are transferred into the registers IP and CS respectively, the interrupt service routine can be transferred to realize the interrupt call. Whenever an interrupt occurs, the CPU multiplies the interrupt number by 4, obtains the interrupt vector address in the interrupt vector table, and then obtains the IP and CS values, thereby turning to the entry address of the interrupt service routine and calling the interrupt. This is the basic process of the interrupt service routine being called by the interrupt number. When the computer starts, the BIOS fills the basic interrupts into the interrupt vector table. When DOS gets the system control, it fills in some interrupt vectors into the table, and also modifies part of the BIOS interrupt vectors. Some interrupt vectors are reserved by the system for users, such as interrupts 60H to 67H, and users can write their own interrupt service routines into these interrupt vectors. Not only that, users can also change and improve the existing interrupt vector of the system.
  In the C language, a new function type interrupt is provided, which is specially used to define interrupt service routines. For example, we can write the following interrupt service routines:
/* Example 1: Interrupt Service Routine */
void interrupt int60()
{
 puts("This is an example");
}
The function of the interrupt is to display a string, why not use the printf ( ) function? This involves the reentrancy of DOS, which will be introduced later.
  After a simple interrupt service routine is written, how to fill in its function entry address into the interrupt vector table so that it can be transferred to the interrupt service routine for execution when an interrupt occurs? The setvect( ) and getvect( ) functions are used here. setvect ( ) has two parameters: the interrupt number and the entry address of the function. Its function is to install the specified function into the specified interrupt vector. The getvect ( ) function has one parameter: the interrupt number, and the return value is the entry address of the interrupt . Before the installation is interrupted, it is best to use the disable ( ) function to close the interrupt to prevent new interruptions during the installation process and cause the program to run chaotically. After the installation is completed, use the enable ( ) function to open the interrupt to make the program run normally. . Now we can enrich the above example a bit more:
/* Example 2: Writing, installing and using interrupt service routines */
#include
#include
#ifdef __cplusplus
 #define __ARGU ...
#else
 #define __ARGU
#endif
void interrupt int60 (__ARGU) /*Interrupt service function*/
{
 puts("This is an example");
}
void install (void interrupt (*fadd)(__ARGU),int num) /*installation interrupt*/
{
 disable(); /*Disable interrupts*/
 setvect(num, fadd); /*set interrupt*/
 enable(); /*Enable interrupts*/
}
void main()
{
install (int60, 0x60); /* install int60 function to 0x60 interrupt */
geninterrupt (0x60); /*manually generate interrupt 0x60*/
}
An experienced reader can easily get the result of the program: "This is an example!" is displayed on the screen.
  This is how to write and install interrupt service routines. Let's talk about the writing and use of memory resident program (TSR). In the C language, you can use the keep( ) function to keep a program in memory. This function takes two parameters: status and size. size is the length of the resident memory, which can be obtained with size=_SS+_SP/16-_psp. Of course, this is also an estimation method, not an exact value. After the function is executed, the exit status information is saved in status. For example, for the above example, rewrite "geninterrupt (0x60);" to "keep(0,_SS+_SP/16-_psp);" and then execute the program, this section of the program will be resident, and then in any other In software or program design, as long as interrupt No. 60H is used, the words "This is an example!" will be displayed on the screen. To restore the system's definition of interrupt No. 60H, only restart the computer.
  The example above is actually quite imperfect. It does not consider the state of the DOS system environment, whether the program has been resident in memory, or whether it has exited memory resident. It is easy to solve the second problem: at the beginning of the execution program, read the address of a function interrupt entry (such as interrupt No. 63H) to determine whether it is empty (NULL), if it is empty, set the address to non-empty first Re-resident memory, if it is non-empty, it means that it has been resident and exits the program. This step is very important to judge, otherwise, the system will crash due to repeated resident occupying too much memory space. As for the other two issues, I will not explain it here, and interested readers can refer to some related books.
  Not only that, we can also call the memory resident program by using the hotkey (Hotkey) under DOS. For example, after the "Hope Dictionary" that comes with "Hope Chinese Character System" is stored in memory, press Ctrl+F11 at any time to activate the program and the dictionary interface will appear. There is a microprocessor chip in the keyboard of the microcomputer, which is used to scan and detect the pressed and released state of each key. Most keys have a scan code to inform the current state of the CPU, but some special keys such as PrintScreen, Ctrl+Break, etc. do not generate scan codes, but directly generate interrupts. Because of this, we can point the interrupt number generated by Ctrl+Break to the entry address of the program written by ourselves, then when Ctrl+Break is pressed, the system will call our own program to execute, which is actually a modification The interrupt vector of Ctrl+Break. As for other key activation programs, it can be realized by using the scan code captured by the 9H keyboard interrupt, which will not be described here. For example, after executing the following program, return to the DOS system, and press Ctrl+Break at any time, the background color of the screen will turn red.
/* Example 3: Interrupt service routine writing, installation and use, memory resident */
#include
#include
#ifdef __cplusplus
 #define __ARGU ...
#else
 #define __ARGU
#endif
void interrupt newint(__ARGU); /*function declaration*/
void install (void interrupt (*fadd)(__ARGU), int num);
intmain()
{
 install (newint,0x1b); /*Ctrl+Break interrupt number: 1BH*/
 keep(0,_SS+(_SP/16)-_psp); /* resident program*/
 return 0;
}
void interrupt newint(__ARGU)
{
 textbackground(4); /*Set the background color of the screen to red*/
 clrscr(); /*Clear screen*/
}
void install (void interrupt (*fadd)(__ARGU), int num)
{
 disable();
 setvect(num,fadd); /*set interrupt*/
 enable();
}
  Since the 13H interrupt is the disk interrupt service program provided by the BIOS, for applications under DOS, their functions of saving and reading disks are realized by calling this interrupt. There are many viruses under DOS that like to modify the 13H interrupt to destroy the system. For example, modify the 13H interrupt service program and change it to:
/* Example 4: Virus body program pseudo code */
void interrupt new13(__ARGU)
{
 if (viral attack conditions are ripe)
 { Modify the entry parameter to point to the entry address of the virus program;
 execute virus code;
 }
 Call the original 13H interrupt;
}
As long as any software (such as EDIT.COM, etc.) operates on the disk and the virus attack conditions are ripe, the virus will be activated. Of course, doing so will reduce the available memory space and be easily discovered by users. Some "smart" viruses will modify other interrupt vectors so that the memory size reported by the system matches the actual size. There are also viruses, when it is found that users track it through some programs (such as DEBUG.COM, etc.), it will slip away quietly, and its basic principle is still related to the modification and interruption. Side 0 Cylinder 0 Sector 1 of the hard disk holds important boot information. Once damaged, the computer will not recognize the hard disk. We can write a program to prevent any software (including viruses) from performing the "write" operation on this sector, which achieves the function of "write protection" to a certain extent. Its basic principle is to modify the 13H interrupt vector and reside in memory. , monitors every detail of software (including virus) operation on disk. Readers please note: This program does not consider the exit of memory resident, if you want to resume the 13H interrupt, please restart the computer.
/*Example 5: Master boot sector protection, please compile with Turbo C 2.0, MBSP.C*/
#include
#include
#include
#define STSIZE 8192
#define PSP_ENV_PSP 0x2c
#define PARA(x) ((FP_OFF(x)+15)>>4)
typedef struct {
 unsigned bp,di,si,ds,es,dx,cx,bx,ax,ip,cs,flags;
} INTERRUPT_PARAMETER;
void install (void interrupt (*faddress)(), int num);
void interrupt new13(INTERRUPT_PARAMETER p);
intmain()
{
union REGS regs;
struct SREGS sregs;
unsigned mem;
unsigned far *pointer;
char far *stack;
printf("\n<> version 1.0\n\n");
  if ((stack=malloc(STSIZE))==NULL)
 {
 printf ("Not enough Memory!\n");
 exit(1);
 }
 if (getvect(0x62)!=NULL)
 {
 printf("Already Installed!\n");
 exit(1);
 }
 install(getvect(0x13),0x62);
 install (new13,0x13);
 pointer=MK_FP(_psp,PSP_ENV_PSP);
 freemem(*pointer);
 segread(&sregs);
 mem=sregs.ds+PARA(stack)-_psp;
 setblock(_psp,mem);
 keep (0,mem);
 return 0;
}
void install (void interrupt (*faddress)(), int num)
{
 disable();
 setvect(num,faddress);
 enable();
}
void interrupt new13(INTERRUPT_PARAMETER p)
{
p.ax=_AX;
p.cx=_CX;
p.dx=_DX;
if(_AH==0x03&&_CH==0&&_CL==0x01&&_DH==0&&_DL==0x80) return;
enable();
geninterrupt (0x62);
disable();
_AX=p.ax;
_CX=p.cx;
_DX=p.dx;
return;
}
  Note: Before using this program, please: ① Conduct a comprehensive scan of the computer's boot sector, memory and all files with anti-virus software, and make sure that there is no virus in the computer; ② Readers with computer assembly language foundation can write a new one by themselves. First, the program resides in the memory, and then the original boot program is called, so that the protection function can be turned on before the virus has obtained the system control.
  Finally, the problem of reentrancy in DOS system is briefly explained. DOS is a single-user single-task operating system. If the program is interrupted during execution, it may cause abnormal operation due to destroying the original program running environment, which is catastrophic. When the interrupt is generated, the CPU immediately suspends the current program to execute the interrupt service routine. If there is a call to a DOS interrupt (such as DOS's 21H interrupt) in the interrupt service routine, it will definitely rewrite the environment global variables (for example, The prefix of the PSP program segment will be changed to the PSP of the executing interrupt program), so that the original environment is destroyed, and the original program cannot be executed correctly. When the interrupt call completes and returns, the user gets unexpected results. Therefore, DOS system function calls should be avoided when writing interrupt service routines, and functions such as malloc ( ), printf ( ), and sprintf ( ) should not appear in C language interrupt service routines.

[url]
http://blog.sina.com.cn/s/blog_4a92ce12010006e3.html
[/url]

Guess you like

Origin http://10.200.1.11:23101/article/api/json?id=326747625&siteId=291194637