Date: Wed, 24 Sep 1997 22:06:30 -0700 (MST) From: firewind To: Brett Porter cc: djgpp AT delorie DOT com Subject: Using "far" pointers In-Reply-To: <199709250334.NAA18495@rabble.uow.edu.au> Message-ID: MIME-Version: 1.0 Content-Type: TEXT/PLAIN; charset=US-ASCII Precedence: bulk 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