Date: Tue, 4 Feb 1997 13:37:31 +0200 (IST) From: Eli Zaretskii To: Jack Cai cc: djgpp AT delorie DOT com Subject: Re: Interrupt using assembly, Please help!!! In-Reply-To: Message-ID: MIME-Version: 1.0 Content-Type: TEXT/PLAIN; charset=US-ASCII On Fri, 31 Jan 1997, Jack Cai wrote: > I change tm1.c a bit to use __dpmi calls without the wrapper call, > change t1.s to use iret instead of ret and put a sti before it. No luck! > So, I dig into gopint.c to find out what goes on in allocate_wrapper call. > I put the fill around my assembly code, thinking that was it. Guess > what, no luck! counter remains 00000000000000.... Some potential problems (I didn't really try to correct them and see if that helps, so some or all of them mught be wild geese): 1) Your assembly-language handler doesn't declare `_counter' extern, so it could be that `counter' in your C driver isn't linked to the one you increment in assembly. 2) You should declare `counter' to be volatile in the C code. Otherwise, gcc is free to optimize it out of existence, or load it into a register and never look back. 3) The assembly handler declares and uses a 100-byte-long stack, which is too small IMHO. 4) You didn't lock the code and data that the interrupt handler touches. I suggest at first to lock all the code and data of your program as described in the DJGPP FAQ list (section 18.9) until you have a working version, then only lock what is necessary. > command to compile: gcc -o tm2.exe tm2.c t2.s I suggest to always add -Wall to gcc switches: it catches an enormous amount of problems which you otherwise need to debug. > Several related questions about the gopint.c comments. > 1) Why does it assume only cs and ss is available, thus the stack swapping > and segment register savings? I thought in flat mode, none of the segments > change. The flat model is only relevant to the code produced by GCC from standard C source. The underlying machine architecture is still segmented (it's the same old Intel CPU, right?). The ``flat'' thing means that as long as your program executes its normal main thread, the values loaded into the DS and SS registers stay put. But since an interrupt processing involves a kind of task switch, your handler is called from the DPMI host code which handles interrupts, and so the values of DS and SS are set to the DPMI host's memory. The DPMI specification regulates the setup of the registers when your handler is called by a DPMI host (which handles interrupt reflection from real mode); in particular, it specifies that SS:ESP point to a locked stack allocated by the DPMI host, which might be too small for a serious handler. Since the wrapper is a general-purpose function, it allocates larger stack. For more details, see the relevant parts of the DPMI spec (a pointer to it is included in the FAQ). > 2) Second, there is no sti in the wrapper code, contrary to the FAQ? This is left to the user-defined handler which the wrapper calls. Don't forget that the wrapper by itself isn't a handler, it only wraps the handler.