delorie.com/archives/browse.cgi   search  
Mail Archives: djgpp/1997/09/25/00:06:55

Date: Wed, 24 Sep 1997 22:06:30 -0700 (MST)
From: firewind <firewind AT metroid DOT dyn DOT ml DOT org>
To: Brett Porter <bporter AT rabble DOT uow DOT edu DOT au>
cc: djgpp AT delorie DOT com
Subject: Using "far" pointers
In-Reply-To: <199709250334.NAA18495@rabble.uow.edu.au>
Message-ID: <Pine.LNX.3.95.970924214311.371B-100000@metroid.dyn.ml.org>
MIME-Version: 1.0

Brett wrote:
> firewind wrote:
> > So... say I was writing an ISR, and wanted to check the InDOS flag, but I
> > had forgotten to initilize previously the variables that contained the
> > InDOS address (returned by the interrupt call in es->bx, so lets call the 
> > two vars that for simplicity), thus they contain junk. Now, what happens
> > if I _farpeekb(_dos_ds, es*16+bx)? Do I get a SIGSEGV or a read from
> > Some Random Location(tm)?

> Sorry, I don't know what the InDOS flag is, but you have a point in what you
> are saying there, anyway. 

More on InDOS in detail below.

> While far pointers have memory protection in that
> you can only use valid selectors, you have _dos_ds there for you which will
> let you access all of the first meg (I think). I haven't played around with
> this sort of thing too much: only to access video memory, etc.

Correct.

> I know you can't actually load ES with an arbitary value: it has to be a
> selector or you get a GPF.

Uh... I'm going to pretend I know what that means. :)  I am clueless when
it comes to registers and selectors and that sort of stuff.

> I'm not sure how this will work though: you are saying that you call some
> interrupt that returns es:bx (as many do). I've got a feeling that using
> these as described above will give a SIGSEGV, but again I am not sure. It
> will also depend whether these were obtained by calling using __dpmi_int to
> simulate a real-mode interrupt or not. Actually, I'm now sure that using
> this es:bx combination as above will not work, but I don't know how the
> __dpmi_int call will make the return values useful. Perhaps it actually
> returns a selector in es and an offset from that in ebx (well, in the
> structure __dpmi_regs, at least).

Nonono! You misunderstand! My example code -will- work as long as 'es' and
'bx' are valid variables culled from a __dpmi_regs struct after a
__dpmi_int call. The actual code, btw, goes like this: (where 'regs' is a
__dpmi_regs struct and 'es' and 'bx' are 'short's)

        regs.h.ah = 0x34;
        if(__dpmi_int(0x21, &regs) == -1) {
                printf("Error obtaining InDOS address.\n");
                exit(2);
        }
        else printf("Found InDOS address.\n");
        es = regs.x.es;
        bx = regs.x.bx;

At this point, it is valid to write the following:

	indos = _farpeekb(_dos_ds, es*16+bx);

'es' (the real mode selector, AFAIK) must be multiplied by 16 to be valid
(I don't know why, but the info page for _far* says so, so I do it :), and
then the offset ('bx') is added to that, resulting in a valid address in
the _dos_ds segment.

My question was not weather InDOS can be accessed like this; I know it can
and have written some ISRs that in fact do it. My question was, if the
_far* functions perform some sort of memory protection, what is the result
when 'es' and 'bx' are garbage? Based on what you said, I now believe it
would be a SIGSEGV.

So, in summary, whenever you call an interrupt that returns an es->bx type
pointer, it -is- valid to read information at that address with code
similar to what I used to access InDOS above. Calling _far* with garbage
'es' and\or 'bx' will cause a SIGSEGV.

> Looks like I've got some research to do.

I find a good browsing of the libc.a reference and the include files (like
\djgpp\include\dpmi.h, \djgpp\include\go32.h, 
\djgpp\include\sys\farptr.h...) is often quite helpful in figuring these
things out.

> Could you please tell me what this InDOS flag is and how it works? I have
> heard it mentioned a couple of times.

The InDOS flag is part of the internal DOS data structures. Whenever a DOS
function is entered (INT 0x21, other DOS interrupts) this flag is
incremented. While this flag is nonzero, you -CANNOT- call any DOS
function, since DOS in non-reentrant; doing so will cause Bad Things(tm).
Therefore, whenever a properly-written, DOS-calling ISR enters, it checks
the InDOS flag, and if it is nonzero, does not do anything.

I recommend Ralf Brown's Interrupt List for more information.

late\fw


- Raw text -


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