Array Management

Reference Section

ARRAY_ALLOC
_array_append
_array_bfind
ARRAY_CLEAR
ARRAY_CMPF
ARRAY_COUNT
_array_curn
_array_delete
ARRAY_EMPTY
ARRAY_ESIZE
ARRAY_FULL
_array_full
_array_init
_array_insert
_array_lfind
_array_lfindr
ARRAY_MAX
_array_next
_array_nth
_array_prev
_array_qsort
_bin_search
_lin_rsearch
_lin_search
_quick_sort

ARRAY_ALLOC


Descrip
(Macro) Allocates and initializes a structured array.

Syntax
#include <sa_array.h>
ARRAY_ALLOC(s_array, max, size, cmpf)

s_array is the name to be assigned to the structured array.
max is the number of array elements to reserve space for.
size is the size of each array element, in bytes (e.g., sizeof(int)).
cmpf is the name of the assembly comparison function to be used for this array (e.g., str_cmp).

Notes
This macro statically allocates space for a structured array in a source file. Space is allocated for max array elements, each of size bytes. The contents of the memory allocated for s_array is undefined.

The static specifier may be used with this macro to initialize all bytes in the array space to 0x00. For example:

static ARRAY_ALLOC (array1, 100, 4, str_cmp);/* init array elements to zero */

The following structure is used by this macro to define the array header and allocate memory for the array elements (MAX and SIZE denote the max and size parameters):

struct {
void(*cmpf)(void); /* assembly comparison function */
unsigned int size; /* size of each element */
unsigned int max; /* maximum number of elements */
unsigned int cnt; /* number of current elements */
char array[MAX][SIZE];/* location of first element in array */
};

The array field indicates the location of the first element of the array. All functions which operate on structured arrays expect the address of this field, NOT the address of the structure. Array header information may be accessed using the following macros:

ARRAY_COUNT(array) (array pntr -2) Current number of array elements
ARRAY_MAX(array) (array pntr -2) Maximum number of array elements
ARRAY_ESIZE(array) (array pntr -6) Size of each array element, in bytes
ARRAY_CMPF(array) (array pntr -8 small code models, -10 in large code models) User comparison function address

In addition, HEADER_SIZE is defined in ARRAY.H to indicate the exact size of the array header in the current memory model.

The comparison function (cmpf) is called every time array elements are compared by any of the structured array management functions. Therefore, the speed of the comparison function directly impacts the performance of the structured array sort/search functions. To maintain the advantage of the assembly language core to the sort/search functions, cmpf must have an assembly language interface. cmpf must preserve all registers while supporting the following inputs and outputs:

Comparison function inputs:

DS:SI address of the element to compare against (key)
ES:DI address of the element to compare (element)

Comparison function outputs:

JA if key would appear after element in the array (key is greater than element).

JE if key would appear at the same location as element in the array (key is equal to element).

JB if key would appear before element in the array (key is less than element).

Note that the return conditions for the comparison function only indicate whether key should appear before, at, or after (i.e., JB, JE, or JA) the position of element in the array. No assumptions are made about the elements themselves. This allows elements to contain any information, and it allows the array to be sorted in any order (i.e., ascending, descending, etc.). If each array element is a single ASCIIZ string, then str_cmp or str_cmpi may be used as the comparison function.

WARNING! To ensure compatibility with future releases, the HEADER_SIZE define should be used any time the size of the header needs to be known.

C/C++ Example
	{
	   void *location;
	   ARRAY_ALLOC (array1, 3, 4, str_cmp); /* use ASM cmpf */
	 
	   _array_insert(array1.array, "cat", array1.array[0]);
	   _array_append(array1.array, "car");
	   if(_array_bfind("aaa",array1.array, &location) != 0)
	      _array_insert(array1.array,"aaa",location);
	   	  	 /* make room for new element */
	   ...
	}

Inline Assembly Example
	{
	   char *str;
	   ARRAY_ALLOC (array1, 2, 4, str_cmp);/* use ASM cmpf */
	   lea bx,array1.array/* BX -> element[0] in array */
	   str = "cat";
	   mov si,str/* SI = offset of "cat" */
	   mov di,bx /* DI -> location to insert element */
	   array_insert();/* insert "cat" in array */
	   str = "can";
	   mov si,str/* SI = offset of "can" */
	   array_append(); /* append "can" in array */
	   ...
	}

Source file SA_ARRAY.H ASM equiv.ARRAY_ALLOC
See also
_array_init

_array_append


Descrip
Appends an element to the end of a structured array.

Syntax
#include <sa_array.h>
int _array_append(void far *s_array, const void far *element);

Returns
0 if element was successfully appended to s_array.

-1 if element could not be appended to s_array.

Notes
This function appends element to the end of s_array and increments the element count. If s_array is already full, 0 is returned and s_array remains unchanged.

WARNING! This function may only be used with structured arrays. Structured arrays may be created using ARRAY_ALLOC or _array_init.

C/C++ Example
	   ...
	   ARRAY_ALLOC (array1, 2, 4, str_cmp);/* use ASM cmpf */
	   _array_insert(array1.array, "cat", array1.array[0]);
	   _array_append(array1.array, "car");
	   if(_array_append(array1.array, "can") == -1)
	      _put_str("\n\rUnable to append element.");
	   ...

Inline Assembly Example
	{
	   char *str;
	   void *array_ptr; /* pointer to dynamic (structured) array */
	   ...
	   if((array_ptr = (char *)malloc(20+HEADER_SIZE)) == NULL)
	      exit(0);
	   mov di,array_ptr/* DI -> array */
	   mov  cx,4	/* CX = size of elements */
	   mov  bx,5	/* BX = number of elements */
	   mov  ax,offset str_cmp
	   array_init();
	   mov di,bx
	   str = "aaa";
	   mov si,str	/* SI -> "aaa" */
	   array_insert();   /* insert "aaa" */
	   str = "bbb";
	   mov si,str	/* SI -> "bbb" */
	   array_append();/* append "bbb" */
	   free(array_ptr);
	   ...
	}

Source file _ARAPPND.ASM ASM equiv ARRAY_APPEND
See also
_array_delete, _array_full, _array_init, _array_insert

_array_bfind


Descrip
Searches for an element in a structured array using a binary search.

Syntax
#include <sa_array.h>
int _array_bfind(const void far *key, const void far *s_array, void far **location);

Returns
0 if the element matching key was found in s_array.
location pointer to the matching array element

-1 if no elements matching key were found in s_array.
location pointer to the position where key may be inserted into s_array

Notes
This function searches s_array for an element matching key. The search is performed using a non-recursive binary search algorithm. If a matching element is found, 0 is returned and location points to element that matches key. If no matching elements are found, -1 is returned and location points to the position that a matching element would occupy in s_array if it were present. This address may be used with _array_insert to insert key into the array in sorted order.

WARNING! This function may only be used with structured arrays. Structured arrays may be created using ARRAY_ALLOC or _array_init. This function also expects the array to be in sorted order.

_array_qsort may be used to sort the array.

C/C++ Example
	   ...
	   ARRAY_ALLOC (array1, 3, 4, str_cmp);/* use ASM cmpf */
	   _array_insert(array1.array, "bbb", array1.array[0]);
	   _array_append(array1.array, "ccc");
	   if(_array_bfind("aaa",array1.array, &location) != 0)
	      _array_insert(array1.array,"aaa",location);
	   	  	 	/* make room for new element */
	...

Inline Assembly Example
	{
	   char *key;
	   ...
	   ARRAY_ALLOC (array1, 3, 4, str_cmp);
	   	  	 	/* allocate static array */
	   lea bx,array1.array/* BX -> array1.array */
	   key = "aaa";
	   mov si,key	/* SI -> element to insert */
	   mov di,bx	/* DI -> array1.array */
	   array_insert();    /* insert "bbb" in array */
	   key = "bbb";
	   mov si,key	/* SI -> element to insert */
	   array_append();    /* insert "ccc" in array */
	   key = "ccc";
	   mov si,key	/* SI -> comparison key */
	   array_bfind();	/* is "aaa" in array? */
	    jnca_bfnd_100/*   y: jump out */
	   array_append();    /*   n: insert in array */
	   ...
	a_bfnd_100:
	   ...
	}

Source file _ARBFIND.ASM ASM equiv ARRAY_BFIND
See also
_array_init, _array_insert, _array_lfind, _array_qsort, _bin_search

ARRAY_CLEAR


Descrip
(Macro) Clears a structured array.

Syntax
#include <sa_array.h>
ARRAY_CLEAR(s_array)
s_array is the address of the first element in a structured array

Returns
None

Notes
This macro clears s_array by setting its element count to zero. No other changes are made to s_array.

WARNING! This macro may only be used with structured arrays. Structured arrays may be created using ARRAY_ALLOC or _array_init.

C/C++ Example
	   ...
	   ARRAY_ALLOC (array1, 3, 4, str_cmp);
	   	  	 	/* use ASM comparison function */
	   _array_insert(array1.array, "bbb", array1.array[0]);
	   _array_delete(array1.array,array1.array[0]);
	   ARRAY_CLEAR(array1.array);/* set array count == 0 */
	   ...

Inline Assembly Example
	(Not applicable)

Source file SA_ARRAY.H ASM equiv .ARRAY_CLEAR
See also
_array_count, _array_init

ARRAY_CMPF


Descrip
(Macro) Returns the address of the comparison function.

Syntax
#include <sa_array.h>
void *ARRAY_CMPF(s_array)
s_array is the address of the first element in a structured array

Returns
Address of comparison function.

Notes
This macro returns the address of the assembly comparison function used by s_array.

WARNING! This macro may only be used with structured arrays. Structured arrays may be created using ARRAY_ALLOC or _array_init.

C/C++ Example
	{
	   char outbuf[80];
	   ARRAY_ALLOC (array1, 3, 4, str_cmp);
	   	  	 /* use ASM comparison function */
	   #if __LARGE_CODE__
	      _put_str(_ul_to_dec(ARRAY_CMPF(array1.array), outbuf));
	   #else
	      _put_str(_ui_to_dec(ARRAY_CMPF(array1.array), outbuf));
	   #endif
	   ...
	}

Inline Assembly Example
	(Not applicable)

Source file SA_ARRAY.H ASM equiv None

ARRAY_COUNT


Descrip
(Macro) Returns the number of elements in a structured array.

Syntax
#include <sa_array.h>
int ARRAY_COUNT(s_array)
s_array is the address of the first element in a structured array

Returns
Number of elements in the array.

Notes
This macro returns the number of elements currently in s_array.

WARNING! This macro may only be used with structured arrays. Structured arrays may be created using ARRAY_ALLOC or _array_init.

C/C++ Example
	{
	   char outbuf[80];
	   ...
	   ARRAY_ALLOC (array1, 3, 4, str_cmp);
	   _put_str(_i_to_dec(ARRAY_COUNT(array1.array), outbuf));
	   ...
	}

Inline Assembly Example
	(Not applicable)

Source file SA_ARRAY.H ASM equiv.ARRAY_COUNT
See also
_array_empty, _array_full, _array_init

_array_curn


Descrip
Returns the index of a specified element in a structured array.

Syntax
#include <sa_array.h>
unsigned int _array_curn(const void far *s_array, const void far *element);

Returns
Index of element in s_array.

-1 if element is invalid.

Notes
This function returns the index (element number) of element in s_array. Array elements are numbered zero through n-1, where n is the total number of elements currently in s_array. -1 is returned if element points past the last element in s_array.

WARNING! This function may only be used with structured arrays. Structured arrays may be created using ARRAY_ALLOC or _array_init.

C/C++ Example
	{
	unsigned index;
	   ...
	   ARRAY_ALLOC (array1, 3, 4, str_cmp);/* use ASM cmpf */
	   _array_insert(array1.array,"bbb",array1.array[0]);
	   _array_append(array1.array,"ccc");
	   index = _array_curn(array1.array,array1.array[1]);
	   	  	 	    /* index = 1 */
	   ...
	}

Inline Assembly Example
	{
	char *element;
	unsigned index;
	   ARRAY_ALLOC (array1, 3, 4, str_cmp);
	   lea bx,array1.array;
	   element = "bbb";
	   mov si,element/* SI -> "bbb" */
	   mov di,bx	 /* DI -> array1.array[0] */
	    array_insert();	/* insert first element */
	    element = "ccc";
	    mov si,element/* SI -> "ccc" */
	    array_append();	/* append "ccc" */
	    array_bfind();	 /* find "ccc", return address */
	    index = array_curn();/* index = 1 */
	    ...
	}

Source file _ARCURN.ASM ASM equiv ARRAY_CURN
See also
_array_init, _array_nth

_array_delete


Descrip
Removes an element from a structured array.

Syntax
#include <sa_array.h>
int _array_delete(void far *s_array, const void far *element);

Returns
0 if element was successfully deleted from array.

-1 if element was invalid.

Notes
This function removes element from s_array. Elements which reside beyond element in s_array are moved one position toward the start of s_array. The array count is decremented and 0 is returned. If element lies beyond the last element in s_array, -1 is returned and s_array remains unchanged.

WARNING! This function may only be used with structured arrays. Structured arrays may be created using ARRAY_ALLOC or _array_init.

C/C++ Example
	{
	   unsigned index;
	   ...
	   ARRAY_ALLOC (array1, 3, 4, str_cmp);/* use ASM cmpf */
	   _array_insert(array1.array,"bbb",array1.array[0]);
	   _array_delete(array1.array,array1.array[0]);
	   if(array1.cnt == 0)
	      _put_str("\n\rNo current elements in array.");
	   ...
	}

Inline Assembly Example
	{
	   char *element;
	   ...
	   ARRAY_ALLOC (array1, 3, 4, str_cmp);/* use ASM cmpf */
	   lea  bx,array1.array; /* BX = offset of array1.array[0] */
	   element = "bbb";
	   mov si,element    /* SI = offset "bbb" */
	   mov di,bx       /* DI = offset of array1.array[0] */
	   array_insert();      /* insert element */
	   array_delete();      /* delete element */
	   ...
	}

Source file _ARDELET.ASM ASM equiv ARRAY_DELETE
See also
_array_empty, _array_init, _array_insert, _array_nth

ARRAY_EMPTY


Descrip
(Macro) Indicates whether or not a structured array is empty.

Syntax
#include <sa_array.h>
int ARRAY_EMPTY(s_array)
s_array is the address of the first element in a structured array

Returns
1 if s_array is empty.

0 if s_array is not empty.

Notes
This macro indicates whether or not s_array is empty. A structured array is empty if its current element count is 0.

WARNING! This macro may only be used with structured arrays. Structured arrays may be created using ARRAY_ALLOC or _array_init.

C/C++ Example
	{
	   char outbuf[80];
	   ...
	   ARRAY_ALLOC (array1, 3, 4, str_cmp);
	   if(ARRAY_EMPTY(array1.array))
	      _put_str("Array is now empty.");
	   ...
	}

Inline Assembly Example
	(Not applicable)

Source file SA_ARRAY.H ASM equiv.ARRAY_EMPTY
See also
_array_count, _array_init

ARRAY_ESIZE


Descrip
(Macro) Returns the size of each element in a structured array.

Syntax
#include <sa_array.h>
int ARRAY_ESIZE(s_array)
s_array is the address of the first element in a structured array

Returns
Size of each array element.

Notes
This macro returns the size of each array element in s_array. All elements in the array are the same size.

WARNING! This macro may only be used with structured arrays. Structured arrays may be created using ARRAY_ALLOC or _array_init.

C/C++ Example
	{
	   char outbuf[80];
	   ...
	   ARRAY_ALLOC(array1, 3, 4, str_cmp);
	   _put_str(_i_to_dec(ARRAY_ESIZE(array1.array), outbuf));
	   ...
	}

Inline Assembly Example
	(Not applicable)

Source file SA_ARRAY.H ASM equiv.ARRAY_ESIZE
See also
_array_init

ARRAY_FULL


Descrip
(Macro) Indicates whether or not a structured array is full.

Syntax
#include <sa_array.h>
int ARRAY_FULL(s_array)
s_array is the address of the first element in a structured array

Returns
1 if s_array is full.

0 if s_array is not full.

Notes
This macro indicates whether or not s_array is full. A structured array is full if its current element count is greater than or equal to the maximum allowed number of array elements.

WARNING! This macro may only be used with structured arrays. Structured arrays may be created using ARRAY_ALLOC or _array_init.

C/C++ Example
	{
	   char outbuf[80];
	   ...
	   ARRAY_ALLOC (array1, 3, 4, str_cmp);
	   if(ARRAY_FULL(array1.array))
	      _put_str("Array is now full.");
	   ...
	}

Inline Assembly Example
	(Not applicable)

Source file SA_ARRAY.H ASM equiv.ARRAY_FULL
See also
ARRAY_CLEAR, ARRAY_COUNT, _array_init

_array_full


Descrip
Indicates whether or not a structured array is full.

Syntax
#include <sa_array.h>
int _array_full(const void far *s_array);

Returns
1 if s_array is full.

0 if s_array is not full.

Notes
This function indicates whether or not s_array is full. An array is full when the current array element count is greater than or equal to the maximum allowed number of array elements.

WARNING! This function may only be used with structured arrays. Structured arrays may be created using ARRAY_ALLOC or _array_init.

C/C++ Example
	{
	   char outbuf[80];
	   ...
	   ARRAY_ALLOC (array1, 3, 4, str_cmp);
	   if(_array_full(array1.array))
	      _put_str("Array is now full.");
	   ...
	}

Inline Assembly Example
	{
	   char *element;
	   char str[] = "Array is now full.";
	   ...
	   ARRAY_ALLOC (array1, 3, 4, str_cmp); /* use ASM cmpf */
	   lea  bx,array1.array; /* BX = offset of array1.array[0] */
	   array_full();
	    jnelabel_020
	   lea si,str
	   put_str();
	   ...
	label_020:
	   ...
	}

Source file _ARFULL.ASM ASM equiv ARRAY_FULL
See also
_array_clear, _array_count, _array_init

_array_init


Descrip
Initializes a structured array.

Syntax
#include <sa_array.h>
void far *_array_init(void far *s_array, unsigned int max, int size, void(*cmpf)(void));

Returns
A pointer to the first element in s_array.

Notes
This function dynamically initializes a structured array in s_array by creating an array header at that location. The array header is initialized to indicate that s_array is currently empty (no elements), that the size of each element is size bytes, that the maximum allowed number of array elements is max, and that the address of the comparison function to be used to compare elements is cmpf.

The array elements are not initialized. The address of the first byte past the header is returned. This is the address where the first array element will be inserted. It is also the address which must be used to refer to s_array whenever it is operated on by any array management function.

Structured arrays may be statically allocated and initialized using the ARRAY_ALLOC macro.

Since the array header precedes the first element in the array, array header information may be accessed using the following macros:

ARRAY_COUNT(s_array) (array pntr -2) Current number of array elements
ARRAY_MAX(s_array) (array pntr -2) Maximum number of array elements
ARRAY_ESIZE(s_array) (array pntr -6) Size of each array element, in bytes
ARRAY_CMPF(s_array) (array pntr -8 small code models, -10 in large code
models) User comparison function address

For example, the following instruction may be used to move the maximum number of array elements into num:

...
unsigned int num;
char *array, *array_ptr;
...
if ((char = (char *)malloc(20+HEADER_SIZE)) == NULL)
_put_str("Not enough memory");
else
{
array_ptr = _array_init(array, 5, 4, str_cmp);
num = ARRAY_MAX(array);/* num = max # of elements (5) */
}
...

In addition, HEADER_SIZE is defined in ARRAY.H to indicate the exact size of the array header in the current memory model.

The comparison function (cmpf) is called every time array elements are compared by any of the structured array management functions. Therefore, the speed of the comparison function directly impacts the performance of the structured array sort/search functions.

To maintain the advantage of the assembly language core to the sort/search functions, cmpf must have an assembly language interface. cmpf must preserve all registers while supporting the following inputs and outputs:

Comparison function inputs:

DS:SI address of the element to compare against (key)
ES:DI address of the element to compare (element)

Comparison function outputs:

JA if key would appear after element in the array (key is greater than element).

JE if key would appear at the same location as element in the array (key is equal to element).

JB if key would appear before element in the array (key is less than element).

Note that the return conditions for the comparison function only indicate whether key should appear before, at, or after (i.e., JB, JE, or JA) the position of element in the array. No assumptions are made about the elements themselves. This allows elements to contain any information, and it allows the array to be sorted in any order (i.e., ascending, descending, etc.). If each array element is a single ASCIIZ string, then str_cmp or str_cmpi may be used as the comparison function.

WARNING! To ensure compatibility with future releases, the HEADER_SIZE define should be used any time the size of the header needs to be known. This define may be used to determine the required size of the buffer for array.

The buffer for array must be large enough to accommodate the array header and all array elements or information following the buffer may be overwritten.

C/C++ Example
	{
	   int num;
	   void *array_ptr, *heap_array;
	   ...	  	 /* pointer to dynamic array */
	   if((array_ptr = (char *)malloc(20+HEADER_SIZE)) == NULL)
	      _put_str("Not enough memory for array initialization.");
	   else
	      heap_array = _array_init(array_ptr,5,4,str_cmp);
	   _array_insert(heap_array,"aaa",(char *)heap_array);
	   _array_append(heap_array,"bbb");
	   num = ARRAY_COUNT(heap_array);
	   	  	 /* num = number of elements (2) */
	   free(array_ptr);
	   ...
	}

Inline Assembly Example
	int test14(void)
	{
	   char *str;
	   void *array_ptr; /* pointer to dynamic (structured) array */
	   ...
	   if((array_ptr = (char *)malloc(20+HEADER_SIZE)) == NULL)
	         exit(0);
	   mov di,array_ptr/* DI -> array */
	   mov  cx,4	/* CX = size of elements */
	   mov  bx,5	/* BX = number of elements */
	   mov  ax,offset str_cmp
	   array_init();
	   mov di,bx
	   str = "aaa";
	   mov si,str	/* SI -> "aaa" */
	   array_insert();   /* insert "aaa" */
	   str = "bbb";
	   mov si,str	/* SI -> "bbb" */
	   array_append();/* append "bbb" */
	   free(array_ptr);
	   ...
	}

Source file _ARINIT.ASM ASM equiv ARRAY_INIT
See also
_array_alloc, _array_insert

_array_insert


Descrip
Inserts an element into a structured array.

Syntax
#include <sa_array.h>
int _array_insert(void far *s_array, const void far *element, void far *inspos);

Returns
0 if element was successfully inserted into s_array.

-1 if element could not be inserted into s_array because s_array was full.

Notes
This function inserts element into s_array at inspos. All elements from inspos to the end of s_array are moved toward the end of s_array to make room for element. If s_array is already full, -1 is returned and s_array is unchanged. If element is successfully inserted, the element count is incremented by one and 0 is returned.

WARNING! This function may only be used with structured arrays. Structured arrays may be created using ARRAY_ALLOC or _array_init.

C/C++ Example
	   ARRAY_ALLOC (array1, 2, 4, str_cmp);/* use ASM cmpf */
	   ...
	   _array_insert(array1.array, "cat", array1.array[0]);
	   	  /* insert "cat" as first element in array */
	   ...

Inline Assembly Example
	{
	   char str[] = "cat";
	   ARRAY_ALLOC (array1, 2, 4, str_cmp);/* use ASM cmpf */
	   lea bx,array1.array;/* BX -> array1.array[0] */
	   lea si,str	/* SI -> "cat" */
	   mov di,bx	/* DI -> array1.array[0] */
	   array_insert();    /* insert "cat" */
	   ...
	}

Source file _ARINSRT.ASM ASM equiv ARRAY_INSERT
See also
_array_append, _array_bfind, _array_delete, _array_init

_array_lfind


Descrip
Searches for an element in a structured array using a forward linear search.

Syntax
#include <sa_array.h>
void far *_array_lfind(const void far *key, const void far *s_array);

Returns
A pointer to the matching array element.

NULL if no elements matching key were found in s_array.

Notes
This function searches s_array for an element which matches key.

The search begins with the first element in s_array and continues with each succeeding element until a matching element is found or until all elements in s_array have been examined. If a matching element is found, a pointer to it is returned; otherwise, NULL is returned.

The array does not need to be in sorted order to use this function.

WARNING! This function may only be used with structured arrays. Structured arrays may be created using ARRAY_ALLOC or _array_init.

C/C++ Example
	{
	   char outstr[20], *location;
	   int num;
	   ARRAY_ALLOC(array1, 3, 4, mem_cmp);
	   ...
	   num = 1111;
	   _array_insert(array1.array, &num, array1.array[0]);
	   num = 3333;
	   _array_append(array1.array, &num);
	   num = 2222;
	   if((location = _array_lfind(&num, array1.array)) == NULL)
	      _array_append (array1.array, &num);  /* append 222 */
	   else
	   {
	      _put_str(_ui_to_dec((int)location, outstr));
	      _put_str(" found.");
	      _put_newline();
	   }
	   ...
	}

Inline Assembly Example
	{
	   int num;
	   ARRAY_ALLOC(array1, 3, 4, mem_cmp);
	    ...
	    lea bx,array1.array;/* BX -> array1.array */
	    lea si,num  	    /* SI -> num */
	    num = 111;
	    mov di,bx	 	/* DI -> array1.array */
	    array_insert();	    /* insert 111 */
	    num = 333;
	    array_append();	    /* append 333 */
	    num = 222;
	    array_lfind();	 	/* is 222 in array? */
	     jnca_lfind_100	/*   y: continue */
	    mov di,bx	 	/* reset DI */
	    array_append();	    /* append 222 */
	    ...
	a_lfind_100:
	    ...
	}

Source file _ARLFIND.ASM ASM equiv ARRAY_LFIND
See also
_array_bfind, _array_init, _array_lfind, _lin_search

_array_lfindr


Descrip
Searches for an element in a structured array using a reverse linear search.

Syntax
#include <sa_array.h>
void far *_array_lfindr(const void far *key, const void far *s_array);

Returns
A pointer to matching array element.

NULL if no elements matching key were found in s_array.

Notes
This function searches s_array for an element which matches key.

The search begins with the last element in s_array and continues with each preceding element until a matching element is found or until all elements in s_array have been examined. If a matching element is found, a pointer to its address is returned; otherwise, NULL is returned. The array does not need to be in sorted order to use this function.

WARNING! This function may only be used with structured arrays. Structured arrays may be created using ARRAY_ALLOC or _array_init.

C/C++ Example
	{
	   char outstr[20], *location;
	   int num;
	   ARRAY_ALLOC(array1, 3, 4, mem_cmp);
	   ...
	   num = 1111;
	   _array_insert(array1.array, &num, array1.array[0]);
	   num = 3333;
	   _array_append(array1.array, &num);
	   num = 2222;
	   if((location = _array_lfindr(&num, array1.array)) == NULL)
	      _array_append (array1.array, &num); /* append 2222 */
	   else
	   {
	      _put_str(_ui_to_dec((int)location, outstr)); 
	      _put_str(" found.");
	      _put_newline();
	   }
	   ...
	}

Inline Assembly Example
	{
	   int num;
	   ARRAY_ALLOC(array1, 3, 4, mem_cmp);
	   ...
	   lea bx,array1.array;/* BX -> array */
	   lea si,num 	    /* SI -> num */
	   num = 111;
	   mov di,bx	/* DI -> array1[0] */
	   array_insert();    /* insert 111 */
	   num = 333;
	   array_append();    /* append 333 */
	   num = 222;
	   array_lfindr();    /* is 222 in array? */
	    jncl_rfind_100/*   y: continue */
	   mov di,bx	/* reset DI -> array1[0] */
	   array_append();    /* append 222 */
	l_rfind_100:
	   ...
	}

Source file _ARRFIND.ASM ASM equiv ARRAY_LFINDR
See also
_array_init, _array_lfind, _lin_rsearch

ARRAY_MAX


Descrip
(Macro) Returns the maximum number of elements allowed in a structured array.

Syntax
#include <sa_array.h>
int ARRAY_MAX(s_array)
s_array is the address of the first element in the structured array

Returns
Maximum number of allowed elements.

Notes
This macro returns the maximum number of allowed elements in s_array.

WARNING! This macro may only be used with structured arrays. Structured arrays may be created using ARRAY_ALLOC or _array_init.

C/C++ Example
	{
	   char outbuf[80];
	   ...
	   ARRAY_ALLOC(array1, 3, 4, str_cmp);
	   _put_str(_i_to_dec(ARRAY_MAX(array1.array), outbuf));
	   ...
	}

Inline Assembly Example
	(Not applicable)

Source file SA_ARRAY.H ASM equiv None

_array_next


Descrip
Returns a pointer to the next element in a structured array.

Syntax
#include <sa_array.h>
void far *_array_next(const void far *s_array, const void far *element);

Returns
A pointer to the next element in s_array.

NULL if element is invalid or if it is the last element in s_array.

Notes
This function returns a pointer to the element in s_array which immediately follows element. NULL is returned if element is invalid or if it is the last element in s_array.

WARNING! This function may only be used with structured arrays. Structured arrays may be created using ARRAY_ALLOC or _array_init.

C/C++ Example
	{
	   ARRAY_ALLOC (array1, 5, 4, str_cmp);
	   ...
	   _array_insert(array1.array,"aaa",array1.array[0]);
	   _array_append(array1.array,"bbb");
	   _put_str(_array_next(array1.array, array1.array[0]));
	   	  	 	/* "bbb" */
	   ...
	}

Inline Assembly Example
	{
	   char *element;
	   ARRAY_ALLOC(array1, 5, 4, str_cmp);
	   ...
	   lea bx,array1.array;/* BX -> array[0] */
	   element = "aaa";
	   mov si,element/* SI -> "aaa" */
	   mov di,bx	/* DI -> array1.array[0] */
	   array_insert();    /* insert "aaa" */
	   element = "bbb";
	   mov si,element/* SI -> element to insert */
	   array_append();    /* append "bbb" */
	   array_next();
	   mov si,di	/* SI -> next element */
	   put_str();	/* "bbb" */
	   ...
	}

Source file _ARNEXT.ASM ASM equiv ARRAY_NEXT
See also
_array_init, _array_nth, _array_prev

_array_nth


Descrip
Returns a pointer to a structured array element given its index.

Syntax
#include <sa_array.h>
void far *_array_nth(const void far *s_array, unsigned int index);
Returns
A pointer to the array element which corresponds to index.

NULL if element is invalid.

Notes
This function returns a pointer to the element in s_array which corresponds to index, where index is the origin zero element number of the element in s_array. NULL is returned if s_array does not contain an element which corresponds to index.

WARNING! This function may only be used with structured arrays. Structured arrays may be created using ARRAY_ALLOC or _array_init.

C/C++ Example
	{
	   ARRAY_ALLOC (array1, 5, 4, str_cmp);
	   ...
	   _array_insert(array1.array,"aaa",array1.array[0]);
	   _array_append(array1.array,"bbb");
	   _put_str(_array_nth(array1.array, 0)); /* "aaa" */
	   ...
	}

Inline Assembly Example
	{
	   char *array, *element;
	   ARRAY_ALLOC (array1, 5, 4, str_cmp);
	   ...
	   lea bx,array1.array;
	   element = "aaa";
	   mov si,element/* SI -> element to insert */
	   mov di,bx         /* DI -> array1.array[0] */
	   array_insert();    /* insert "aaa" */
	   element = "bbb";
	   mov si,element/* SI -> element to insert */
	   array_append();    /* append "bbb" */
	   mov ax,0	/* element to return address of */
	   array_nth();
	   mov si,di	/* SI -> 0 element */
	   put_str();	/* "aaa" */
	   put_newline();
	   ...
	}

Source file _ARNTH.ASM ASM equiv ARRAY_NTH
See also
_array_curn, _array_init

_array_prev


Descrip
Returns a pointer to the previous element in a structured array.

Syntax
#include <sa_array.h>
void far *_array_prev(const void far *s_array, const void far *element);

Returns
A pointer to the previous element in s_array.
NULL if element is invalid or if it is the first element in s_array.

Notes
This function returns a pointer to the element in s_array which immediately precedes element. NULL is returned if element is the first element in s_array.

WARNING! This function may only be used with structured arrays. Structured arrays may be created using ARRAY_ALLOC or _array_init.

C/C++ Example
	ARRAY_ALLOC (array1, 5, 4, str_cmp);
	   ...
	   _array_insert(array1.array,"aaa",array1.array[0]);
	   _array_append(array1.array,"bbb");
	   _put_str(_array_prev(array1.array, array1.array[1]));
	   	  	 	/* "aaa" */
	   ...
	}

Inline Assembly Example
	{
	   char *element;
	   ...
	   ARRAY_ALLOC (array1, 5, 4, str_cmp); /* use ASM cmpf */
	   lea bx,array1.array	  /* BX -> first element */
	   element = "aaa";
	   mov si,element/* SI -> "aaa" */
	   mov di,bx	/* DI -> array1.array[0] */
	   array_insert();    /* insert "aaa" */
	   element = "bbb";
	   mov si,element/* SI -> "bbb" */
	   array_append();    /* append "bbb" */
	   add di,4	/* DI -> array1.array[1] */
	   array_prev();	/* locate previous element */
	   mov si,di	/* SI -> array1.array[0] */
	   put_str();	/*  "aaa" */
	   ...
	}

Source file _ARPREV.ASM ASM equiv ARRAY_PREV
See also
_array_init, _array_next, _array_nth

_array_qsort


Descrip
Sorts the elements in a structured array.

Syntax
#include <sa_array.h>
void far *_array_qsort(void far *s_array);

Returns
A pointer to the sorted array.

Notes
This function sorts the elements in s_array using a "median of three" recursive quicksort algorithm. The comparison function specified in the array header is used to compare s_array elements when sorting.

The sort algorithm used by this function is non-stable. (This means that the original order of identical elements is not preserved.)
WARNING! This function may use up to 32ùlog2n bytes of stack space plus the stack requirements of the comparison function, where n is the current number of elements in the array. 512 bytes of stack space is sufficient for the largest arrays. This function may also only be used with structured arrays. Structured arrays may be created using ARRAY_ALLOC or _array_init.

C/C++ Example
	{
	   int i;
	   ARRAY_ALLOC (array1, 3, 4, str_cmp);
	   ...
	  _array_insert(array1.array, "cat", array1.array[0]);
	  _array_append(array1.array, "cap");
	  _array_append(array1.array, "can");
	  _array_qsort(array1.array);    /* sort the array */
	  for (i = 0; i < 3; i++)
	    { _put_str(array1.array[i]); _put_chr(' ');};
	   	  	 	    /* "can cap cat" */
	   ...
	}

Inline Assembly Example
	{
	   char *element;
	   ARRAY_ALLOC (array1, 3, 4, str_cmp);
	   ...
	   lea bx,array1.array;/* BX -> array1.array[0] */
	   element = "cat";
	   mov si,element/* SI -> "cat" */
	   mov di,bx	/* DI -> array1.array[0] */
	   array_insert();    /* insert "cat" */
	   element = "can";
	   mov si,element/* SI -> "can" */
	   array_append();    /* append "can" */
	   element = "cap";
	   mov si,element/* SI -> "cap" */
	   array_append();    /* append "cap" */
	   array_qsort();	/* sort elements */
	   mov si,bx	/* SI -> array1.array[0] */
	   mov cx,3	/* CX = number of elements */
	   mov al,' '	/* AL = space character */
	a_out_100:
	   put_str();	/* display string element */
	   put_chr();	/*
	   add si,ARRAY_ESIZE/* SI -> next element */
	     loop a_out_100    /* "can cap cat" */
	   ...
	}

Source file _ARQSORT.ASM ASM equiv ARRAY_QSORT
See also
_array_bfind, _array_init, _quick_sort

_bin_search


Descrip
Locates an element in an array using a binary search.

Syntax
#include <sa_array.h>
int _bin_search(const void far *key, const void far *array, unsigned int num, int size, void(*cmpf)(void), void far * far * location);

Returns
0 if an element matching key was found in array.
location address of matching array element

-1 if no elements matching key were found in array.
location points to location where key may be inserted into array

Notes
This function searches array for an element matching key. The search is performed using a non-recursive binary search algorithm. If a matching element is found, location contains its address and 0 is returned. If no matching elements are found, -1 is returned and location indicates the position a matching element would occupy in array if it were present. This address may be used to insert key into the array in sorted order. To insert key into array, all elements at or beyond the returned address must be moved a distance of size bytes towards the end of the array; key may then be copied into array at the returned pointer position (see _array_insert).

Because the comparison function (cmpf) is called every time array elements are compared, the speed of the comparison function directly impacts the performance of _bin_search. To maintain the advantage of the assembly language core, cmpf must have an assembly language interface. cmpf must preserve all registers while supporting the following inputs and outputs:

Comparison function inputs:

DS:SI address of the element to compare against (key)
ES:DI address of the element to compare (element)

Comparison function outputs:

JA if key would appear after element in the array (key is greater than element).
JE if key would appear at the same location as element in the array (key is equal to element).
JB if key would appear before element in the array (key is less than element).

Note that the return conditions for the comparison function only indicate whether key should appear before, at, or after (JB, JE, or JA) the position of element in the array. No assumptions are made about the elements themselves. This allows elements to contain any information, and it allows the array to be sorted in any order (e.g., ascending, descending). If each array element is a single ASCIIZ string, then str_cmp or str_cmpi (no leading underscore) may be used as the comparison function.

WARNING! This function expects the array to be in sorted order. The same comparison function which is used to sort the array must be used to search the array. The total size of array must be less than 64K bytes. This function is designed to use only comparison functions that have an assembly interface.

C/C++ Example
	{
	   char *location;
	   char array2[3][4];
	   _str_cpy(array2[0],"bbb");
	   _str_cpy(array2[1],"ccc");
	   if(_bin_search("aaa",(char *)array2[0], 5, sizeof(array2[0]),
	                   str_cmp, &location) != 0)
	      _str_cpy(location,"aaa");/* add new element */
	   ...
	}

Inline Assembly Example
	#include <inline.h>
	{
	   char *str;
	   char array2[3][4];
	   
	   str = "bbb";
	   mov si,str	/* SI = offset of str */
	   lea di,array2[0]
	   str_cpy();	/* copy element to array */
	   str = "ccc";
	   mov si,str	/* SI = offset of str */
	   add di,4	/* DI = offset of array2[1] */
	   str_cpy();	/* append "ccc" to array */
	   str = "aaa";
	   mov si,str	/* SI = offset of str */
	   sub di,4	/* DI = offset of array2[0] */
	   mov bx,2	/* BX = number of elements */
	   mov cx,4	/* CX = size of elements */
	   lea ax,str_cmp/* AX = offset of cmpf */
	   bin_search();	/* is "aaa" in array? */
	    jncb_srch_100/*   y: continue */
	   str = "aaa";	/*   n: append "aaa" */
	   mov si,str	/* SI = offset of "aaa" */
	   add di,8	/* di = offset of next element */
	   str_cpy();	/* copy "aaa" into array */
	b_srch_100:
	   ...
	}

Source file _ARBFND2.ASM ASM equiv BIN_SEARCH
See also
_array_bfind, _quick_sort, _array_insert, _array_delete

_lin_rsearch


Descrip
Searches for an element in an array using a reverse linear search.

Syntax
#include <sa_array.h>
void far *_lin_rsearch(const void far *key, const void far *array, unsigned int num, int size, void(*cmpf)(void));

Returns
A pointer to the matching element in array.

NULL if an element matching key was not found in array.

Notes
This function searches for an element in array which matches key. The search begins with the last element in array and continues with each preceding element until a matching element is found or until there are no more elements in array. If a matching element is found, a pointer to its address is returned; otherwise, NULL is returned.

The array does not need to be in sorted order to use this function.

Because the comparison function (cmpf) is called every time array elements are compared, the speed of the comparison function directly impacts the performance of the _lin_rsearch function. To maintain the advantage of the assembly language core, cmpf must have an assembly language interface. cmpf must preserve all registers while supporting the following inputs and outputs:

Comparison function inputs:

DS:SI address of element to compare against (key)
ES:DI address of element to compare (element)

Comparison function outputs:

JA if key would appear after element in the array (key is greater than element).
JE if key would appear at the same location as element in the array (key is equal to element).
JB if key would appear before element in the array (key is less than element).

Note that the return conditions for the comparison function only indicate whether key should appear before, at, or after (i.e., JB, JE, or JA) the position of element in the array. No assumptions are made about the elements themselves. This allows elements to contain any information, and it allows the array to be sorted in any order (i.e., ascending, descending, etc.). If each array element is a single ASCIIZ string, then str_cmp or str_cmpi may be used as the comparison function.

WARNING! The total size of array must be less than 64K bytes. This function expects an assembly comparison function.

C/C++ Example
	{
	   char array1[3][4];
	   char *location;
	   _str_cpy (array1[0],"aaa");
	   _str_cpy (array1[1],"ccc");
	   if((location = (char *)_lin_rsearch("bbb",(void *)array1, 3, 
	   sizeof(array1[0]), str_cmp)) == NULL)
	      _str_cpy (array1[2], "bbb"); /* if "bbb" is not found */
	   else
	   {
	      _put_str(location); _put_str(" already in array.");
	      _put_newline();
	   } 
	   ...
	}

Inline Assembly Example
	#include <inline.h>
	{
	   char *str;
	   char array1[3][4];
	   ...
	   lea di,array1[0];/* DI = offset array1[0] */
	   str = "aaa";
	   mov si,str	/* SI = offset "aaa" */
	   str_cpy();	/* add element to array */
	   str = "ccc";
	   mov si,str	/* SI = offset "ccc" */
	   add di,4	/* DI -> array1[1] */
	   str_cpy();	/* add element to array */
	   str = "bbb";	
	   mov si,str	/* SI = offset "bbb" */
	   add di,4	/* DI -> array[2] */
	   mov cx,3	/* CX = number of elements */
	   mov bx,4	/* BX = size of each element */
	   mov ax,offset str_cmp /* AX = offset of cmpf */
	   lin_rsearch();	/* is "bbb" in array? */
	    jncl_rsrch_100
	   str_cpy();	/*   n: add to array */
	l_rsrch_100:
	   ...
	}

Source file _ARRFND2.ASM ASM equiv LIN_RSEARCH
See also
_array_lfind, _bin_search, _lin_search

_lin_search


Descrip
Searches for an element in an array using a forward linear search.

Syntax
#include <sa_array.h>
void far *_lin_search(const void far *key, const void far *array, unsigned int num, int size, void(*cmpf)(void));

Returns
A pointer to the matching element in array.

NULL if an element matching key was not found in array.

Notes
This function searches for an element in array which matches key. The search begins with the last element in array and continues with each preceding element until a matching element is found or until there are no more elements in array. If a matching element is found, a pointer is returned to the element in array; otherwise, NULL is returned.

The array does not need to be in sorted order to use this function.

Because the comparison function (cmpf) is called every time array elements are compared, the speed of the comparison function directly impacts the performance of the _lin_search function. To maintain the advantage of the assembly language core, cmpf must have an assembly language interface. cmpf must preserve all registers while supporting the following inputs and outputs:

Comparison function inputs:

DS:SI address of element to compare against (key)
ES:DI address of element to compare (element)

Comparison function outputs:

JA if key would appear after element in the array (key is greater than element).
JE if key would appear at the same location as element in the array (key is equal to element).
JB if key would appear before element in the array (key is less than element).

Note that the return conditions for the comparison function only indicate whether key should appear before, at, or after (i.e., JB, JE, or JA) the position of element in the array. No assumptions are made about the elements themselves. This allows elements to contain any information, and it allows the array to be sorted in any order (i.e., ascending, descending, etc.). If each array element is a single ASCIIZ string, then str_cmp or str_cmpi may be used as the comparison function.

WARNING! The total size of array must be less than 64K bytes.

C/C++ Example
	{
	   char array1[3][4];
	   char *location;
	   _str_cpy (array1[0],"aaa");
	   _str_cpy (array1[1],"ccc");
	   if((location = (char *)_lin_search("bbb",(void *)array1, 3, 
	   sizeof(array1[0]), str_cmp)) == NULL)
	      _str_cpy (array1[2], "bbb"); /* if "bbb" is not found */
	   else
	   {
	      _put_newline(); 
	      _put_str(location); _put_str("already in array.");
	   }
	   ...
	}

Inline Assembly Example
	#include <include.h>
	{
	   char *str;
	   char array1[3][4];
	   ...
	   lea di,array1[0];/* DI = offset array1[0] */
	   str = "aaa";
	   mov si,str	/* SI = offset "aaa" */
	   str_cpy();	/* add element to array */
	   str = "ccc";
	   mov si,str	/* SI = offset "ccc" */
	   add di,4	/* DI -> array1[1] */
	   str_cpy();	/* add element to array */
	   str = "bbb";	
	   mov si,str	/* SI = offset "bbb" */
	   sub di,4	/* DI -> array[0] */
	   mov cx,3	/* CX = number of elements */
	   mov bx,4	/* BX = size of each element */
	   mov ax,offset str_cmp /* AX = offset of cmpf */
	   lin_search();	/* is "bbb" in array? */
	    jncl_rsrch_100
	   add di,8	/* DI -> array[2] */
	   str_cpy();	/*   n: add to array */
	l_rsrch_100:
	   ...
	}

Source file _ARLFND2.ASM ASM equiv LIN_SEARCH
See also
array_lfind, _bin_search, _lin_rsearch

_quick_sort


Descrip
Sorts the elements in an array.

Syntax
#include <sa_array.h>
void far *_quick_sort(void far *array, unsigned int num, int size, void(*cmpf)(void));

Returns
A far pointer to sorted array.

Notes
This function sorts the elements in array using a "median of three" recursive quicksort algorithm. The comparison function (cmpf) is called every time array elements are compared. Therefore, the speed of the comparison function directly impacts the performance of the _quick_sort function. To maintain the advantage of the assembly language core to the _quick_sort function, cmpf must have an assembly language interface. cmpf must preserve all registers while supporting the following inputs and outputs:

Comparison function inputs:

DS:SI address of element to compare against (key)
ES:DI address of element to compare (element)

Comparison function outputs:

JA if key would appear after element in the array (key is greater than element).
JE if key would appear at the same location as element in the array (key is equal to element).
JB if key would appear before element in the array (key is less than element).

Note that the return conditions for the comparison function only indicate whether key should appear before, at, or after (i.e., JB, JE, or JA) the position of element in array. No assumptions are made about the elements themselves. This allows elements to contain any information, and it allows the array to be sorted in any order (i.e., ascending, descending, etc.). If each array element is a single ASCIIZ string, then str_cmp or str_cmpi may be used as the comparison function.

The sort algorithm used by this function is non-stable. (This means that the original order of identical elements is not preserved.)

WARNING! This function may use up to 32ùlog2n bytes of stack space plus the stack requirements of the comparison function, where n is the current number of elements in array. 512 bytes of stack space is sufficient for the largest arrays.

WARNING! The total size of array must be less than 64K bytes. This function is designed for use with an assembly interface comparison function only.

C/C++ Example
	{
	   char array2[5][4];
	   _str_cpy (array2[0],"cat");
	   _str_cpy (array2[1],"car");
	   _str_cpy (array2[2],"cab");
	   _str_cpy (array2[3],"cap");
	   _str_cpy (array2[4],"can");
	   _quick_sort((void *)array2, 5, sizeof(array2[0]), str_cmp);
	   ...
	}

Inline Assembly Example
	#include <inline.h>
	{
	   char *element;
	   char array1[5][4];
	   ...
	   pushss
	   pop es	 	/* ES=SS (segment of array) */
	   lea di,array1[0]/* DI = offset of array1[0] */
	   mov bx,di	/* BX = saved array offset */
	   element = "aaa";
	   mov si,element/* SI = offset of "aaa" */
	   str_cpy();	/* insert "aaa" */
	   add di,4	/* DI = offset of array1[1] */
	   element = "ddd";
	   mov si,element/* SI = offset of "ddd" */
	   str_cpy();	/* insert "ddd" */
	   add di,4	/* DI = offset of array1[2] */
	   element = "bbb";
	   mov si,element/* SI = offset of "bbb" */
	   str_cpy();	/* insert "bbb" */
	   add di,4	/* DI = offset of "array1[3] */
	   element = "ccc";
	   mov si,element/* SI = offset of "ccc" */
	   str_cpy();	/* insert "ccc" */
	   add di,4	/* DI = offset of "array[4] */
	   element = "eee";    
	   mov si,element/* SI = offset of "eee" */
	   str_cpy();	/* insert "eee" */
	   mov di,bx	/* reset DI = offset of array1 */
	   mov bx,5	/* BX = number of elements */
	   mov cx,4	/* CX = size of each element */
	   mov ax,offset str_cmp /* AX = offset of cmpf */
	#if __LARGE_CODE__
	   mov dx,seg str_cmp/* DX = segment of cmpf */
	#endif
	    quick_sort();  /* sort array */
	   ...
	}

Source file _ARQSRT2.ASM ASM equiv QUICK_SORT
See also
_array_qsort, _bin_search