c++ - Interrupt Handling
- Dan Guinter (27/27) Sep 19 2010 I am looking to port an old C++ app from the (ancient)
- Walter Bright (3/7) Sep 24 2010 getvect and setvect should work. I don't know why it is failing for you....
- Dan Guinter (36/36) Sep 27 2010 I believe I found two problems; I'll post them separately.
- Walter Bright (1/1) Oct 02 2010 http://bugzilla.digitalmars.com/issues/show_bug.cgi?id=84
- %u (1/1) Nov 06 2010 Hello
- Dan Guinter (47/47) Sep 27 2010 The second thing I found involves accessing the registers in an
- Walter Bright (1/1) Oct 02 2010 http://bugzilla.digitalmars.com/issues/show_bug.cgi?id=83
- Walter Bright (2/3) Oct 02 2010 You're welcome. Thanks for the detailed reports, which I've added to bug...
I am looking to port an old C++ app from the (ancient) Microsoft 16-bit DOS-capable C++ compiler. Generally, it's going well, DMC being a little more strict on some things than the older compiler. What I'm wrestling with is interrupt handling. The old code used dos_getvect / setvect to insert my handler in place of the clock handler, and this just doesn't work under DMC - it crashes. If I change over to use int_intercept, it works again. Should the standard techniques of getvect/setvect be expected to work? (all the good stuff like blocking interrupts while changing vectors is in there, so this isn't a newbie "How do I make interrupts go to my code" question. Now I'm battling packet driver interrupts since I make int86 calls to tell the packet driver where my code is (i.e., I can't [easily] use int_intercept because the packet driver captures the actual interrupt then chains out to my code). I've narrowed the crash down to the actual interrupt that occurs when a packet is received and the packet driver tries to call my code. Seems like this "ought" to work, but my battle with setvect vs. int_intercept for the clock interrupt makes me think that I have the same problem in my ethernet code. Suggestions? Thanks in advance for any pointers. Dan
Sep 19 2010
Dan Guinter wrote:What I'm wrestling with is interrupt handling. The old code used dos_getvect / setvect to insert my handler in place of the clock handler, and this just doesn't work under DMC - it crashes.getvect and setvect should work. I don't know why it is failing for you. Do you have the source code for those two?
Sep 24 2010
I believe I found two problems; I'll post them separately. The first is that my old code had a typedef for the interrupt handler, and under DMC it isn't handled the same way. Here is the C code (compiled with -mld -4): typedef void _interrupt IRQHANDLER; IRQHANDLER irq( void ) { asm nop return; } void _interrupt irq2( void ) { asm nop return; } And here is the assembler. You can see that the first form (the typedef) ignored the _interrupt declaration and compiled as a standard subroutine, not as an interrupt handler: _irq PROC NEAR nop retf _irq ENDP _irq2 PROC NEAR pushaw push ds push es mov bp, sp push ds mov ax, DGROUP mov ds, ax cld nop mov sp, bp pop es pop ds popaw iret _irq2 ENDP
Sep 27 2010
http://bugzilla.digitalmars.com/issues/show_bug.cgi?id=84
Oct 02 2010
The second thing I found involves accessing the registers in an interrupt handler. Since I've not seen anything mentioned in the archives on this, I'm guessing it may be something in more recent compiler releases (assuming what I found is valid). Take the following C source where we try to access one of the registers at the time of the interrupt: void __interrupt isr( unsigned es, unsigned ds, unsigned di, unsigned si, unsigned bp, unsigned sp, unsigned bx, unsigned dx, unsigned cx, unsigned ax, unsigned ip, unsigned cs, unsigned flags ) { es = 0; return; } The resultant assembler (compiled with -mld -4): _isr PROC NEAR pushaw push ds push es mov bp, sp push ds mov ax, DGROUP mov ds, ax cld mov word ptr [bp+1AH], 0 mov sp, bp pop es pop ds popaw iret _isr ENDP It appears that the compiler "skips over" the data on the stack from the pusha, push ds, and push es, and offsets bp as if a calling routine had actually pushed arguments onto the stack. The line: mov word ptr [bp+1AH], 0 Should be: mov word ptr [bp+0], 0 I checked this against some old asm dumps from the Microsoft V1.52 compiler and the ES register is accessed at offset 0 from BP inside the interrupt handler. Under DMC, I patched around it by inserting an asm step to subtract 1AH from bp immediately upon entering (so the resultant mov is from [bp+0]) and it worked (I had to add 1AH just before return to keep SP correct). Thanks! Dan
Sep 27 2010
http://bugzilla.digitalmars.com/issues/show_bug.cgi?id=83
Oct 02 2010
Dan Guinter wrote:Thanks!You're welcome. Thanks for the detailed reports, which I've added to bugzilla.
Oct 02 2010