INF: XMS Usage with Compact, Large, or Huge Memory Model

ID Number: Q76064

6.00 6.00a 6.00ax

MS-DOS

Summary:

In Microsoft QuickC versions 2.5 and 2.51, and Microsoft C versions

6.0, 6.0a, 6.0ax, and C/C++ 7.0, and also in the Extended Memory

Specification (XMS) the "R6001: Null pointer assignment" error may be

encountered when writing XMS functions in the compact, large, or huge

memory model with inline assembly. The problem will appear if the

variables used in the inline assembly are global.

More Information:

The XMS comes with a library that works only with the small memory

model. A programmer who wants to implement the XMS with another memory

model must write his or her own library routines.

If you use the sample code provided in the XMS to find the address of

the XMS driver with the compact, large, or huge memory model, you must

make sure that all variables used in the inline assembly code are

declared as local variables.

If you do not use local variables, you will get the "R6001: null

pointer assignment" error.

For more information on the problem with inline assembly accessing

global data, please query on the following words:

inline and assembly and incorrectly and accesses and far and labels

Below is a sample program that finds the address of the XMS driver,

uses that address to get its version, and then displays it. The

program works with all memory models.

Sample Code

-----------

/***************************************************

LXMS.C : Sample program to get XMS driver address

and make a call to get its version. This

sample works with the large memory model

through inline assembly.

The trick here is to define all variables

used in the inline assembly as local.

****************************************************/

#include <stdlib.h>

#include <stdio.h>

#include <dos.h>

#define GET_VERSION 0

unsigned xms_call( void (_far *xms_driver)(),

unsigned call_number )

{

_asm

{

mov ah, call_number

call far ptr [xms_driver]

mov call_number, ax

}

return( call_number );

}

void main ( void )

{

unsigned int status;

void (_far *xms_driver) ( void );

unsigned int xms_version;

status = 0;

_asm

{

mov ax, 4300h

int 2Fh

cmp al, 80h

jne noXMS

;---- Get Driver Address for Later Requests ---

mov ax, 4310h

int 2Fh

mov word ptr [xms_driver], bx

mov word ptr [xms_driver+2], es

jmp End

noXMS:

mov xms_version, 0

mov status, ax

End:

}

xms_version = xms_call( xms_driver, GET_VERSION );

if(!xms_version) status = 80 ;

if(!status)

printf("\n XMS Driver %x Detected.\n",xms_version);

}

Additional reference words: 2.50 2.51 6.00 6.00a 6.00ax 7.00 extended

memory ems/xms specs