Mail Archives: djgpp-workers/1999/02/17/02:29:16
Somebody complained on c.o.m.d. that the flags set in an RMCB don't
get reflected back to the real-mode. See the thread called "How to
check the carry flag?" for details (the case in point was the keyboard
intercept call-out, Int 15h/AH=4Fh).
It turns out the wrapper set up by gormcb.c overwrites the flags in
the real-mode call structure with its original value (taken from the
real-mode stack). A relevant portion of the wrapper is attached to
this message. As you see, it takes the flags pushed onto the
real-mode stack from [esi+4] and plugs them into [edi+32], where the
flags are stored in the __dpmi_regs structure passed to the
user-defined callback.
This means it is impossible to modify flags that are returned to the
real mode.
I'm guessing that this was done for safety reasons (e.g., imagine that
the user code messes with the flags and sets, say, the V86 flag
there ;-). Is that the only reason?
If safety is all we need to be concerned about, we could mask off the
dangerous bits (i.e. pass them as they were originally pushed onto the
real-mode stack), but allow to pass those which cannot hurt. I think
at least CF and ZF should be passed, and possibly some more.
Comments?
static unsigned char wrapper_iret[] = {
0x66, 0x8b, 0x46, 0x04, /* mov ax,[esi+4] */
0x66, 0x26, 0x89, 0x47, 0x20, /* mov es:[edi+32],ax */
0x66, 0x26, 0x83, 0x47, 0x2e, 0x06, /* add es:[edi+46],0x6 */
0xcf /* iret */
};
- Raw text -