🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Article View: comp.os.msdos.programmer
Article #1588

Re: More "Far Call in C"

#1588
From: Bernie Roehl
Date: Tue, 17 Jul 1990 14:59
61 lines
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!broehl
References: <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