Dec 122017
 
Nice (large) library of assembly language functions - the start of a public domain library. Full source code is included.
File STDLIB_A.ZIP from The Programmer’s Corner in
Category Assembly Language
Nice (large) library of assembly language functions – the start of a public domain library. Full source code is included.
File Name File Size Zip Size Zip Type
ADDCHAR.ASM 477 265 deflated
ADDSTR.ASM 698 361 deflated
ADDSTRL.ASM 892 438 deflated
ATOH.ASM 2162 738 deflated
ATOI.ASM 1703 660 deflated
ATOL.ASM 1872 711 deflated
COPYSET.ASM 863 394 deflated
CPUTYPE.ASM 11539 1989 deflated
CRSETS.ASM 988 463 deflated
CTYPES.ASM 841 273 deflated
DIFFSET.ASM 731 366 deflated
EMPTYSET.ASM 695 357 deflated
GETC.ASM 6401 2241 deflated
GETS.ASM 2187 955 deflated
HTOA.ASM 2312 819 deflated
INTERSET.ASM 726 357 deflated
ISIZE.ASM 1111 407 deflated
ITOA.ASM 2250 842 deflated
LSIZE.ASM 2106 610 deflated
LTOA.ASM 2588 936 deflated
LWRTBL.ASM 417 216 deflated
MEMBER.ASM 607 308 deflated
MEMORY.ASM 24095 6385 deflated
NEXTITEM.ASM 547 298 deflated
OLDTEST.ASM 30573 6245 deflated
PRINT.ASM 416 244 deflated
PRINTF.ASM 14719 3758 deflated
PUTC.ASM 3244 1022 deflated
PUTH.ASM 630 268 deflated
PUTI.ASM 819 360 deflated
PUTISIZE.ASM 1492 524 deflated
PUTL.ASM 1224 487 deflated
PUTLSIZE.ASM 1686 607 deflated
PUTS.ASM 446 241 deflated
RANGESET.ASM 676 339 deflated
RMVCHAR.ASM 490 273 deflated
RMVITEM.ASM 614 333 deflated
RMVSTR.ASM 698 371 deflated
RMVSTRL.ASM 952 460 deflated
SCANF.ASM 10637 2774 deflated
SER1.ASM 17909 5065 deflated
SHELL.ASM 2045 935 deflated
SPRINTF.ASM 16024 4003 deflated
STDLIB.A 24306 2820 deflated
STDLIB.DOC 143865 29054 deflated
STDLIB.LIB 29696 11524 deflated
STRCAT.ASM 893 415 deflated
STRCAT2.ASM 1983 740 deflated
STRCAT2L.ASM 2204 817 deflated
STRCATL.ASM 999 473 deflated
STRCHR.ASM 856 387 deflated
STRCMP.ASM 1906 828 deflated
STRCMPL.ASM 2058 810 deflated
STRCPY.ASM 956 457 deflated
STRCPYL.ASM 961 442 deflated
STRCSPAN.ASM 1297 552 deflated
STRCSPN2.ASM 1361 588 deflated
STRCSPNL.ASM 1425 608 deflated
STRDEL.ASM 1378 617 deflated
STRDEL2.ASM 1614 651 deflated
STRDUP.ASM 1046 459 deflated
STRDUPL.ASM 1162 510 deflated
STRICMP.ASM 2069 856 deflated
STRICMPL.ASM 2541 940 deflated
STRINS.ASM 1694 673 deflated
STRINS2.ASM 2321 865 deflated
STRINS2L.ASM 2553 959 deflated
STRINSL.ASM 1927 739 deflated
STRLEN.ASM 511 254 deflated
STRLWR.ASM 1037 474 deflated
STRREV.ASM 959 475 deflated
STRREV2.ASM 1388 614 deflated
STRSET.ASM 654 348 deflated
STRSET2.ASM 1113 532 deflated
STRSPAN.ASM 1251 536 deflated
STRSPANL.ASM 1402 594 deflated
STRSTR.ASM 1492 601 deflated
STRSTRL.ASM 1595 630 deflated
STRUPR.ASM 1017 460 deflated
TEST.ASM 30573 6234 deflated
TPCREAD.ME 199 165 deflated
UNIONSET.ASM 683 347 deflated
UPRTBL.ASM 417 213 deflated

Download File STDLIB_A.ZIP Here

Contents of the STDLIB.DOC file


***************************************************************************
***************************************************************************



The UCR Standard Library for Assembly Language Programmers,
Written By Randall Hyde and others, is

sssssss ss ss ss sssssss sssssss
ss ss ss ssss ss ss ss
ss ss ss ss ss ss ss ss
sssssss sssssssss ssssssss sssssss sssss ssssssss
ss ss ss ss ss ss ss ss
ss ss ss ss ss ss ss ss
sssssss ss ss ss ss ss ss sssssss



ww ww ww sssssss sssssss
ww ww wwww ss ss ss
ww ww ww ww ww ss ss ss
ww wwww ww wwwwwwww sssssss sssss
ww ww ww ww ww ww ss ss ss
wwww wwww ww ww ss ss ss
ww ww ww ww ss ss sssssss




We do not want any registration fees for this software.

Now for the catch... It is more blessed to give than to receive.
If this software saves you time and effort and you enjoy using it,
our lives will be enriched knowing that others have appreciated our work.
We would like to share this wonderful feeling with you. If you like this
software and use it, we would like you to contribute at least one routine to
the library. Perhaps you think this library has some neat-o routines in it.
Imagine how nice it would become if everyone used their imagination to
contribute something useful to it.

We hereby release this software to the public domain. You can use it in any
way you see fit. However, we would appreciate it if you share this software
with others as much as it has been shared it with you. That is not to suggest
that you give away software you have written with this package (We're not
quite as crazy as Richard Stallman, bless his heart), but if someone else would
like a copy of this library, please help them out. Naturally, we would be
tickeled pink to receive credit in software that uses these routines (which is
the honorable thing to do) but we understand the way many corporations operate
and won't be terribly put off if you use it without giving due credit.

Enjoy!

If you have comments, bug reports, new code to contribute, etc., you can
reach us through:

rhyde(On BIX).
[email protected](On Internet).
[email protected](Also on Internet).

or

Randy Hyde
Dept of Computer Science
2208 Sproul Hall
University of California
Riverside, Ca. 92521-0135


COMMENTS ABOUT THE CODE:
************************

Please don't expect super optimal code here. Most of it is fairly mediocre
(from a size/speed point of view). Hopefully, you'll agree, it's the idea
that counts. If you do not like something I have done, you have got the
sources -- have at it. (Of course, it would be appreciated if you would
send any modifications to one of the E-MAIL addresses above.)





ROUTINES WE WOULD LIKE TO HAVE:
*******************************

If you're interested in adding some routines to this
package, GREAT! Here are some suggestions.

1) Routines which manipulate directories (read/write/etc.)
2) A regular expression interpreter.
3) Length-prefixed strings package.
4) A graphics package.
5) An object-oriented programming class library.
6) Just about anything else appearing in a HLL "standard" library.
If you've got any ideas, we would love to discuss them with you. The best
way to reach us is through the E-MAIL addresses above.


MISSING ROUTINES TO BE SUPPLIED IN THE FUTURE:
**********************************************

Character strings:
trim-Removes trailing blanks from a string.
blkdel-Removes leading blanks from a string.
translit-Transliterates characters in a string based on a translation
table.


Pattern matching and character sets:
span-Skips through a sequence of characters in a string which
belong to a character set.
break-Skips through a sequence of characters in a string which do not
belong to a character set.
any-Skips over a character if it is a member of a set.
notany-Skips over a character in a string if it is not a member
of a set.
tab-Matches upto the nth character in a string.
rtab-Matches upto the nth character from the end of a string.
pos-Matches if we are currently at the nth position in a string.
rpos-Matches if we are at the nth position from the end of the
string.
mark-Marks a position in a string during pattern matching
grab-Copies everything from the last mark and creates a new string
on the stack from this substring.
match-Initialize pattern matching system.
alternate-Try an alternative if the current pattern does not match.
arb-Skip over an arbitrary number of characters in a match.
replace-Replace a substring from the last mark to the current
position with some other string.
fail-Force a match failure.
succeed-Force a match success.


Memory Manager Package
Memavail-Largest block of free memory available on the heap.
Memfree-Total amount of free space on the heap.
BlockSize-Returns the size of the memory block which es:di points at.


Structured Array Package
aryalloc-Allocate storage for a single dimension structured array.
ary2alloc-Allocate storage for a two dimension structured array.
ary3alloc-Allocate storage for a three dimension structured array.
arynalloc-Allocate storage for an n-dimensional structured array.
aryaccess-Access an element of a structured array.
ary2access-Access an element of a two-dimension structured array.
ary3access-Access an element of a three-dimension structured array.
arynaccess-Access an element of an n-dimensional structured array.
copyarray-Copy the elements of one structured array to another.
duparray-Duplicate a structured array on the heap.
redim-Redimension a structured array.
aryfill-Initialize an array with a list of values.
cmpary-Compares two structured arrays to see if they are equal.


Process Manager Package
CoCall-Call a coroutine.
CoInit-Initialize a coroutine.
CoRet-Quit a coroutine.


HOW TO USE THE STANDARD LIBRARY:
********************************

When you are ready to begin programming with the library, you should
copy the shell.asm file, provided in the package, to another file in
which you will be working, i.e. myprog.asm. The shell.asm file sets
up the machine (segments, etc.) as the UCR Standard Library expects
them. Results are undefined for other setups. Therefore, I strongly
suggest, that when you begin using these routines, you follow the
shell.asm format. Later, when you are familiar with the software,
you may wish to create your own shell.asm file, but it is wise to
initially use the one provided. The shell.asm file has comments which
tell you where to place your code, variables, etc.


HOW THE STANDARD LIBRARY IS ORGANIZED:
**************************************

In the next several pages are the documentation spec sheets for each of the
standard library routines. The routines are listed by category. The listing
of the categories and their order in the documentation is below.

Standard Input Routines
Standard Output Routines
Conversion Routines
Utility Routines
String Handling Routines
Memory Management Routines
Character Set Routines

In addition, at the beginning of each of the category is a brief
discussion of the purpose of its routines.





Character Input Routines
------------------------


The character input routines take input from either a standard
device (keyboard, etc.) or a standard library. After the character input
routines receive the characters they either place the characters on the stack
and/or return. The character input routines work similar to the "C" character
input routines.



Routine: Getc
--------------


Category: Character Input Routine


Registers on Entry: None


Registers on Return: AL- Character from input device.
AH- 0 if eof, 1 if not eof.


Flags Affected: Carry- 0 if no error, 1 if error. If error occurs, AX
contains DOS error code.


Example of Usage:
getc
mov KbdChar, al
putc


Description: This routine reads a character from the standard input device.
This call is synchronous, that is, it does not return until a
character is available. The Default input device is DOS
standard input.

Getc returns two types of values: extended ASCII (codes 1-255)
and IBM keyboard scan codes. If Getc returns a non-zero value,
you may interpret this value as an ASCII character. If Getc
returns zero, you must call Getc again to get the actual
keypress.

The second call returns an IBM PC keyboard scan code.

Since the user may redirect input from the DOS command line,
there is the possibility of encountering end-of-file (eof)
when calling getc. Getc uses the AH register to return eof
status. AH contains the number of characters actually read
from the standard input device. If it returns one, then
you've got a valid character. If it returns zero, you've
reached end of file. Note that pressing control-z forces an
end of file condition when reading data from the keyboard.

This routine returns the carry flag clear if the operation
was successful. It returns the carry flag set if some sort
of error occurred while reading the character. Note that eof
is not an error condition. Upon reaching the end of file,
Getc returns with the carry flag clear. If getc is seen from
a file the control-z is not seen as an end-of-file marker,
but just read in as a character of the file.

Control-c if read from a keyboard device aborts the program.
However if when reading something other than a keyboard
(files, serial ports), control-c from the input source
returns control-c. However when pressing control-break
the program will abort regardless of the input source.

Regarding CR/LF, if the input is from a device, (eg. keyboard
serail port) getc returns whatever that device driver returns,
(generally CR without a LF). However if the input is from
a file, getc stripes a single LF if it immediately follows
the CR.

When using getc the files operate in "cooked" mode. While
devices operate in "pseudo-cooked" mode, which means no
buffering, no CR -> CR/LF, but it handles control-c, and
control-z.

If reading from a file, getc calls DOS (AH = 3Fh). If reading
from a device, getc calls DOS (AH = 8), it also uses IOCTL
call (AX = 4400h) to determine if the input is a file or a
device.

Include: stdlib.a




Routine: GetcStdIn
--------------------


Category: Character Input Routine


Register on entry: None.


Register on return: AL- Character from input device.


Flags affected: AH- 0 if eof, 1 if not eof.
Carry- 0 if no error, 1 if error
(AX contains DOS error code if error occurs).


Example of Usage:
GetcStdIn
mov InputChr, al
putc


Description: This routine reads a character from the DOS standard input
device. This call is synchronous, that is, it does not return
until a character is available. See the description of Getc
above for more details.


Include: stdlib.a






Routine: GetcBIOS
-------------------


Category: Character Input Routine


Register on entry: None


Register on return: AL- Character from the keyboard.


Flags affected: AH- 1 (always). Carry- 0 (always).


Example of Usage:
GetcBIOS
mov CharRead, al
mov ScanCode, ah
putc


Description: This routine reads a character from the keyboard. This call is
synchronous, that is it does not return until a character is
available.



Include: stdlib.a



Routine: SetInAdrs
-------------------

Category: Character Input Routine


Registers on Entry: ES:DI - address of new input routine


Registers on return: None


Flags affected:


Example of Usage:

mov es, seg NewInputRoutine
mov di, offset NewInputRoutine
SetInAdrs
les di, RoutinePtr
SetInAdrs


Description: This routine redirects the stdlib standard input so that it
calls the routine who's address you pass in es:di. This
routine obtains a character (from anywhere) returns it in AL,
and must preserve all registers. If it makes sense to do so,
it should also return a "scan code" in the AH register.


Include: stdlib.a






Routine: GetInAdrs
--------------------


Category: Character Input Routine


Register on entry: None


Register on return: ES:DI - address of current input routine (called by Getc).


Flags affected: None


Example of Usage:
GetInAdrs
mov word ptr SaveInAdrs, di
mov word ptr SaveInAdrs+2, es


Description: You can use this function to get the address of the current
input routine, perhaps so you can save it or see if it is
currently pointing at some particular piece of code.
If you want to temporarily redirect the input and then restore
the original input or outline, consider using
PushInAdrs/PopInAdrs described later.


Include: stdlib.a




Routine: PushInAdrs
---------------------


Category: Character Input Routine


Register on entry: ES:DI - Address of new input routine.


Register on return: Carry=0 if operation successful.
Carry=1 if there were already 16 items on the stack.


Example of Usage:
mov es, seg NewInputRoutine
mov di, offset NewInputRoutine
PushInAdrs
.
.
.
les di, RoutinePtr
PushInAdrs


Description: This routine "pushes" the current input address onto an
internal stack and then stores the value in es:di into the
current input routine pointer. The PushInAdrs and PopInAdrs
routines let you easily save and redirect the standard output
and then restore the original output routine address later on.
If you attempt to push more than 16 items on the stack,
PushInAdrs will ignore your request and return with the
carry flag set. If PushInAdrs is successful, it will
return with the carry flag clear.


Include: stdlib.a





Routine: PopInAdrs
--------------------


Category: Character Input Routine


Register on entry: None


Register on return: ES:DI - Points at the previous stdout routine before
the pop.


Example of Usage:
mov es, seg NewInRoutine
mov di, offset NewInputRoutine
PushInAdrs
.
.
.
PopInAdrs


Description: PopInAdrs undoes the effects of PushInAdrs. It pops an item
off the internal stack and stores it into the input routine
pointer. The previous value in the output pointer is returned
in es:di.

Include: stdlib.a





Routine: Gets
--------------


Category: Character Input Routine


Register on entry: None


Register on return: ES:DI - address of input of text.
carry- 0 if no error, 1 if error.
If error, AX contains: 0- End of
file encountered in middle of
string. 1- Memory allocation error.
Other- DOS error code.


Flags affected: None

Example of usage:
gets ;Read a string from the
;keyboard
puts ;Print it
putcr ;Print a new line
free ;Deallocate storage for
;string.

Description: Reads a line of text from the stdlib standard input device.
Automatically allocates storage for the input string on the
heap. Handles input lines up to 256 characters long.
Gets reads a line of text from the stdlib standard input.
It returns a pointer to a string containing each character read
in the ES:DI registers. Gets calls malloc to allocate 256 bytes
on the heap (plus any overhead bytes required by the memory
manager system). If the user enters less than 256 bytes, gets
calls realloc to free any unnecessary bytes. Gets returns all
characters typed by the user except for the carriage return
(ENTER) key code. Gets always returns a zero - terminated
string. The action of various keys to gets depends upon where
input has been directed. Generally, you can count on gets
properly handling the backspace (erase previous character),
escape (erase entire line), and ENTER (accept line) keys.
Other keys may be active as well. For example, by default gets
calls getc which calls DOS' standard input routine. If you
type a control-C or break key while reading from DOS' standard
input it will abort the program. If this bothers you, you can
always redirect stdlib's getc routine so it calls BIOS directly
rather than reading data through DOS' keyboard input routine.
Note that the error condition is flagged a little differently
for GETS (compared to GETC and associated routines). For GETS,
eof is an error condition. If the carry flag is set and AX
contains zero upon return, then GETS encountered eof somewhere
in the string. ES:DI contain garbage in such a case. Note that
AX is normally preserved by GETS unless an error occurs, in
which case AX contains the error code.


Include: stdlib.a





Routine: Scanf
---------------


Category: Character Input Routine


Register on entry: None


Register on return: None


Flags affected: None


Example of usage:
scanf
db "%i %h %^s",0
dd i, x, sptr

Description: * Formatted input from stdlib standard input.
* Similar to C's scanf routine.
* Converts ASCII to integer, unsigned, character, string, hex,
and long values of the above.
Scanf provides formatted input in a fashion analogous to
printf's output facilities. Actually, it turns out that scanf
is considerably less useful than printf because it doesn't
provide reasonable error checking facilities (neither does C's
version of this routine). But for quick and dirty programs
whose input can be controlled in a rigid fashion (or if you're
willing to live by "garbage in, garbage out") scanf provides
a convenient way to get input from the user. Like printf, the
scanf routine expects you to follow the call with a format
string and then a list of (far pointer) memory addresses. The
items in the scanf format string take the following form: %^f,
where f represents d, i, x, h, u, c, x, ld, li, lx, or lu.
Like printf, the "^" symbol tells scanf that the address
following the format string is the address of a (far) pointer
to the data rather than the address of the data location itself.
By default, scanf automatically skips any leading whitespace
before attempting to read a numeric value. You can instruct
scanf to skip other characters by placing that character in the
format string. For example, the following call instructs scanf
to read three integers separated by commas (and/or whitespace):

scanf db "%i,%i,%i",0
dd i1,i2,i3

Whenever scanf encounters a non-blank character in the format
string, it will skip that character (including multiple
occurrences of that character) if it appears next in the input
stream. Scanf always calls gets to read a new line of text
from stdlib's standard input. If scanf exhausts the format
list, it ignores any remaining characters on the line. If
scanf exhausts the input line before processing all of the
format items, it leaves the remaining variables unchanged.
Scanf always deallocates the storage allocated by gets.


Include: stdlib.a





Character Output Routines
-------------------------


The stdlib character output routines allow you to print to the
standard output device. Although the processing of non-ASCII
characters is undefined, most output devices handle these characters
properly. In particular, they can handle return, line feed, back space,
and tab.

Most of the output routines in the standard library output data
through the Putc routine. They generally use the AX register upon
entry and print the character(s) to the standard output device by
calling DOS by default. The output is redirectable to the
user-written routine. However, the PutcBIOS routine prints doesn't
use DOS. Instead it uses BIOS routines to print the character in AL
using the INT command for teletype-like output.

The print routines are similar to those in C, however, they differ
in their implementation. The print routine returns to the address
immediately following the terminating byte, therefore, it is important
to remember to terminate your string with zero or you will print an
unexpected instruction.



Routine: Putc
--------------


Category: Character Output Routine


Registers on Entry: AL- character to output


Registers on Return: None


Flags affected: None


Example of Usage:

mov al, 'C'
putc ;Prints "C" to std output.


Description: Putc is the primitive character output routine. Most other
output routines in the standard library output data through
this procedure. It prints the ASCII character in AL register.
The processing of control codes is undefined although most output
routines this routine links to should be able to handle return,
line feed, back space, and tab. By default, this routine calls
DOS to print the character to the standard output device. The
output is redirectable to to user-written routine.


Include: stdlib.a



Routine: PutCR
---------------


Category: Character Output Routine


Register on entry: None


Register on return: None


Flags affected: None


Example of Usage: PutCR


Description: Using PutCR is an easy way of printing a newline to the stdlib
standard output. It prints a newline (carriage return/line feed)
to the current standard output device.


Include: stdlib.a





Routine: PutcStdOut
-------------------


Category: Character Output Routine


Registers on Entry: AL- character to output


Registers on Return: None


Flags Affected: None


Example of Usage:
mov AL, 'C'
PutcStdOut ; Writes "C" to standard output


Description: PutcStdOut calls DOS to print the character in AL to the standard
output device. Although processing of non-ASCII characters and
control characters is undefined, most output devices handle these
characters properly. In particular, most output devices properly
handle return, line feed, back space, and tab. The output is
redirectable via DOS I/O redirection.


Include: stdlib.a



Routine: PutcBIOS
-----------------


Category: Character Output Routine


Registers on Entry: AL- character to print


Registers on Return: None


Flags Affected: None


Example of Usage:
mov AL, "C"
PutcBIOS


Description: PutcBIOS prints the character in AL using the BIOS routines,
using INT 10H/AH=14 for teletype-like output. Output through
this routine cannot be redirected; such output is always sent
to the video display on the PC (unless, of course, someone has
patched INT 10h). Handles return, line feed, back space, and
tab. Prints other control characters using the IBM Character set.


Include: stdlib.a






Routine: GetOutAdrs
-------------------


Category: Character Output Routine


Registers on Entry: None


Registers on Return: ES:DI- address of current output routine (called by Putc)


Flags Affected: None


Example of Usage:
GetOutAdrs
mov word ptr SaveOutAdrs, DI
mov word ptr SaveOutAdrs+2, ES

Description: GetOutAdrs gets the address of the current output routine, perhaps
so you can save it or see if it is currently pointing at some
particular piece of code. If you want to temporarily redirect the
output and then restore the original output routine, consider
using PushOutAdrs/PopOutAdrs described later.

Include: stdlib.a




Routine: SetOutAdrs
--------------------


Category: Character Output Routine


Registers on Entry: ES:DI - address of new output routine


Registers on return: None


Flags affected: None


Example of Usage:

mov es, seg NewOutputRoutine
mov di, offset NewOutputRoutine
SetOutAdrs
les di, RoutinePtr
SetOutAdrs

Description: This routine redirects the stdlib standard output so that it
calls the routine who's address you pass in es:di. This routine
expects the character to be in AL and must preserve all registers.
It handles the printable ASCII characters and the four control
characters return, line feed, back space, and tab. (The routine
may be modified in the case that you wish to handle these codes in
a different fashion.)


Include: stdlib.a



Routine: PushOutAdrs
---------------------


Category: Character Output Routine


Registers on Entry: ES:DI- Address of new output routine


Registers on Return: None


Flags Affected: Carry = 0 if operation is successful
Carry = 1 if there were already 16 items on the stack


Example of Usage:
mov ES, seg NewOutputRoutine
mov DI, offset NewOutputRoutine
PushOutAdrs
.
.
.
les DI, RoutinePtr
PushOutAdrs


Description: This routine "pushes" the current output address onto an internal
stack and then stores the value in es:di into the current output
routine pointer. The PushOutAdrs and PopOutAdrs routines let you
easily save and redirect the standard output and then restore the
original output routine address later on. If you attempt to push
more than 16 items on the stack, PushOutAdrs will ignore your
request and return with the carry flag set. If PushOutAdrs is
successful, it will return with the carry flag clear.


Include: stdlib.a





Routine: PopOutAdrs
--------------------


Category: Character Output Routine


Registers on Entry: None


Registers on Return: ES:DI- Points at the previous stdout routine before
the pop


Flags Affected: None


Example of Usage:
mov ES, seg NewOutputRoutine
mov DI, offset NewOutputRoutine
PushOutAdrs
.
.
.
PopOutAdrs


Description: PopOutAdrs undoes the effects of PushOutAdrs. It pops an item off
the internal stack and stores it into the output routine pointer.
The previous value in the output pointer is returned in es:di.
Defaults to PutcStdOut if you attempt to pop too many items off
the stack.

Include: stdlib.a






Routine: Puts
--------------


Category: Character Output Routine


Register on entry: ES:DI register - contains the address of the string


Register on return: None


Flags affected: None


Example of Usage:
les di, StrToPrt
puts
putcr


Description: Puts prints a zero-terminated string whose address appears
in es:di. Each character appearing in the string is printed
verbatim. There are no special escape characters. Unlike
the "C" routine by the same name, puts does not print a
newline after printing the string. Use putcr if you want
to print the newline after printing a string with puts.


Include: stdlib.a




Routine: Puth
--------------


Category: Character Output Routine


Register on entry: AL


Register on return: AL


Flags affected: None


Example of Usage:
mov al, 1fh
puth


Description: The Puth routine Prints the value in the AL register as two
hexadecimal digits. If the value in AL is between 0 and 0Fh,
puth will print a leading zero. This routine calls the stdlib
standard output routine (putc) to print all characters.


Include: stdlib.a








Routine: Putw
--------------


Category: Character Output Routine


Registers on Entry: AX- Value to print


Registers on Return: None


Flags Affected: None


Example of Usage:
mov AX, 0f1fh
putw


Description: The Putw routine prints the value in the AX register as four
hexadecimal digits (including leading zeros if necessary).
This routine calls the stdlib standard output routine (putc)
to print all characters.

Include: stdlib.a



Routine: Puti
--------------


Category: Character Output Routine


Registers on Entry: AX- Value to print


Registers on Return: None


Flags Affected: None


Example of Usage:
mov AX, -1234
puti


Description: Puti prints the value in the AX register as a decimal integer. This
routine uses the exact number of screen positions required to
print the number (including a position for the minus sign, if the
number is negative). This routine calls the stdlib standard
output routine (putc) to print all characters.


Include: stdlib.a





Routine: Putu
--------------


Category: Character Output Routine


Register on entry: AX register


Register on return: None


Flags affected: None


Example of Usage:
mov ax, 1234
putu


Description: Putu prints the value in the AX register as a decimal integer.
This routine uses the exact number of screen positions required
to print the number. This routine calls the stdlib standard
output routine (putc) to print all characters.


Include: stdlib.a





Routine: Putl
--------------


Category: Character Output Routine


Register on entry: DX:AX register


Register on return: None


Flags affected: None


Example of Usage:
mov dx, 0ffffh
mov ax, -1234
putl


Description: Putl prints the value in the DX:AX registers as a decimal integer.
This routine uses the exact number of screen positions
required to print the number (including a position for the
minus sign, if the number is negative). This routine calls
the stdlib standard output routine (putc) to print all
characters.


Include: stdlib.a




Routine: Putul
---------------


Category: Character Output Routine


Register on entry: DX:AX register


Register on return: None


Flags affected: None


Example of Usage:
mov dx, 12h
mov ax, 1234
putul


Description: Putul prints the value in the DX:AX registers as a decimal integer.
This routine uses the exact number of screen positions required
to print the number. This routine calls the stdlib standard
output routine (putc) to print all characters.


Include: stdlib.a






Routine: PutISize
------------------


Category: Character Output Routine


Registers on Entry: AX - value to print
CX - Minimum number of print positions to use


Registers on return: None


Flags affected:


Example of Usage:
mov cx, 5
mov ax, I
PutISize
.
.
.
mov cx, 12
mov ax, J
PutISize


Description: PutISize prints the signed integer value in AX to the
stdlib standard output device using a minimum of n print
positions. CX contains n, the minimum field width for the
output value. The number (including any necessary minus sign)
is printed right justified in the output field.
If the number in AX requires more print positions than
specified by CX, PutISize uses however many print positions
are necessary to actually print the number. If you specify
zero in CX, PutISize uses the minimum number of print positions
required. Of course, PutI will also use the minimum number
of print positions without disturbing the value in the CX
register.

Note that, under no circumstances, will the number in AX
ever require more than size print positions (-32,767 requires
the most print positions).


Include: stdlib.a





Routine: PutUSize
------------------


Category: Character Output Routine


Registers on entry: AX and CX


Registers on return: None


Flags affected: None


Example of usage:
mov cx, 8
mov ax, U
PutUSize


Description: PutUSize prints the value in AX as an unsigned decimal integer. Prints
the number in a minimum field width specified by the value in CX.
Like PutISize above except this one prints unsigned values.
Note that the maximum number of print positions required by any
number (e.g., 65,535) is five.


Include: stdlib.a




Routine: PutLSize
------------------


Category: Character Output Routine


Register on entry: DX:AX register


Register on return: None


Flags affected: None


Example of Usage:
mov cx, 16
mov dx, word ptr L+2
mov ax, word ptr L
PutLSize


Description: PutLSize is similar to PutISize, except this prints the long
integer value in DX:AX. Note that there may be as many as
11 print positions (e.g., -1,000,000,000).

Include: stdlib.a





Routine: PutULSize
-------------------


Category: Character Output Routine


Register on entry: AX : DX and CX


Register on return: None


Flags affected: None


Example of usage: mov cx, 8
mov dx, word ptr UL+2
mov ax, word ptr UL
PutULSize


Description: Prints the value in DX:AX as a long unsigned decimal integer.
Prints the number in a minimum field width specified by the
value in CX. Just like PutLSize above except this one prints
unsigned numbers rather than signed long integers. The largest
field width for such a value is 10 print positions.


Include: stdlib.a



Routine: Print
----------------


Category: Character Output Routine


Register on entry: CS:RET - Return address points at the string to print.


Register on return: None


Flags affected: None


Examples of Usage: print
db "Print this string to the display device"
db 13,10
db "This appears on a new line"
db 13,10
db 0


Description: Print lets you print string literals in a convenient
fashion. The string to print immediately follows the call
to the print routine. The string must contain a
zero terminating byte and may not contain any intervening
zero bytes. Since the print routine returns to the address
immediately following the zero terminating byte, forgetting
this byte or attempting to print a zero byte in the middle
of a literal string will cause print to return to an
unexpected instruction. This usually hangs up the machine.
Be very careful when using this routine!


Include: stdlib.a






Routine: Printf
---------------------


Category: Character Output Routine


Register on entry: CS:RET - Return address points at the format string


Register on return: None


Flags affected: None


Example of Usage:
printf
db "Indirect access to i: %^d",13,10,0
dd IPtr;
printf
db "A string allocated on the heap: %-\.32^s"
db 13,10,0
dd SPtr



Descriptions: Printf, like its "C" namesake, provides formatted output
capabilities for the stdlib package. A typical call to printf
always takes the following form:

printf
db "format string",0
dd operand1, operand2, ..., operandn

The format string is comparable to the one provided in the
"C" programming language. For most characters, printf simply
prints the characters in the format string up to the
terminating zero byte. The two exceptions are character
prefixed by a backslash ("\") and character prefixed by a
percent sign ("%"). Like C's printf, stdlib's printf uses
the backslash as an escape character and the percent sign as
a lead-in to a format string.

Printf uses the escape character ("\") to print special
characters in a fashion similar to, but not identical to C's
printf. Stdlib's printf routine supports the following
special characters:

* r Print a carriage return (but no line feed)
* n Print a new line character (carriage return/line feed).
* b Print a backspace character.
* t Print a tab character.
* l Print a line feed character (but no carriage return).
* f Print a form feed character.
* \ Print the backslash character.
* % Print the percent sign character.
* 0xhh Print ASCII code hh, represented by two hex digits.

C users should note a couple of differences between stdlib's
escape sequences and C's. First, use "\%" to print a percent
sign within a format string, not "%%". C doesn't allow the
use of "\%" because the C compiler processes "\%" at compile
time (leaving a single "%" in the object code) whereas printf
processes the format string at run-time. It would see a single
"%" and treat it as a format lead-in character. Stdlib's
printf, on the other hand, processes both the "\" and "%" and
run-time, therefore it can distinguish "\%".

Strings of the form "\0xhh" must contain exactly two hex
digits. The current printf routine isn't robust enough to
handle sequences of the form "\0xh" which contain only a
single hex digit. Keep this in mind if you find printf
chopping off characters after you print a value.

There is absolutely no reason to use any escape character
sequences except "\0x00". Printf grabs all characters
following the call to printf up to the terminating zero byte
(which is why you'd need to use "\0x00" if you want to print
the null character, printf will not print such values).
Stdlib's printf routine doesn't care how those characters got
there. In particular, you are not limited to using a single
string after the printf call. The following is perfectly legal:


printf
db "This is a string",13,10
db "This is on a new line",13,10
db "Print a backspace at the end of this line:"
db 8,13,10,0


Your code will run a tiny amount faster if you avoid the use
of the escape character sequences. More importantly, the
escape character sequences take at least two bytes. You can
encode most of them as a single byte by simply embedding the
ASCII code for that byte directly into the code stream.
Don't forget, you cannot embed a zero byte into the code
stream. A zero byte terminates the format string. Instead,
use the "\0x00" escape sequence.

Format sequences always between with "%". For each format
sequence you must provide a far pointer to the associated
data immediately following the format string, e.g.,
printf
db "%i %i",0
dd i,j

Format sequences take the general form "%s\cn^f" where:

* "%" is always the "%" character. Use "\%" if you
actually want to print a percent sign.
* s is either nothing or a minus sign ("-").
* "\c" is also optional, it may or may not appear in
the format item. "c" represents any printable
character.
* "n" represents a string of 1 or more decimal digits.
* "^" is just the caret (up-arrow) character.
* "f" represents one of the format characters: i, d, x,
h, u, c, s, ld, li, lx, or lu.

The "s", "\c", "n", and "^" items are optional, the "%" and
"f" items must be present. Furthermore, the order of these
items in the format item is very important. The "\c" entry,
for example, cannot precede the "s" entry. Likewise, the "^"
character, if present, must follow everything except the "f"
character(s).

The format characters i, d, x, h, u, c, s, ld, li, lx, and
lu control the output format for the data. The i and d
format characters perform identical functions, they tell
printf to print the following value as a 16-bit signed
decimal integer. The x and h format characters instruct
printf to print the specified value as a 16-bit or 8-bit
hexadecimal value (respectively). If you specify u, printf
prints the value as a 16-bit unsigned decimal integer.
Using c tells printf to print the value as a single character.
S tells printf that you're supplying the address of a
zero-terminated character string, printf prints that string.
The ld, li, lx, and lu entries are long (32-bit) versions of
d/i, x, and u. The corresponding address points at a 32-bit
value which printf will format and print to the standard output.
The following example demonstrates these format items:

printf
db "I= %i, U= %u, HexC= %h, HexI= %x, C= %c, "
db "S= %s",13,10
db "L= %ld",13,10,0
dd i,u,c,i,c,s,l

The number of far addresses (specified by operands to the "dd"
pseudo-opcode) must match the number of "%" format items in
the format string. Printf counts the number of "%" format
items in the format string and skips over this many far
addresses following the format string. If the number of
items do not match, the return address for printf will be
incorrect and the program will probably hang or otherwise
malfunction. Likewise (as for the print routine), the format
string must end with a zero byte. The addresses of the items
following the format string must point directly at the memory
locations where the specified data lies.

When used in the format above, printf always prints the
values using the minimum number of print positions for each
operand. If you want to specify a minimum field width, you
can do so using the "n" format option. A format item of the
format "%10d" prints a decimal integer using at least ten
print positions. Likewise, "%16s" prints a string using at
least 16 print positions. If the value to print requires
more than the specified number of print positions, printf
will use however many are necessary. If the value to print
requires fewer, printf will always print the specified number,
padding the value with blanks. Printf will print the value
right justified in the print field (regardless of the data's
type). If you want to print the value left justified in the
output file, use the "-" format character as a prefix to the
field width, e.g.,

printf
db "%-17s",0
dd string

In this example, printf prints the string using a 17 character
long field with the string left justified in the output field.
By default, printf blank fills the output field if the value
to print requires fewer print positions than specified by the
format item. The "\c" format item allows you to change the
padding character. For example, to print a value, right
justified, using "*" as the padding character you would use
the format item "%\*10d". To print it left justified you
would use the format item "%-\*10d". Note that the "-" must
precede the "\*". This is a limitation of the current
version of the software. The operands must appear in this
order. Normally, the address(es) following the printf
format string must be far pointers to the actual data to print.
On occasion, especially when allocating storage on the heap
(using malloc), you may not know (at assembly time) the
address of the object you want to print. You may have only
a pointer to the data you want to print. The "^" format
option tells printf that the far pointer following the format
string is the address of a pointer to the data rather than
the address of the data itself. This option lets you access
the data indirectly.

Note: unlike C, stdlib's printf routine does not support
floating point output. There are two reasons for this: first,
stdlib does not (yet) have a floating point library associated
with it; second, adding floating point support would increase
the size of printf by a tremendous amount, even if you don't
use its floating point capabilities. Since most assembly
language programmers don't use floating point arithmetic,
I've intentionally left out floating point output. As soon as
I add a floating point package to stdlib I will include
floating point output. However, I will create a new routine,
printf which includes floating point output. This will
allow those who never use floating point I/O to keep their
programs much smaller.


Include: stdlib.a





Conversion Routines
-------------------


The stdlib conversion routines follow a uniform format of storing the data
to be converted and returned. Most routines accept input and return data
of either an ASCII string of characters, stored in the ES:DI register, or
integers, stored in the DX:AX register. If a value is just a 16 or 8-bit
value then it will be stored in AX or AL.

Since there is a possibility of an error in the input values to be converted,
such as it does not contain what is supposed to be converted, we use the
carry flage to show error status. If the error flag is one then an error has
occured and if it is zero no error occured.

The routines which convert integers to strings of characters will automatically
allocated storage. It allocates storage for the string on the heap via a call
to the malloc routine. The string will hold the minimun number of characters
required to hold the character representation of the value. It is up to the
programmer to free the memory after it has been used.





Routine: ATOL/ATOL2
--------------------


Category: Conversion Routine


Registers on Entry: ES:DI- Points at string to convert


Registers on Return: DX:AX- Long integer converted from string


Flags Affected: Carry flag- Error status


Examples of Usage:
gets ;Get a string from user
ATOL ;Convert to a value in DX:AX


Description: ATOL converts the string of digits that ES:DI points at to a
long (signed) integer value and returns this value in DX:AX.
Note that the routine stops on the first non-digit.
If the string does not begin with a digit, this routine returns
zero. The only exception to the "string of digits" only rule is
that the number can have a preceding minus sign to denote a
negative number. Note that this routine does not allow leading
spaces. ATOL2 works in a similar fashion except it doesn't
preserve the DI register. That is, ATOL2 leaves DI pointing at
the firsy character beyond the string of digits. ATOL/ATOL2 both
return the carry flag clear if it translated the string of digits
without error. It returns the carry flag set if overflow
occurred.


Include: stdlib.a




Routine: AtoUL
---------------


Category: Conversion Routine


Register on entry: ES:DI (contains the address of the string to be converted)


Register on return: DX:AX (contains the 32-bit unsigned integer)


Flags affected: Carry flag (Carry flag = 1 if error)
(Carry flag = 0 if no error)

Examples of Usage:
les InputString
AtoUL


Description: AtoUL converts the string pointed by ES:DI to a 32-bit unsigned
integer. It places the 32-bit unsigned integer into the memory
address pointed by DX:AX. If there is an error in conversion,
the carry flag will set to one. If there is not an error, the
carry flag will be set to zero.


Include: stdlib.a




Routine: AtoUL2
----------------


Category: Conversion Routine


Register on entry: ES:DI (contains the address of the string to be converted)


Register on return: DX:AX (contains the 32-bit unsigned integer)
DI (if error, DI will have the first character that
is not a character)


Flags affected: Carry flag (Carry = 0 if no error)
(Carry = 1 if error)

Example of Usage:
les InputString
AtoUL2


Description: AtoUL2 converts the string pointed by ES:DI to a 32-bit unsigned
integer. It places the 32-bit unsigned integer into the memory
address pointed by DX:AX. If there is an error in conversion,
the carry flag will set to one, and DI will contain the first
non-digit character in the string. If there is not an error, the
carry flag will be clear.


Include: stdlib.a



Routine: ATOU/ATOU2
--------------------------


Category: Conversion Routine


Register on entry: ES:DI points at string to convert


Register on return: AX register - unsigned 16-bit integer


Flags affected: carry flag - error status


Example of Usage:


Description: ATOU converts an ASCII string of digits, pointed to by ES:DI,
to unsigned integer format. It places the unsigned 16-bit
integer, converted from the string, into the AX register.
ATOI works the same, except it handle unsigned 16-bit integers
in the range 0..65535.


Include: stdlib.a






Routine: ATOH, ATOH2
--------------------


Category: Conversion Routine


Registers on Entry: ES:DI- Points to string to convert


Registers on Return: AX- Unsigned 16-bit integer converted from hex string
DI (ATOH2)- First character beyond string of hex digits


Flags Affected: Carry = Error status


Example of Usage:
les DI, Str2Convrt
atoh ;Convert to value in AX.
putw ;Print word in AX.


Description: ATOH converts a string of hexadecimal digits, pointed to by
ES:DI, into unsigned 16-bit numeric form. It returns the value in
the AX register. If there is an error in conversion, the carry
flag will set to one. If there is not an error, the carry flag
will be clear. ATOH2 works the same except if an error occured
DI points to the first character beyond the string of hex digits.


Include: stdlib.a








Routine: ATOLH, ATOLH2
----------------------


Category: Conversion Routine


Registers on Entry: ES:DI- Points to string to convert


Registers on Return: DX:AX- Unsigned 32-bit integer converted from hex string
DI (ATOLH2)- First character beyond string of hex digits


Flags Affected: Carry = Error status


Example of Usage:
les DI, Str2Convrt
atolh ;Convert to value in DX:AX

Description: ATOLH converts a string of hexadecimal digits, pointed to by
ES:DI, into unsigned 32-bit numeric form. It returns the value in
the DX:AX register. If there is an error in conversion, the carry
flag will set to one. If there is not an error, the carry flag
will be clear. ATOLH2 works the same except if an error occured
DI points to the first character beyond the string of hex digits.


Include: stdlib.a




Routine: ATOI
---------------


Category: Conversion Routine


Register on entry: ES:DI- Points at string to convert.


Register on return: AX- Integer converted from string.
DI (ATOI2)- First character beyond string of digits.


Flags affected: Error status


Examples of Usage:


Description: Works just like ATOL except it translates the string to a
signed 16-bit integer rather than a 32-bit long integer.


Include: stdlib.a



Routine ITOA
------------


Category: Conversion Routine


Registers on Entry: AX- Signed 16-bit value to convert to a string


Registers on Return: ES:DI- Pointer to string containing converted
characters.


Flags Affected: None


Example of Usage:
mov ax, -1234
ITOA ;Convert to string.
puts ;Print it.
free ;Deallocate string.


Description: ITOA converts the signed integer value in AX to a string of
characters which represents that value. It allocates storage
for the string on the heap via a call to the malloc routine
and returns a pointer to the string in ES:DI. The string
contains the minimum number of characters required to hold the
character representation of the value, which is always between
one and six characters long.


Include: stdlib.a




Routine: UTOA
---------------


Category: Conversion Routine


Register on entry: AX - unsigned 16-bit integer to convert to a string


Register on return: ES:DI register - pointer to a string containing
converted characters


Flags affected: None


Example of Usage:
mov ax, 65000
utoa
puts
free


Description: UTOA converts a 16-bit unsigned integer value in AX to a
string of characters which represents that value. It
allocates storage for the string on the heap via a call to
the malloc routine and returns a pointer to the string in
ES:DI. The string contains the minimum number of characters
required to hold the character representation of the value,
which is always between one and five characters long.


Include: stdlib.a






Routine: HTOA
---------------


Category: Conversion Routine


Register on entry: AL - 8-bit integer to convert to a string


Register on return: ES:DI register - pointer to a string containing
converted characters


Flags affected: None


Description: HTOA converts an 8-bit value in AL to the two-character
hexadecimal representation of that byte. It automatically
allocates storage for the string on the heap via a call to
the malloc routine and returns a pointer to the string in
ES:DI. This routine always outputs exactly two
hexadecimal digits, including a leading zero (if necessary).


Include: stdlib.a




Routine: WTOA
--------------


Category: Conversion Routine


Registers on Entry: AX- 16-bit value to convert to a string


Registers on Return: ES:DI- Pointer to string containing
converted characters.


Flags Affected: None


Example of Usage:
Like HTOA above


Description: WTOA converts the 16-bit value in AX to a string of four
hexadecimal digits. It automatically allocates storage for
the string on the heap via a call to the malloc routine and
returns a pointer to the string in ES:DI. Outputs exactly four
digits including leading zeros if necessary.


Include: stdlib.a





Routine: LtoA
--------------


Category: Conversion Routine


Register on entry: DX:AX (contains a signed 32 bit integer)


Register on return: ES:DI (contains the address of the converted string)


Flags affected: None


Example of Usage:
ltoa


Description: LtoA converts a 32-bit signed integer pointed by DX:AX to
a string pointed by ES:DI. Note: LtoA only converts from one
to eleven characters.


Include: stdlib.a





Routine: ULTOA
---------------


Category: Conversion Routine


Registers on Entry: DX:AX- Unsigned 32-bit value to convert to a string


Registers on Return: ES:DI- Pointer to string containing converted
characters


Flags Affected: None


Example of Usage:
Like LTOA


Description: Like LTOA except this routine handles unsigned integer values.
Automatically allocates storage for string converted
characters.

Include: stdlib.a





Routine: SPrintf
-----------------


Category: Conversion Routine
In-Memory Formatting Routine


Register on entry: CS:RET - Pointer to format string and operands of the
sprintf routine


Register on return: ES:DI register - pointer to a string containing
output data


Flags affected: None


Example of Usage:
sprintf
db "I=%i, U=%u, S=%s",13,10,0
db i,u,s
puts
free


Description: SPrintf is an in-memory formatting routine. It is similar to
C's sprintf routine. It automatically allocates storage
for the string on the heap.
The programmer selects the maximum length of the output string.
SPrintf works in a manner quite similar to printf, except sprintf
writes its output to a string variable rather than to the stdlib
standard output. Sprintf returns a pointer to the string
(which is allocates on the heap) in the ES:DI registers.
SPrintf, by default, allocates 2048 characters for this string
and then deallocates any unnecessary storage. An external
variable, sp_MaxBuf, holds the number of bytes to allocate upon
entry into sprintf. If you wish to allocate more or less than
2048 bytes when calling sprintf, simply change the value of this
public variable (type is word). Sprintf calls malloc to
allocate the storage dynamically. You should call free to
return this buffer to the heap when you are through with it.


Include: stdlib.a





Routine: BPrintf
------------------


Category: Conversion Routine
In-Memory Formatting Routine


Register on entry: CS:RET - Pointer to format string and operands of the
sprintf routine

ES:DI - Pointer to buffer area to store string data


Register on return: None


Flags affected: None


Example of Usage:
les di, BufferAdrs
bprintf
db "I=%i, U=%u, S=%s",13,10,0
db i,u,s
puts


Description: BPrintf works just like SPrintf except it does not automatically
allocate storage for the output string. Instead, you must
supply the address of an output buffer in the ES:DI registers.


Include: stdlib.a






Routine: SScanf
----------------


Category: Conversion Routine
Formatted In-Memory Conversion Routine


Registers on Entry: ES:DI - points at string containing values to convert


Registers on return: None


Flags affected:


Example of Usage:

; this code reads the values for i, j, and s from the characters
; starting at memory location Buffer.

les di, Buffer
SScanf
db "%i %i %s",0
dd i, j, s


Description: SScanf provides formatted input in a fashion analogous to scanf.
The difference is that scanf reads in a line of text from the
stdlib standard input whereas you pass the address of a sequence
of characters to SScanf in es:di.


Include: stdlib.a




Routine: ToLower
-----------------


Category: Conversion Routine

Register on entry: AL- Character to (possibly) convert
to lower case.

Register on return: AL- Converted character.


Flags affected: None


Example of usage:
mov al, char
ToLower



Description: ToLower checks the character in the AL register, if it is upper
case it converts it to lower case. If it is anything else,
ToLower leaves the value in AL unchanged. For high performance
this routine is implemented as a macro rather than as a
procedure call. This routine is so short you would spend more
time actually calling the routine than executing the code inside.
However, the code is definitely longer than a (far) procedure
call, so if space is critical and you're invoking this code
several times, you may want to convert it to a procedure call to
save a little space.


Include: stdlib.a




Routine: ToUpper
------------------


Category: Conversion Routine


Registers on Entry: AL- Character to (possibly) convert to upper case


Registers on Return: AL- Converted character


Flags Affected: None


Example of Usage:
mov al, char
ToUpper



Description: ToUpper checks the character in the AL register, if it is lower
case it converts it to upper case. If it is anything else,
ToUpper leaves the value in AL unchanged. For high performance
this routine is implemented as a macro rather than as a
procedure call (see ToLower, above).


Include: stdlib.a





Utility Routines
----------------


The following 10 routines are all Utility Routines. The first routines listed
below compute the number of print positions required by a 16-bit and 32-bit
signed and unsigned integer value. UlSize is like the LSize except it treats
the value in DX:AX as an unsigned long integer. The next set of routines in
this section check the character in the AL register to see whether it is a
hexidecimal digit, if it alphabetic, if it is a lower case alphabetic, if it
is a upper case alphabetic, and if it is numeric.




Routine: ISize
---------------


Category: Utility Routine


Register on entry: AX- 16-bit value to compute the
output size for.


Register on return: AX- Number of print positions
required by this number (including
the minus sign, if necessary).


Flags affected: None


Example of usage:
mov ax, I
ISize
puti ;Prints positions
;req'd by I.


Description: This routine computes the number of print positions
required by a 16-bit signed integer value. ISize computes
the minimum number of character positions it takes to print
the signed decimal value in the AX register. If the number
is negative, it will include space for the minus sign in
the count.


Include: stdlib.a






Routine: USize
---------------


Category: Utility Routine


Register on entry: AX- 16 bit value to compute the
output size for


Register on return: AX- number of print positions
required by this number (including
the minus sign, if necessary)


Flags affected: None


Example of usage:
mov ax, I
USize
puti ;prints position
;required by I


Description: This routine computes the number of print positions
required by a 16-bit signed integer value. It also
computes the number of print positions required by a
16-bit unsigned value. USize computes the minimum number
of character positions it will take to print an unsigned
decimal value in the AX register. If the number is
negative, it will include space for the minus sign in the
count.


Include: stdlib.a







Routine: LSize
---------------


Category: Utility Routine


Register on entry: DX:AX - 32-bit value to compute the
output size for.


Register on return: AX - Number of print positions
required by this number (including
the minus sign, if necessary).


Flags affected: None


Example of Usage:
mov ax, word ptr L
mov dx, word ptr L+2
LSize
puti ;Prints positions
;req'd by L.


Description: This routine computes the number of print positions
required by a 32-bit signed integer value. LSize computes
the minimum number of character positions it will take to
print the signed decimal value in the DX:AX registers. If
the number is negative, it will include space for the minus
sign in the count.


Include: stdlib.a










Routine: ULSize
----------------


Category: Utility Routine


Registers on Entry: DX:AX - 32-bit value to compute the output size for.


Registers on return: AX - number of print positions required by this number


Flags affected: None


Example of Usage:
mov ax, word ptr L
mov dx, word ptr L+2
ULSize
puti ; Prints positions req'd by L


Description: ULSize computes the minimum number of character
positions it will take to print an unsigned decimal
value in the DX:AX registers.


Include: stdlib.a





Routine: IsAlNum
-----------------


Category: Utility routine


Register on entry: AL - character to check.


Register on return: None


Flags affected: Zero flag - set if character is alpha- numeric,
clear if not.


Example of usage : mov al, char
IsAlNum
je IsAlNumChar


Description : This routine checks the character in the AL register to
see if it is in the range A-Z, a-z, or 0-9. Upon return,
you can use the JE instruction to check to see if the
character was in this range (or, conversely, you can use
JNE to see if it is not in range).



Include: stdlib.a






Routine: IsXDigit
------------------


Category: Utility Routine


Retgister on Entry: AL- character to check


Registers on Return: None


Flags Affected: Zero flag- Set if character is a hex digit, clear if not


Example of Usage: mov al, char
IsXDigit
je IsXDigitChar


Description: This routine checks the character in the AL register to
see if it is in the range A-F, a-f, or 0-9. Upon
return, you can use the JE instruction to check to see
if the character was in this range (or, conversely,
you can use jne to see if it is not in the range).


Include: stdlib.a







Routine: IsDigit
------------------


Category: Utility Routine


Register on entry: AL- Character to check


Register on return: Zero flag- set if character is numeric, clear if not.


Flags affected: None


Example of Usage: mov al, char
IsDigit
je IsDecChar


Description: This routine checks the character in the AL register to
see if it is in the range 0-9. Upon return, you can use
the JE instruction to check to see if the character was
in the range (or, conversely, you can use JNE to see if it
is not in the range).


Include: stdlib.a






Routine: IsAlpha
------------------


Category: Utility Routine


Register on entry: AL- Character to check


Register on return: Zero flag- set if character is alphabetic, clear if not.


Flags affected: None


Example of Usage: mov al, char
IsAlpha
je IsAlChar


Description: This routine checks the character in the AL register to
see if it is in the range A-Z or a-z. Upon return, you
can use the JE instruction to check to see if the character
was in the range (or, conversely, you can use JNE to see
if it is not in the range).

Include: stdlib.a






Routine: IsLower
----------------


Category: Utility Routine


Registers on Entry: AL- character to test


Registers on Return: None


Flags Affected: Zero = 1 if character is a lower case alphabetic character
Zero = 0 if character is not a lower case alphabetic
character


Example of Usage: mov AL, char ; put char in AL
IsLower ; is char lower a-z?
je IsLowerChar ; if yes, jump to IsLowerChar


Description: This routine checks the character in the AL register to
see if it is in the range a-z. Upon return, you can use
the JE instruction to check and see if the character was
in this range (or you can use JNE to check and see if
the character was not in this range). This procedure is
implemented as a macro for high performance.


Include: stdlib.a





Routine: IsUpper
-----------------


Category: Utility Routine


Registers on Entry: AL- character to check


Registers on Return: None


Flags Affected: Zero flag - set if character is uppercase alpha, clear
if not.


Example of Usage: mov al, char
IsUpper
je IsUpperChar


Description: This routine checks the character in the AL register to
see if it is in the ranger A-Z. Upon return, you can use
the JE instruction to check to see if it not in the
range). It uses macro implementation for high performance.


Include: stdlib.a





String Handling Routines
------------------------


Manipulating text is a major part of many computer applications. Typically,
strings are inputed and interpreted. This interpretation may involve some
chores such as extracting certain part of the text, copying it, or comparing
with other strings.

The string manipulation routines in C provides various functions. Therefore,
the stdlib has some C-like string handling functions (e.g. strcpy, strcmp).
In C a string is an array of characters; similarly, the string are terminated
by a "0" as a null character. In general, the input strings of these routines
are pointed by ES:DI. In some routines, the carry flag will be set to indicate
an error. The file "stdlib.a" is necessary to be included and the routines
are declared as extern.





Routine: Strcpy, Strcpyl
-------------------------


Category: String Handling Routine


Registers on Entry: ES:DI - pointer to source string (Strcpy only)
CS:RET - pointer to source string (Strcpy1 only)
DX:SI - pointer to destination string


Registers on return: ES:DI - points at the destination string


Flags affected:


Example of Usage:
mov dx, seg target
mov si, offset target
Strcpy1 db "String for Strcpy1",0 ; Copy that string to
; Target2 as well,
; note that ES:DI
; already points at
; "Target".
mov dx, seg Target2
mov si, offset Target2
Strcpy


Description: Strcpy is used to copy a zero-terminated string from one
location to another. ES:DI points at the source string,
DX:SI points at the destination address. Strcpy copies all
bytes, up to and including the zero byte, from the source
address to the destination address. The target buffer must
be large enough to hold the string. Strcpy performs no error
checking on the size of the destination buffer.

Strcpy1 copies the zero-terminated string immediately following
the call instruction to the destination address specified by
DX:SI. Again, this routine expects you to ensure that the
taraget buffer is large enough to hold the result.


Include: stdlib.a






Routine: StrDup, StrDupl
-------------------------


Category: String Handling Routine


Register on entry: ES:dI - pointer to source string (StrDup
only). CS:RET - Pointer to source string
(StrDupl only).


Register on return: ES:DI - Points at the destination string
allocated on heap. Carry=0 if operation
successful. Carry=0 if insufficient
memory for new string.


Flags affected: Carry flag


Example of usage:
StrDupl
db "String for StrDupl",0
jc MallocError
mov word ptr Dest1, di
mov word ptr Dest1+2, es ;create another
;copy of this
;string. Note
;that es:di points
;at Dest1 upon
;entry to StrDup,
;but it points at
;the new string on
;exit
StrDup
jc MallocError
mov word ptr Dest2, di
mov word ptr Dest2+2, es


Description: StrDup and StrDupl duplicate strings. You pass them
a pointer to the string (in es:di for strdup, via
the return address for strdupl) and they allocate
sufficient storage on the heap for a copy of this
string. Then these two routines copy their source
strings to the newly allocated storage and return
a pointer to the new string in ES:DI.



Include: stdlib.a





Routine: Strlen
----------------


Category: String Handling Routine


Registers on entry: ES:DI - pointer to source string.


Register on return: CX - length of specified string.


Flags Affected: None


Examples of Usage:
les di, String
strlen
mov sl, cx
printf
db "Length of '%s' is %d\n",0
dd String, sl


Description: Strlen computes the length of the string whose address
appears in ES:DI. It returns the number of characters
up to, but not including, the zero terminating byte.


Include: stdlib.a






Routine: Strcat, Strcat2, Strcatl, Strcat2l
--------------------------------------------


Category: String Handling Routine


Registers on Entry: ES:DI- Pointer to first string
DX:SI- Pointer to second string (Strcat and Strcat2 only)


Registers on Return: ES:DI- Pointer to new string (Strcat2 and Strcat2l only)


Flags Affected: Carry = 0 if no error
Carry = 1 if insufficient memory (Strcat2 and Strcat2l
only)


Example of Usage: les DI, String1
mov DX, seg String2
lea SI, String2
Strcat ; String1 <- String1 + String2

les DI, String1
Strcatl ; String1 <- String1 +
db "Appended String",0 ; "Appended String",0


les DI, String1
mov DX, seg String2
lea SI, String2
Strcat2 ; NewString <- String1 + String2
puts
free

les DI, String1
Strcat2l ; NewString <- String1 +
db "Appended String",0 ; "Appended String",0
puts
free


Description: These routines concatenate two strings together. They differ
mainly in the location of their source and destination operands.

Strcat concatenates the string pointed at by DX:SI to the end of
the string pointed at by ES:DI in memory. Both strings must be
zero-terminated. The buffer pointed at by ES:DI must be large
enough to hold the resulting string. Strcat does NOT perform
bounds checking on the data.

( continued on next page )







Routine: Strcat, Strcat2, Strcatl, Strcat2l ( continued )
--------------------------------------------


Strcat2 computes the length of the two strings pointed at by ES:DI
and DX:SI and attempts to allocate this much storage on the heap.
If it is not successful, Strcat2 returns with the Carry flag set,
otherwise it copies the string pointed at by ES:DI to the heap,
concatenates the string DX:SI points at to the end of this string
on the heap, and returns with the Carry flag clear and ES:DI
pointing at the new (concatenated) string on the heap.

Strcatl and Strcat2l work just like Strcat and Strcat2 except you
supply the second string as a literal constant immediately AFTER
the call rather than pointing DX:SI at it (see examples above).


Include: stdlib.a




Routine: Strchr
----------------


Category: String Handling Routine


Register on entry: ES:DI- Pointer to string.
AL- Character to search for.


Register on return: CX- Position (starting at zero)
where Strchr found the character.


Flags affected: Carry=0 if Strchr found the character.
Carry=1 if the character was not present
in the string.


Example of usage:
les di, String
mov al, Char2Find
Strchr
jc NotPresent
mov CharPosn, cx


Description: Strchr locates the first occurrence of a character within a
string. It searches through the zero-terminated string pointed
at by es:di for the character passed in AL. If it locates the
character, it returns the position of that character to the CX
register. The first character in the string corresponds to the
location zero. If the character is not in the string, Strchr
returns the carry flag set. CX's value is undefined in that
case. If Strchr locates the character in the string, it
returns with the carry clear.



Include: stdlib.a





Routine: Strstr, Strstrl
-------------------------


Category: String Handling Routine


Register on entry: ES:DI - Pointer to string.
DX:SI - Pointer to substring(strstr).
CS:RET - Pointer to substring (strstrl).


Register on return: CX - Position (starting at zero)
where Strstr/Strstrl found the
character. Carry=0 if Strstr/
Strstrl found the character.
Carry=1 if the character was not
present in the string.


Flags affected: Carry flag


Example of usage :
les di, MainString
lea si, Substring
mov dx, seg Substring
Strstr
jc NoMAtch
mov i, cx
printf db "Found the substring '%s' at location
%i\n",0
dd Substring, i
jmp Done


Description: Strstr searches for the position of a substring
within another string. ES:DI points at the
string to search through, DX:SI points at the
substring. Strstr returns the index into ES:DI's
string where DX:SI's string is found. If the
string is found, Strstr returns with the carry
flag clear and CX contains the (zero based) index
into the string. If Strstr cannot locate the
substring within the string ES:DI points at, it
returns the carry flag set. Strstrl works just
like Strstr except it excepts the substring to
search for immediately after the call instruction
(rather than passing this address in DX:SI).



Include: stdlib.a




Routine: Strcmp
----------------


Category: String Handling Routine


Registers on entry: ES:DI (contains the address of the first string)
DX:SI (contains the address of the second string)


Register on return: CX (contains the position where the two strings differ)


Flags affected: Carry flag and zero flag (string1 > string2 if C + Z = 0)
(string1 < string2 if C = 1)


Example of Usage:
les di, String1
mov dx, seg String2
lea si, String2
strcmp


Description: Strcmp compares the first strings pointed by ES:DI with
the second string pointed by DX:SI. The carry and zero flag
will contain the corresponding result. So unsigned branch
instructions such as JA or JB is recommended. If string1
equals string2, strcmp will return with CX containing the
offset of the zero byte in the two strings.


Include: stdlib.a




Routine: Strcmpl
----------------


Category: String Handling Routine


Registers on entry: ES:DI (contains the address of the first string)
CS:RET (contains the address of the substring)


Registers on return: CX (contains the position where two strings differ)


Flags affected: Carry flag and zero flag (string1 > string2 if C + Z = 0)
(string1 < string2 if C = 1)


Example of Usage:
les di, String1
strcmpl db "Hello",0
jbe elsewhere


Description: Strcmpl compares the first string pointed by ES:DI with
the substring pointed by CS:RET. The carry and zero flag
will contain the corresponding result. So unsigned branch
instructions such as JA or JB is recommended. If string1
equals to the substring, strcmp will return with CX
containing the offset of the zero byte in the two strings.


Include: stdlib.a






Routine: Strupr
----------------


Category: String Handling Routine
Conversion Routine


Register on entry: ES:DI (contains the pointer to input string)


Register on return: ES:DI (contains the pointer to input string
with characters converted to upper case)


Flags affected: None


Example of Usage:
les di, lwrstr1
strupr
print


Description: Strupr converts the input string pointed by ES:DI to
upper case. It will actually modify the string you pass
to it.

Include: stdlib.a





Routine: Strupr2
-----------------


Category: String Handling Routine
Conversion Routine


Register on entry: ES:DI (contains the pointer to input string)


Register on return: ES:DI (contains the pointer to newly created string)


Flags affected: Carry flag (Carry = 0 if no error)
(Carry = 1 if error)


Example of Usage:
les di, lwrstr1
strupr2


Description: Strupr2 calls Strdup to copy the input string to a new string,
and converts the new string to upper case. ES:DI will contain
the pointer to the new string on return. If there is an error
in allocating space for the new string, the carry flag will
set to 1; otherwise, it will remain 0.


Include: stdlib.a





Routine: Strlwr
----------------


Category: String Handling Routine
Conversion Routine


Register on entry: ES:DI (contains the pointer to input string)


Register on return: ES:DI (contains the pointer to input string
with characters converted to lower case).


Flags affected: None


Example of Usage:
les di, uprstr1
strlwr
print


Description: Strlwr converts the input string pointed by ES:DI to
lower case. It will actually modify the string you pass
to it.


Include: stdlib.a





Routine: Strlwr2
-----------------


Category: String Handling Routine
Conversion Routine

Register on entry: ES:DI (contains the pointer to input string)


Register on return: ES:DI (contains the pointer to newly created string)


Flags affected: Carry flag (Carry = 0 if no error)
(Carry = 1 if error)


Example of Usage:
les di, uprstr1
strlwr2


Description: Strlwr2 calls Strdup to copy the input string to a new string,
and converts the new string to lower case. ES:DI will contain
the pointer to the new string on return. If there is an error
in allocating memory for the new string, the carry flag will
set to 1; otherwise, it will remain 0.


Include: stdlib.a






Routine: Strset
----------------


Category: String Handling Routine


Register on entry: ES:DI (contains the pointer to input string)
AL (contains the character to copy)


Register on return: None


Flags affected: None


Example of Usage:
les di, string1
Strset


Description: Strset overwrites the data on input string pointed by
ES:DI with the character on AL.


Include: stdlib.a









Routine: Strset2
-----------------


Category: String Handling Routine


Register on entry: AL (contains the character to copy)
CX (contains the number of characters to copy)


Register on return: ES:DI (contains the pointer to new string)


Flags affected: Carry flag (Carry = 0 if no error)
(Carry = 1 if error)

Example of Usage:
mov al,'#'
mov cx, 5
strset2
puts


Description: Strset2 calls Malloc to allocate space for the new string and
initializes it with the character in AL. If there is an error
from malloc, the carry will set to one; otherwise, it will set
to zero.


Include: stdlib.a





Routine: Strspan, Strspanl
---------------------------


Category: String Handling Routine


Registers on Entry: ES:DI - Pointer to string to scan
DX:SI - Pointer to character set (Strspan only)
CS:RET- Pointer to character set (Strspanl only)


Registers on Return: CX- First position in scanned string which does not
contain one of the characters in the character set


Flags Affected: None


Example of Usage:
les DI, String
mov DX, seg CharSet
lea SI, CharSet
Strspan ; find first position in String with a
mov i, CX ; char not in CharSet
printf
db "The first char which is not in CharSet "
db "occurs at position %d in String.\n",0
dd i

les DI, String
db "aeiou",0
Strspanl ; find first position in String which
mov j, CX ; is not a vowel
printf
db "The first char which is not a vowel "
db "occurs at position %d in String.\n",0
dd j


Description: Strspan(l) scans a string, counting the number of characters which
are present in a second string (which represents a character set).
ES:DI points at a zero-terminated string of characters to scan.
DX:SI (strspan) or CS:RET (strspanl) points at another zero-
terminated string containing the set of characters to compare
against. The position of the first character in the string
pointed to by ES:DI which is NOT in the character set is returned.
If all the characters in the string are in the character set, the
position of the zero-terminating byte will be returned.

Although strspan and (especially) strspanl are very compact and
convenient to use, they are not particularly efficient. The
character set routines provide a much faster alternative at the
expense of a little more space.


Include: stdlib.a





Routine: Strcspan, Strcspanl
-----------------------------


Category: String Handling Routine


Registers on Entry: ES:DI - Pointer to string to scan
DX:SI - Pointer to character set (Strcspan only)
CS:RET- Pointer to character set (Strcspanl only)


Registers on Return: CX- First position in scanned string which contains one
of the characters in the character set


Flags Affected: None


Example of Usage:
les DI, String
mov DX, seg CharSet
lea SI, CharSet
Strcspan ; find first position in String with a
mov i, CX ; char in CharSet
printf
db "The first char which is in CharSet "
db "occurs at position %d in String.\n",0
dd i

les DI, String
db "aeiou",0
Strcspanl ; find first position in String which
mov j, CX ; is a vowel
printf
db "The first char which is a vowel occurs "
db "at position %d in String.\n",0
dd j


Description: Strcspan(l) scans a string, counting the number of characters
which are NOT present in a second string (which represents a
character set). ES:DI points at a zero-terminated string of
characters to scan. DX:SI (strcspan) or CS:RET (strcspanl) points
at another zero-terminated string containing the set of characters
to compare against. The position of the first character in the
string pointed to by ES:DI which is in the character set is
returned. If all the characters in the string are not in the
character set, the position of the zero-terminating byte will be
returned.

Although strcspan and strcspanl are very compact and convenient to
use, they are not particularly efficient. The character set
routines provide a much faster alternative at the expense of a
little more space.


Include: stdlib.a




Routine: StrIns, StrIns2, StrInsl, StrIns2l
--------------------------------------------


Category: String Handling Routine


Registers on Entry: ES:DI - Pointer to destination string (to insert into)
DX:SI - Pointer to string to insert
(StrIns and StrIns2 only)
CX - Insertion point in destination string


Registers on Return: ES:DI - Pointer to new string (StrIns2 and StrIns2l only)


Flags Affected: Carry = 0 if no error
Carry = 1 if insufficient memory
(StrIns2 and StrIns2l only)


Example of Usage:
les DI, DestStr
mov DX, word ptr SrcStr+2
mov SI, word ptr SrcStr
mov CX, 5
StrIns ; Insert SrcStr before the 6th char of DestStr

les DI, DestStr
mov CX, 2
StrInsl ; Insert "Hello" before the 3rd char of DestStr
db "Hello",0

les DI, DestStr
mov DX, word ptr SrcStr+2
mov SI, word ptr SrcStr
mov CX, 11
StrIns2 ; Create a new string by inserting SrcStr
; before the 12th char of DestStr
puts
putcr


Description: These routines insert one string into another string. ES:DI
points at the string into which you want to insert another. CX
contains the position (or index) where you want the string
inserted. This index is zero-based, so if CX contains zero, the
source string will be inserted before the first character in the
destination string. If CX contains a value larger than the size
of the destination string, the source string will be appended to
the destination string.

StrIns inserts the string pointed at by DX:SI into the string
pointed at by ES:DI at position CX. The buffer pointed at by
ES:DI must be large enough to hold the resulting string. StrIns
does NOT perform bounds checking on the data.

( continued on next page )










Routine: StrIns, StrIns2, StrInsl, StrIns2l ( continued )
--------------------------------------------

StrIns2 does not modify the source or destination strings, but
instead attempts to allocate a new buffer on the heap to hold the
resulting string. If it is not successful, StrIns2 returns with
the Carry flag set, otherwise the resulting string is created and
its address is returned in the ES:DI registers.

StrInsl and StrIns2l work just like StrIns and StrIns2 except you
supply the second string as a literal constant immediately AFTER
the call rather than pointing DX:SI at it (see examples above).






Routine: StrDel, StrDel2
-------------------------


Category: String Handling Routine


Registers on Entry: ES:DI - pointer to string
CX - deletion point in string
AX - number of characters to delete


Registers on return: ES:DI - pointer to new string (StrDel2 only)


Flags affected: Carry = 1 if memory allocation error, 0 if okay
(StrDel2 only).


Example of Usage:
les di, Str2Del
mov cx, 3 ; Delete starting at 4th char
mov ax, 5 ; Delete five characters
StrDel ; Delete in place

les di, Str2Del2
mov cx, 5
mov ax, 12
StrDel2
puts
free


Description: StrDel deletes characters from a string. It works by computing
the beginning and end of the deletion point. Then it copies all
the characters from the end of the deletion point to the end of
the string (including the zero byte) to the beginning of the
deletion point. This covers up (thereby effectively deleting)
the undesired characters in the string.

Here are two degenerate cases to worry about -- 1) when you
specify a deletion point which is beyond the end of the string;
and 2) when the deletion point is within the string but the
length of the deletion takes you beyond the end of the string.
In the first case StrDel simply ignores the deletion request. It
does not modify the original string. In the second case,
StrDel simply deletes everything from the deletion point to the
end of the string.

StrDel2 works just like StrDel except it does not delete the
characters in place. Instead, it creates a new string on the
heap consisting of the characters up to the deletion point and
those following the characters to delete. It returns a pointer
to the new string on the heap in ES:DI, assuming that it
properly allocated the storage on the heap.


Include: stdlib.a





Routine: StrRev, StrRev2
-------------------------


Author: Michael Blaszczak (.B ekiM)


Category: String Handling Routine


Registers on Entry: ES:DI - pointer to string


Registers on return: ES:DI - pointer to new string (StrRev2 only).


Flags affected: Carry = 1 if memory allocation error, 0 if okay
(StrRev2 only).


Example of Usage:


Description: StrRev reverses the characters in a string. StrRev reverses,
in place, the characters in the string that ES:SI points at.
StrRev2 creates a new string on the heap (which contains the
characters in the string ES:DI points at, only reversed) and
returns a pointer to the new string in ES:DI. If StrRev2
cannot allocate sufficient memory for the string, it returns
with the carry flag set.


Include: stdlib.a





Memory Management Routines
--------------------------


The stdlib memory management routines let you dynamically allocate storage on
the heap. These routines are somewhat similar to those provided by the "C"
programming language. However, these routines do not perform garbage
collection, as this would introduce too many restrictions and have a very
adverse effect on speed.

The following paragraph gives a description of how the memory management
routines work. These routines may be updated in future revisions, however,
so you should never make assumptions about the structure of the memory
management record (described below) or else your code may not work on the
next revision.

The allocation/deallocation routines should be fairly fast. Malloc and free
use a modified first/next fit algorithm which lets the system quickly find a
memory block of the desired size without undue fragmentation problems (average
case). The memory manager data structure has an overhead of eight bytes
(meaning each malloc operation requires at least eight more bytes than you ask
for) and a granularity of 16 bytes. The overhead (eight bytes) per allocated
block may seem rather high, but that is part of the price to pay for faster
malloc and free routines. All pointers are far pointers and each new item is
allocated on a paragraph boundary. The current memory manager routines always
allocate (n+8) bytes, rounding up to the next multiple of 16 if the result is
not evenly divisible by sixteen. The first eight bytes of the structure are
used by the memory management routines, the remaining bytes are available for
use by the caller (malloc, et. al., return a pointer to the first byte beyond
the memory management overhead structure).





Routine: MemInit
-----------------


Category: Memory Management Routine


Registers on Entry: DX - number of paragraphs to reserve


Globals Affected: zzzzzzseg - segment name of the last segment in your
program
PSP - public word variable which holds the PSP value
for your program


Registers on return: CX - number of paragraphs actually reserved by MemInit


Flags affected: Carry = 0 if no error.
Carry = 1 if error; AX contains DOS error code.


Example of Usage:
; Don't forget to set up PSP
; and zzzzzzseg before calling
; MemInit
mov dx, dx ; Allocate all available RAM
MemInit jc
MemoryError ; CX contains the number of
; paragraphs actually
; allocated


Description: This routine initializes the memory manager system. You must
call it before using any routines which call any of the memory
manager procedures (since a good number of the stdlib routines
call the memory manager, you should get in the habit of always
calling this routine.) The system will "die a horrible death"
if you call a memory manager routine (like malloc) without first
calling MemInit.

This routine expects you to define (and set up) two global
names: zzzzzzseg and PSP. "zzzzzzseg" is a dummy segment which
must be the name of the very last segment defined in your
program. MemInit uses the name of this segment to determine the
address of the last byte in your program. If you do not
declare this segment last, the memory manager will overwrite
anything which follows zzzzzzseg. The "shell.asm" file
provides you with a template for your programs which properly
defines this segment.

PSP should be a word variable which contains the program segment
prefix value for your program. MS-DOS passes the PSP value to
your program in the DS and ES registers. You should save this
value in the PSP variable. Don't forget to make PSP a public
symbol in your main program's source file. The "shell.asm" file
demonstrates how to properly set up this value.

The DX register contnains the number of 16-byte paragraphs you
want to reserve for the heap. If DX contains zero, MemInit will
allocate all of the available memory to the heap. If your
program is going to allow the user to run a copy of the command
interpreter, or if your program is going to EXEC some other
program, you should not allocate all storage to the heap.
Instead, you should reserve some memory for those programs.
By setting DX to some value other than zero, you can tell MemInit
how much memory you want to reserve for the heap. All left over
memory will be available for other system (or program) use.
If the value in DX is larger than the amount of available RAM,
MemInit will split the available memory in half and reserve half
for the heap leaving the other half unallocated. If you want to
force this situation (to leave half available memory for other
purposes), simply load DX with 0FFFFH before calling MemInit.
There will never be this much memory available, so this will
force MemInit to split the available RAM between the heap and
unallocated storage.

On return from MemInit, the CX register contains the number of
paragraphs actually allocated. You can use this value to see if
MemInit has actually allocated the number of paragraphs you
requested. You can also use this value to determine how much
space is available when you elect to split the free space
between the heap and the unallocated portions.

If all goes well, this routine returns the carry flag clear.
If a DOS memory manager error occurs, this routine returns the
carry flag set and the DOS error code in the AX register.


Include: stdlib.a







Routine: Malloc
----------------


Category: Memory Management Routine


Registers on Entry: CX - number of bytes to reserve


Registers on return: CX - number of bytes actually reserved by Malloc
ES:DI - ptr to 1st byte of memory allocated by Malloc


Flags affected: Carry=0 if no error.
Carry=1 if insufficient memory.


Example of Usage:
mov cx, 256
Malloc
jnc GoodMalloc
print db "Insufficient memory to continue.",cr,lf,0
jmp Quit
GoodMalloc: mov es:[di], 0 ;Init string to NULL


Description: Malloc is the workhorse routine you use to allocate a block of
memory. You give it the numbmer of bytes you need and if it
finds a block large enough, it will allocate the requested
amount and return a pointer to that block.

Most memory managers require a small amount of overhead for each
block they allocate. Stdlib's (current) memory manager requires
an overhead of eight bytes. Furthermore, the grainularity is 16
bytes. This means that Malloc always allocates blocks of memory
in paragraph multiples. Therefore, Malloc may actually reserve
more storage than you specify. Therefore, the value returned in
CX may be somewhat greater than the requested value. By setting
the minimum allocationn size to a paragraph, however, the
overhead is reduced and the speed of Malloc is improved by a
considerable amount.

Stdlib's memory management does not do any garbage collection.
Doing so would place too many demands on Malloc's users.
Therefore, it is quite possible for you to fragment memory with
multiple calls to maloc, realloc, and free. You could wind up in
a situation where there is enough free memory to satisfy your
request, but there isn't a single contiguous block large enough
for the request. Malloc treats this as an insufficient memory
error and returns with the carry flag set.

If Malloc cannot allocate a block of the requested size, it
returns with the carry flag set. In this situation, the contents
of ES:DI is undefined. Attempting to dereference this pointer
will produce erratic and, perhaps, disasterous results.


Include: stdlib.a






Routine: Realloc
-----------------


Category: Memory Management Routine


Registers on Entry: CX - number of bytes to reserve
ES:DI - pointer to block to reallocate.


Registers on return: CX - number of bytes actually reserved by Realloc.
ES:DI - pointer to first byte of memory allocated by
Realloc.


Flags affected: Carry = 0 if no error.
Carry = 1 if insufficient memory.


Example of Usage:


Description: Realloc lets you change the size of an allocated block in the
heap. It allows you to make the block larger or smaller.
If you make the block smaller, Realloc simply frees (returns
to the heap) any leftover bytes at the end of the block. If
you make the block larger, Realloc goes out and allocates a
block of the requested size, copies the bytes form the old
block to the beginning of the new block (leaving the bytes at
the end of the new block uninitialized)), and then frees the
old block.


Include: stdlib.a





Routine: Free
--------------


Category: Memory Management Routine


Registers on Entry: ES:DI - pointer to block to deallocate


Registers on return: None


Flags affected: Carry = 0 if no error.
Carry = 1 if ES:DI doesn't point at a Free block.


Example of Usage:
les di, HeapPtr
Free

Description: Free (possibly) deallocates storage allocated on the heap by
malloc or Realloc. Free returns this storage to heap so other
code can reuse it later. Note, however, that Free doesn't
always return storage to the heap. The memory manager data
structure keeps track of the number of pointers currently
pointing at a block on the heap (see DupPtr, below). If you've
set up several pointers such that they point at the same block,
Free will not deallocate the storage until you've freed all of
the pointers which point at the block.

Free usually returns an error code (carry flag = 1) if you
attempt to Free a block which is not currently allocated or if
you pass it a memory address which was not returned by malloc
(or Realloc). By no means is this routine totally robust.
If you start calling free with arbitrary pointers in es:di
(which happen to be pointing into the heap) it is possible,
under certain circumstances, to confuse Free and it will attempt
to free a block it really should not.

This problem could be solved by adding a large amount of extra
code to the free routine, but it would slow it down considerably.
Therefore, a little safety has been sacrificed for a lot of
speed.


Include: stdlib.a






Routine: DupPtr
----------------


Category: Memory Manager Routine


Registers on Entry: ES:DI - pointer to block


Registers on return: None


Flags affected: Carry = 0 if no error.
Carry = 1 if es:di doesn't point at a free block.

Example of Usage:
les di, Ptr
DupPtr


Description: DupPtr increments the pointer count for the block at the
specifiied address. Malloc sets this counter to one. Free
decrements it by one. If free decrements the value and it
becomes zero, free will release the storage to the heap for
other use. By using DupPtr you can tell the memory manager
that you have several pointers pointing at the same block
and that it shouldn't deallocate the storage until you free
all of those pointers.


Include: stdlib.a









Routine: IsInHeap
------------------


Category: Memory Management Routine


Registers on Entry: ES:DI - pointer to a block


Registers on return: None


Flags affected: Carry = 0 if ES:DI is a valid pointer.
Carry = 1 if not.


Example of Usage:


Description: This routine lets you know if es:di contains the address of
a byte in the heap somewhere. It does not tell you if es:di
contains a valid pointer returned by malloc (see IsPtr, below).
For example, if es:di contains the address of some particular
element of an array (not necessarily the first element)
allocated on the heap, IsInHeap will return with the carry clear
denoting that the es:di points somewhere in the heap. Keep in
mind that calling this routine does not validate the pointer;
it could be pointing at a byte which is part of the memory
manager data structure rather than at actual data (since the
memory manager maintains that informatnion within the
bounds of the heap). This routine is mainly useful for seeing
if something is allocated on the heap as opposed to somewhere
else (like your code, data, or stack segment).


Include: stdlib.a







Routine: IsPtr
---------------


Category: Memory Management Routine


Registers on Entry: ES:DI - pointer to block


Registers on return: None


Flags affected: Carry = 0 if es:di is a valid pointer.
Carry = 1 if not.

Example of Usage:


Description: IsPtr is much more specific than IsInHeap. This routine returns
the carry flag clear if and only if es:di contains the address
of a properly allocated (and currently allocated) block on the
heap. This pointer must be a value returned by Malloc, Realloc,
or DupPtr and that block must be currently allocated for IsPtr
to return the carry flag clear.


Include: stdlib.a





Character Set Routines
----------------------


The character set routines let you deal with groups of characters as a set
rather than a string. A set is an unordered collection of objects where
membership (presence or absence) is the only important quality. The stdlib
set routines were designed to let you quickly check if an ASCII character is
in a set, to quickly add characters to a set or remove characters from a set.
These operations are the ones most commonly used on character sets. The
other operations (like union, intersection, difference, etc.) are useful, but
are not as popular as the former routines. Therefore, the data structure
has been optimized for sets to handle the membership and add/delete operations
at the slight expense of the others.

Character sets are implemented via bit vectors. A "1" bit means that an item
is present in the set and a "0" bit means that the item is absent from the
set. The most common implementation of a character set is to use thirty-two
consecutive bytes, eight bytes per, giving 256 bits (one bit for each char-
acter in the character set). While this makes certain operations (like
assignment, union, intersection, etc.) fast and convenient, other operations
(membership, add/remove items) run much slower. Since these are the more
important operations, a different data structure is used to represent sets.
A faster approach is to simply use a byte value for each item in the set.
This offers a major advantage over the thirty-two bit scheme: for operations
like membership it is very fast (since all you have got to do is index into
an array and test the resulting value). It has two drawbacks: first, oper-
ations like set assignment, union, difference, etc., require 256 operations
rather than thirty-two; second, it takes eight times as much memory.

The first drawback, speed, is of little consequence. You will rarely use the
the operations so affected, so the fact that they run a little slower will be
of little consequence. Wasting 224 bytes is a problem, however. Especially
if you have a lot of character sets.

The approach used here is to allocate 272 bytes. The first eight bytes con-
tain bit masks, 1, 2, 4, 8, 16, 32, 64, 128. These masks tell you which bit
in the following 264 bytes is associated with the set. This facilitates
putting eight sets into 272 bytes (34 bytes per character set). This provides
almost the speed of the 256-byte set with only a two byte overhead. In the
stdlib.a file there is a macro that lets you define a group of character
sets: set. The macro is used as follows:

set set1, set2, set3, ... , set8

You must supply between one and eight labels in the operand field. These are
the names of the sets you want to create. The set macro automatically
attaches these labels to the appropriate mask bytes in the set. The actual
bit patterns for the set begin eight bytes later (from each label). There-
fore, the byte corresponding to chr(0) is staggered by one byte for each
set (which explains the other eight bytes needed above and beyond the 256
required for the set). When using the set manipulation routines, you should
always pass the address of the mask byte (i.e., the seg/offset of one of the
labels above) to the particular set manipulation routine you are using.
Passing the address of the structure created with the macro above will
reference only the first set in the group.

Note that you can use the set operations for fast pattern matching appli-
cations. The set membership operation for example, is much faster that the
strspan routine found in the string package. Proper use of character sets
can produce a program which runs much faster than some of the equivalent
string operations.



Routine: Createsets
--------------------


Category: Character Set Routine


Registers on Entry: no parameters passed


Registers on return: ES:DI - pointer to eight sets


Flags affected: Carry = 0 if no error. Carry = 1 if insufficient
memory to allocate storage for sets.


Example of Usage:
Createsets
jc NoMemory
mov word ptr SetPtr, di
mov word ptr SetPtr+2, es


Description: Createsets allocates 272 bytes on the heap. This is sufficient
room for eight character sets. It then initializes the first
eight bytes of this storage with the proper mask values for
each set. Location es:0[di] gets set to 1, location es:1[di]
gets 2, location es:2[di] gets 4, etc. The Createsets routine
also initializes all of the sets to the empty set by clearing
all the bits to zero.


Include: stdlib.a






Routine: EmptySet
------------------


Category: Character Set Routine


Registers on Entry: ES:DI - pointer to first byte of desired set


Registers on return: None


Flags affected:


Example of Usage:
les di, SetPtr
add di, 3 ; Point at 4th set in group.
Emptyset


Description: Emptyset clears out the bits in a character set to zero
(thereby setting it to the empty set). Upon entry, es:di must
point at the first byte of the character set you want to clear.
Note that this is not the address returned by Createsets. The
first eight bytes of a character set structure are the
addresses of eight different sets. ES:DI must point at one of
these bytes upon entry into Emptyset.


Include: stdlib.a






Routine: Rangeset
------------------


Category: Character Set Routine


Registers on entry: ES:DI (contains the address of the first byte of the set)
AL (contains the lower bound of the items)
AH (contains the upper bound of the items)


Registers on return: None


Flags affected: None


Example of Usage:
lea di, SetPtr
add di, 4
mov al, 'A'
mov ah, 'Z'
rangeset


Description: This routine is to add a range of a set with ES:DI as the
pointer of the set, AL as the lower bound of the set, and
AH as the upper bound of the set (AH has to be greater than
AL, otherwise, there will an error).


Include: stdlib.a






Routine: Addstr, Addstrl
-------------------------


Category: Character Set Routine


Registers on Entry: ES:DI- pointer to first byte of desired set
DX:SI- pointer to string to add to set (Addstr only)
CS:RET-pointer to string to add to set (Addstrl only)


Registers on Return: None


Flags Affected: None


Example of Usage:
les di, SetPtr
add di, 1 ;Point at 2nd set in group.
mov dx, seg CharStr ;Pointer to string
lea si, CharStr ; chars to add to set.
addstr ;Union in these characters.
;
les di, SetPtr ;Point at first set in group.
addstrl
db "AaBbCcDdEeFf0123456789",0
;


Description: Addstr lets you add a group of characters to a set by
specifying a string containing the characters you want in
the set. To Addstr you pass a pointer to a zero-terminated
string in dx:si. Addstr will add (union) each character
from this string into the


Include: stdlib.a











Routine: Rmvstr
----------------


Category: Character Set Routine


Registers on entry: ES:DI (contains the address of first byte of a set)
DX:SI (contains the address of string to be removed
from a set)


Registers on return: None


Flags affected: None


Example of Usage:
lea di, SetPtr
add di, 1
mov dx, seg CharStr
lea si, CharStr
rmstr


Description: This routine is to remove a string from a set with ES:DI
pointing to its first byte, and DX:SI pointing to the
string to be removed from the set.


Include: stdlib.a






Routine: AddChar
-----------------


Category: Character Set Routine


Registers on Entry: ES:DI- pointer to first byte of desired set
AL- character to add to the set


Registers on Return: None


Flags affected: None


Example of Usage:
les di, SetPtr
add di, 1 ;Point at 2nd set in group.
mov al, Ch2Add ;Character to add to set.
addchar


Description: AddChar lets you add a single character (passed in AL)
to a set.


Include: stdlib.a





Routine: Rmvchar
-----------------


Category: Character Set Routine


Registers on entry: ES:DI (contains the address of first byte of a set)
AL (contains the character to be removed)


Registers on return: None


Flags affected: Zero flag (Zero = 1 if the character is in the set
Zero = 0 if the character is not in the set)


Example of Usage:
lea di, SetPtr
add di, 7
mov al, Ch2Chk
member
je IsInSet


Description: This routine is to remove a character in AL from a set.
ES:SI points to its mask byte. If the character is in
the set, the zero flag is set to 1. If not, it is set
to zero.


Include: stdlib.a





Routine: Member
----------------


Category: Character Set Routine


Registers on entry: ES:DI (contains the address of first byte of a set)
AL (contains the character to be compared)


Registers on return: None


Flags affected: Zero flag (Zero = 1 if the character is in the set
Zero = 0 if the character is not in the set)


Example of Usage:
les di, SetPtr
add di, 1
mov al, 'H'
member
je IsInSet


Description: Member is used to find out if a character in AL is in a set
with ES:DI pointing to its mask byte. If the character is in
the set, the zero flag is set to 1. If not, the zero flag is
set to zero.


Include: stdlib.a






Routine: CopySet
-----------------


Category: Character Set Routine


Register on entry: ES:DI- pointer to first byte of destination set.
DX:SI- pointer to first bye of source set.


Register on Return: None


Flags affected: None


Example of Usage:
les di, SetPtr
add di, 7 ;Point at 8th set in group.
mov dx, seg SetPtr2 ;Point at first set in group.
lea si, SetPtr2
copyset


Description: CopySet copies the items from one set to another. This is a
straight assignment, not a union operation. After the
operation, the destination set is identical to the source set,
both in terms of the element present in the set and absent
from the set.


Include: stdlib.a







Routine: SetUnion
------------------


Category: Character Set Routine


Register on entry: ES:DI - pointer to first byte of destination set.
DX:SI - pointer to first byte of source set.


Register on return: None


Flags affected: None


Example of Usage: les di, SetPtr
add di, 7 ;point at 8th set in group.
mov dx, seg SetPtr2 ;point at 1st set in group.
lea si, sSetPtr2
unionset ;


Description: The SetUnion routine computes the union of two sets.
That is, it adds all of the items present in a source set
to a destination set. This operation preserves items
present in the destination set before the SetUnion
operation.


Include: stdlib.a






Routine: SetIntersect
----------------------


Category: Character Set Routine


Register on entry: ES:DI - pointer to first byte of destination set.
DX:SI - pointer to first byte of source set.


Register on return: None


Flags affected: None


Example of Usage:
les di, SetPtr
add di, 7 ;point at 8th set in group.
mov dx, seg SetPtr2 ;point at 1st set in group.
lea si, SetPtr2
setintersect


Description: SetIntersect computes the intersection of two sets, leaving
the result in the destination set. The new set consists
only of those items which previously appeared in
both the source and destination sets.


Include: stdlib.a






Routine: SetDifference
-----------------------


Category: Character Set Routine


Register on entry: ES:DI - pointer to the first byte of destination set.
DX:SI - pointer to the first byte of the source set.


Register on return: None


Flags affected: None


Example of Usage:
les di, SetPtr
add di, 7 ;point at 8th set in group.
mov dx, seg SetPtr2 ;point at 1st set in group.
lea si, SetPtr2
setdifference


Discription: SetDifference computes the result of (ES:DI) := (ES:DI) -
(DX:SI). The destination set is left with its original
items minus those items which are also in the source set.


Include: stdlib.a







Routine: Nextitem
------------------


Category: Character Set Routine


Registers on entry: ES:DI (contains the address of first byte of the set)


Registers on return: AL (contains the first item in the set)


Flags affected: None


Example of Usage:
les di, SetPtr
add di, 7
nextitem


Description: Nextitem is the routine to search the first character (item)
in the set with ES:DI pointing to its mask byte. AL will
return the character in the set. If the set is empty, AL
will contain zero.


Include: stdlib.a





Routine: Rmvitem
-----------------


Category: Character Set Routine


Registers on entry: ES:DI (contains the address fo first byte of the set)



Registers on return: AL (contains the first item in the set)


Flags affected: None


Example of Usage:
les di, SetPtr
add di, 7
rmvitem


Description: Rmvitem locates the first available item in the set and
removes it with ES:DI pointing to its mask byte. AL will
return the item removed. If the set is empty, AL will
return zero.


Include: stdlib.a




 December 12, 2017  Add comments

Leave a Reply