www.delorie.com/archives/browse.cgi   search  
Mail Archives: djgpp/1997/02/04/06:50:04

Date: Tue, 4 Feb 1997 13:37:31 +0200 (IST)
From: Eli Zaretskii <eliz AT is DOT elta DOT co DOT il>
To: Jack Cai <cai AT haas DOT berkeley DOT edu>
cc: djgpp AT delorie DOT com
Subject: Re: Interrupt using assembly, Please help!!!
In-Reply-To: <Pine.SOL.3.91.970131120434.14037A-100000@haas.berkeley.edu>
Message-ID: <Pine.SUN.3.91.970204130958.29580D-100000@is>
MIME-Version: 1.0

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 -


  webmaster     delorie software   privacy  
  Copyright © 2019   by DJ Delorie     Updated Jul 2019