Microsoft KB Archive/50518

From BetaArchive Wiki

BX Register Is Popped Twice for a C Interrupt Function


6.00 6.00a 6.00ax 7.00 | 6.00 6.00a | 1.00 1.50 1.51 1.52 MS-DOS | OS/2 | WINDOWS kbtool ------------------------------------------------------------------------ The information in this article applies to: - The Microsoft C/C++ Compiler (CL.EXE) included with: - Microsoft C for MS-DOS, versions 6.0, 6.0a, and 6.0ax - Microsoft C for OS/2, versions 6.0, and 6.0a - Microsoft C/C++ for MS-DOS, version 7.0 - Microsoft Visual C++ for Windows, version 1.0, 1.5, 1.51, and 1.52 ------------------------------------------------------------------------ SUMMARY ======= The interrupt keyword is used to designate specific C functions as interrupt service routines and instructs the compiler to generate appropriate entry and exit instructions. If you compile code with the /G1 or /G2 option (80186 or 80286 code generation), then the compiler produces pusha and popa instructions that save and restore all vital registers. However, if you compile with the default /G0 (8086 code generation), then the registers are each explicitly pushed and popped. One difference, which may at first appear to be a problem in this code, is that the BX register is popped twice but the SP register is not popped at all. This is not a problem. The SP register is saved in the following instruction sequence: mov bp, sp . . ISR code . mov sp, bp MORE INFORMATION ================ The peculiar double popping of BX can be explained by the following: - The registers are pushed AX, CX, DX, BX, SP, BP, SI, DI, DS, ES (left to right) - The registers are popped AX, CX, DX, BX, BX, BP, SI, DI, DS, ES (right to left) Notice that ES receives the old ES; DS the old DS, but BX receives the old SP, then BX receives the old BX. The first pop of SP to BX is necessary to remove the previous value of SP from the stack. The second pop of BX is necessary to restore the old BX value. The old value of SP was restored in the "MOV SP,BP" instruction, which immediately precedes the popping of all the registers. This ensures that the state of the registers are saved and then restored in the Interrupt Service Routine. Sample Code ----------- /* Compiler Options Needed: /Fc /G0 (or /G1) */ #include #include void __interrupt __far func1(unsigned _es, unsigned _ds, unsigned _di, unsigned _si ) {} void main(void) {} Additional reference words: kbinf 1.00 1.50 6.00 6.00a 6.00ax 7.00 8.00 8.00c KBCategory: kbtool KBSubcategory: CLIss

Keywords : kb16bitonly
Issue type :
Technology : kbVCsearch kbAudDeveloper kbCVCComp

Last Reviewed: May 5, 2001
© 2001 Microsoft Corporation. All rights reserved. Terms of Use.