Article View: comp.os.msdos.programmer
Article #1588Re: More "Far Call in C"
From: Bernie Roehl
Date: Tue, 17 Jul 1990 14:59
Date: Tue, 17 Jul 1990 14:59
61 lines
2817 bytes
2817 bytes
In article <1990Jul9.195959.13596@ariel.unm.edu> saunders@hydra.unm.edu writes:
>Here is an example from the XMS docs:
>
> mov ax,4310h ; XMS int 2fh signiture
> int 2Fh
> mov word ptr [XMSControl],bx ; XMSControl is a DWORD
> mov word ptr [XMSControl+2],es
> ; We now have the XMS API entry point
> ; then we'de call an XMS function like this:
> mov ah,00h ; function code for "Get XMS version number"
> call [XMSControl]
There are a couple of ways of doing this. In Turbo C 2.00:
#include <dos.h>
void far (*xmsfn)();
...
union REGS r;
struct SREGS s;
r.x.ax = 0x4310;
int86x(0x2F, &r, &r, &s);
xmsfn = MK_FP(s.es, r.x.bx);
/* We now have the XMS API entry point */
_AX = 0;
(*xmsfn)();
Note that in Turbo C (and presumably other C's), no registers are used in
do the (*xmsfn)(); that line of code becomes the single instruction
"call dword ptr DGROUP:_xxx" (assuming the xxx is declared globally, which
it should be). Thus you can load up the _AX, _BX etc registers with
whatever you like before the call, and (if you're careful) get most of them
after the call. Not real elegant, but it works.
The other way to do it is:
#include <dos.h>
void interrupt (*xmsfn)(); /* Note interrupt, not far */
int xxx = 0x??; /* pick some unused interrupt vector */
...
union REGS r;
struct SREGS s;
r.x.ax = 0x4310;
int86x(0x2F, &r, &r, &s);
xmsfn = MK_FP(s.es, r.x.bx);
setvect(xxx, xmsfn);
r.h.ah = 0;
int86x(xxx, &r, &r, &s);
The advantage to this approach is that it makes no assumptions about what
code is generated by the compiler, and the technique should work similarly
under any reasonable C compiler; the disadvantage is that you have to find
one interrupt vector that you *know* isn't being used for anything else.
(It would be very nice if there were a "standard" vector for this purpose;
the best you can do is search (say, starting at 0x60 or so) for vectors
pointing to an IRET instruction).
--
Bernie Roehl, University of Waterloo Electrical Engineering Dept
Mail: broehl@watserv1.waterloo.edu OR broehl@watserv1.UWaterloo.ca
BangPath: {allegra,decvax,utzoo,clyde}!watmath!watserv1!broehl
Voice: (519) 747-5056 [home] (519) 885-1211 x 2607 [work]
Technical Details
Message-ID:
<1990Jul17.145927.2711@watserv1.waterloo.edu>Path:
arc1-ca.pugleaf.net!utzoo!attcan!uunet!dino!ux1.cso.uiuc.edu!iuvax!maytag!watserv1!broehlReferences:
<1990Jul9.195959.13596@ariel.unm.edu>Show Full Headers
Complete Article Headers
Path: arc1-ca.pugleaf.net!utzoo!attcan!uunet!dino!ux1.cso.uiuc.edu!iuvax!maytag!watserv1!broehl From: broehl@watserv1.waterloo.edu (Bernie Roehl) Newsgroups: comp.os.msdos.programmer,comp.sys.ibm.pc.programmer,alt.msdos.programmer Subject: Re: More "Far Call in C" Message-ID: <1990Jul17.145927.2711@watserv1.waterloo.edu> Date: 17 Jul 90 14:59:27 GMT References: <1990Jul9.195959.13596@ariel.unm.edu> Distribution: na Organization: University of Waterloo Lines: 61