Mail Archives: djgpp/1997/09/25/00:06:55
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, ®s) == -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 -