Mail Archives: djgpp/1997/02/04/06:50:04
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.
- Raw text -