StdLib Character Functions


UCR StdLib2: Character Routines
3.1 - Interface
3.2 - Generic Interface
3.3 - IsAlnum
3.4 - IsAlpha
3.5 - IsDigit
3.6 - IsLower
3.7 - IsUpper
3.8 - IsXDigit
3.9 - ToLower
3.10 - ToUpper
3.11.2 - IsAlpha Implementations
3.11.3 - IsDigit Implementations
3.11.4 - IsLower Implementations
3.11.5 - IsUpper Implementations
3.11.6 - IsXDigit Implementations
3.11.7 - ToLower Implementations
3.11.8 - ToUpper Implementations

 


UCR StdLib2: Character Routines

The UCR Standard Library (stdlib) contains a large number of routines that operate on single characters. These routines fall into two general categories, those that test characters to see if they are in a certain character set and those that translate characters (e.g., from lower to upper case).


3.1 Interface

To access the routines in the conversions package, your assembly language module must include the file "char.a" during assembly. You can accomplish this with either of the following include statements in your assembly code:

 




	include	char.a
or
	include	ucrlib.a

Note that the "ucrlib.a" include file automatically includes all include files associated with the UCR Standard Library.

The char.a include file exports several symbols. The UCR Standard Library prefaces all "private" names with a dollar sign ("$"). You should not call any routine in this package that begins with this symbol. To avoid name conflicts, you should not define any symbols in your programs that begin with a dollar sign ("$"). Note that future versions of the stdlib (that remain compatible with this release) may change "private" names. To remain compatible with future releases, you must not refer to these "private" names within your programs unless otherwise advised that this is okay.

Source code appearing in this chapter is current as of Version Two, Release 40. There may be minor changes between this source code and the current release.

 


3.2 Generic Interface

Many of the standard library routines use a common generic programmer's interface. Such routines let you pass parameters to them in several different locations. Common examples include in the registers, by value in the code stream (CSi), by reference in the code stream (CS), by value on the top of stack (TOS), and by reference on the top of stack (Stk). Typically, there are separate invocation macros defined for each of these variants, e.g.,

 





        IsAlNum                 ;Passed in AL register.

        IsAlNumCS
        dword   chrPtr          ;Passed by reference in code stream.

        push    'a'             ;Passed by value on the stack.
        IsAlNumTOS

        push    seg chrVar      ;Passed by reference on the stack.
        push    offset chrVar
        IsAlNumStk

Note that you will rarely find actual routines that pass their parameters by value in the code stream using the "CSi" suffix. The reason this is so is because most such routines use different, more descriptive names. For example, "PutsCSi" goes by the name "Print".

In addition to the above forms there are two other suffixes generally applied to stdlib routine names: "m" and "x". The "m" suffix stands for "malloc". Routines with the "m" suffix typically generate a string result and malloc storage for the string on the heap, returning a pointer to this string in the ES:DI register pair. The routines with an "x" suffix also process strings. Most stdlib routines preserve the value of the ES:DI registers when processing strings; typically, they leave the ES:DI register pair pointing at the start of the string. The routines with an "x" suffix do not preserve ES:DI, they generally leave ES:DI pointing at the zero byte of the string they processed or generated.

To make it easier to use all these different variants, the standard library typically defines a macro for each routine that lets you specify various operands using stdlib "addressing modes." The allowable addressing modes vary by routines, but they typically take one of the following forms:

 





        name            ;If operand field is blank, use "plain" 
version.
        name    var     ;Generally passes address of var in code stream 
(CS).
        name    const   ;Pushes const onto TOS and uses nameTOS routine.
        name    [wvar]  ;Pushes DS followed by value of wVar variable
                        ; (assumed to be a word) and calls nameSTK
        name    [dVar]  ;Pushes dword value of dVar onto stk, calls 
nameStk.

Since not all of these "addressing modes" are applicable to all instructions, and some instructions allow different sets of operands (including multiple operands), there are lots of special cases. Such cases are noted after the explaination for each particular routine.


3.3 IsAlnum

IsAlNum checks a character to see if it is alphanumeric {'0' - '9', 'a' - 'z', 'A' - 'Z'}. This routine returns the zero flag set if the character is a member of this set, it returns the zero flag clear otherwise.


3.3.1 Calling Conventions and Assertions


3.3.2 IsAlNum Addressing Modes

The following versions of IsAlNum are available:

IsAlNum Addressing Modes
Name Plain CS TOS Stk X CSi
IsAlNum X X X X - -

 

The IsAlNum macro allows the following operands:

IsAlNum Extended Syntax
Name   byteVar Num const [word Var] [dword Var] String Const
IsAlNum X X X X X -


3.3.3 Syntax & Examples

The following examples assume the following declarations:

 




chrVar  byte    ?
wPtr    word    chrVar
dPtr    dword   chrVar

         .
         .
         .

        mov     al, chrVar
        IsAlNum
        jz      InSet

        IsAlNumCS
        dword   chrVar
        jz      InSet

        push    wPtr            ;or push seg chrVar, push offset chrVar
        IsAlNumStk
        jz      IsInSet

        push    word ptr chrVar
        IsAlNumTOS

; Alternate syntax using stdlib addressing modes:

        mov     al, chrVar
        IsAlNum
        jz      IsInSet

        IsAlNum chrVar          ;Uses IsAlNumCS
        jz      IsInSet

        IsAlNum [wPtr]          ;Uses IsAlNumStk
        jz      IsInSet

        IsAlNum [dPtr]          ;Uses IsAlNumStk
        jz      IsInSet

        IsAlNum 'a'             ;Uses IsAlNumTOS
        jz      IsInSet


3.4 IsAlpha

IsAlpha checks a character to see if it is alphabetic {'a' - 'z', 'A' - 'Z'}. This routine returns the zero flag set if the character is a member of this set, it returns the zero flag clear otherwise.


3.4.1 Calling Conventions and Assertions


3.4.2 IsAlpha Addressing Modes

The following versions of IsAlNum are available:

IsAlpha Addressing Modes
Name Plain CS TOS Stk X CSi
IsAlpha X X X X - -

 

The IsAlNum macro allows the following operands:

IsAlpha Extended Syntax
Name   byteVar Num const [word Var] [dword Var] String Const
IsAlpha X X X X X -


3.4.3 Syntax & Examples

The following examples assume the following declarations:

 




chrVar  byte    ?
wPtr    word    chrVar
dPtr    dword   chrVar

         .
         .
         .

        mov     al, chrVar
        IsAlpha
        jz      InSet

        IsAlphaCS
        dword   chrVar
        jz      InSet

        push    wPtr            ;or push seg chrVar, push offset chrVar
        IsAlphaStk
        jz      IsInSet

        push    word ptr chrVar
        IsAlphaTOS

; Alternate syntax using stdlib addressing modes:

        mov     al, chrVar
        IsAlpha
        jz      IsInSet

        IsAlpha chrVar          ;Uses IsAlphaCS
        jz      IsInSet

        IsAlpha [wPtr]          ;Uses IsAlphaStk
        jz      IsInSet

        IsAlpha [dPtr]          ;Uses IsAlphaStk
        jz      IsInSet

        IsAlpha 'a'             ;Uses IsAlphaTOS
        jz      IsInSet


3.5 IsDigit

IsDigit checks a character to see if it is numeric {'0' - '9'}. This routine returns the zero flag set if the character is a member of this set, it returns the zero flag clear otherwise.


3.5.1 Calling Conventions and Assertions


3.5.2 IsDigit Addressing Modes

The following versions of IsDigit are available:

IsDigit Addressing Modes
Name Plain CS TOS Stk X CSi
IsDigit X X X X - -

 

The IsDigit macro allows the following operands:

IsDigit Extended Syntax
Name   byteVar Num const [word Var] [dword Var] String Const
IsDigit X X X X X -


3.5.3 Syntax & Examples

The following examples assume the following declarations:

 




chrVar  byte    ?
wPtr    word    chrVar
dPtr    dword   chrVar

         .
         .
         .

        mov     al, chrVar
        IsDigit
        jz      InSet

        IsDigitCS
        dword   chrVar
        jz      InSet

        push    wPtr            ;or push seg chrVar, push offset chrVar
        IsDigitStk
        jz      IsInSet

        push    word ptr chrVar
        IsDigitTOS

; Alternate syntax using stdlib addressing modes:

        mov     al, chrVar
        IsDigit
        jz      IsInSet

        IsDigit chrVar          ;Uses IsDigitCS
        jz      IsInSet

        IsDigit [wPtr]          ;Uses IsDigitStk
        jz      IsInSet

        IsDigit [dPtr]          ;Uses IsDigitStk
        jz      IsInSet

        IsDigit 'a'             ;Uses IsDigitTOS
        jz      IsInSet


3.6 IsLower

IsLower checks a character to see if it is a lower case alphabetic {'a' - 'z'}. This routine returns the zero flag set if the character is a member of this set, it returns the zero flag clear otherwise.


3.6.1 Calling Conventions and Assertions


3.6.2 IsLower Addressing Modes

The following versions of IsLower are available:

IsLower Addressing Modes
Name Plain CS TOS Stk X CSi
IsLower X X X X - -

 

The IsLower macro allows the following operands:

IsLower Extended Syntax
Name   byteVar Num const [word Var] [dword Var] String Const
IsLower X X X X X -


3.6.3 Syntax & Examples

The following examples assume the following declarations:

 

 




chrVar  byte    ?
wPtr    word    chrVar
dPtr    dword   chrVar

         .
         .
         .

        mov     al, chrVar
        IsLower
        jz      InSet

        IsLowerCS
        dword   chrVar
        jz      InSet

        push    wPtr            ;or push seg chrVar, push offset chrVar
        IsLowerStk
        jz      IsInSet

        push    word ptr chrVar
        IsLowerTOS

; Alternate syntax using stdlib addressing modes:

        mov     al, chrVar
        IsLower
        jz      IsInSet

        IsLower chrVar          ;Uses IsLowerCS
        jz      IsInSet

        IsLower [wPtr]          ;Uses IsLowerStk
        jz      IsInSet

        IsLower [dPtr]          ;Uses IsLowerStk
        jz      IsInSet

        IsLower 'a'             ;Uses IsLowerTOS
        jz      IsInSet


3.7 IsUpper

IsUpper checks a character to see if it is alphabetic {'a' - 'z', 'A' - 'Z'}. This routine returns the zero flag set if the character is a member of this set, it returns the zero flag clear otherwise.


3.7.1 Calling Conventions and Assertions

IsUpper:


3.7.2 IsUpper Addressing Modes

The following versions of IsUpper are available:

IsUpper Addressing Modes
Name Plain CS TOS Stk X CSi
IsUpper X X X X - -

 

The IsUpper macro allows the following operands:

IsUpper Extended Syntax
Name   byteVar Num const [word Var] [dword Var] String Const
IsUpper X X X X X -


3.7.3 Syntax & Examples

The following examples assume the following declarations:

 

 




chrVar  byte    ?
wPtr    word    chrVar
dPtr    dword   chrVar

         .
         .
         .

        mov     al, chrVar
        IsUpper
        jz      InSet

        IsUpperCS
        dword   chrVar
        jz      InSet

        push    wPtr            ;or push seg chrVar, push offset chrVar
        IsUpperStk
        jz      IsInSet

        push    word ptr chrVar
        IsUpperTOS

; Alternate syntax using stdlib addressing modes:

        mov     al, chrVar
        IsUpper
        jz      IsInSet

        IsUpper chrVar          ;Uses IsUpperCS
        jz      IsInSet

        IsUpper [wPtr]          ;Uses IsUpperStk
        jz      IsInSet

        IsUpper [dPtr]          ;Uses IsUpperStk
        jz      IsInSet

        IsUpper 'a'             ;Uses IsUpperTOS
        jz      IsInSet


3.8 IsXDigit

IsXDigit checks a character to see if it is a hexadecimal digit {'0' - '9', 'a' - 'f', 'A' - 'F'}. This routine returns the zero flag set if the character is a member of this set, it returns the zero flag clear otherwise.


3.8.1 Calling Conventions and Assertions


3.8.2 IsXDigit Addressing Modes

The following versions of IsXDigit are available:

IsXDigit Addressing Modes
Name Plain CS TOS Stk X CSi
IsXDigit X X X X - -

 

The IsXDigit macro allows the following operands:

IsXDigit Extended Syntax
Name   byteVar Num const [word Var] [dword Var] String Const
IsXDigit X X X X X -


3.8.3 Syntax & Examples

The following examples assume the following declarations:

 

 




chrVar  byte            ?
wPtr    word            chrVar
dPtr    dword           chrVar

         .
         .
         .

        mov             al, chrVar
        IsXDigit
        jz              InSet

        IsXDigitCS
        dword           chrVar
        jz              InSet

        push            wPtr            ;or push seg chrVar, push offset 
chrVar
        IsXDigitStk
        jz              IsInSet

        push            word ptr chrVar
        IsXDigitTOS

; Alternate syntax using stdlib addressing modes:

        mov             al, chrVar
        IsXDigit
        jz              IsInSet

        IsXDigit        chrVar          ;Uses IsXDigitCS
        jz              IsInSet

        IsXDigit        [wPtr]          ;Uses IsXDigitStk
        jz              IsInSet

        IsXDigit        [dPtr]          ;Uses IsXDigitStk
        jz              IsInSet

        IsXDigit        'a'             ;Uses IsXDigitTOS
        jz              IsInSet


3.9 ToLower

ToLower checks a character to see if it is an upper case character {'A' - 'Z'}. If it is, this routine converts that character to the corresponding lower case character. If the character is not alphabetic or it is already lower case, this function does not change it's value.


3.9.1 Calling Conventions and Assertions


3.9.2 ToLower Addressing Modes

The following versions of ToLower are available:

ToLower Addressing Modes
Name Plain CS TOS Stk X CSi
ToLower X X X X - -

 

The ToLower macro allows the following operands:

ToLower Extended Syntax
Name   byteVar Num const [word Var] [dword Var] String Const
ToLower X X X X X -


3.9.3 Syntax & Examples

The following examples assume the following declarations:

 

 




chrVar  byte    ?
wPtr    word    chrVar
dPtr    dword   chrVar

         .
         .
         .

        mov     al, chrVar
        ToLower

        ToLowerCS
        dword   chrVar

        push    wPtr            ;or push seg chrVar, push offset chrVar
        ToLowerStk

        push    word ptr chrVar
        ToLowerTOS

; Alternate syntax using stdlib addressing modes:

        mov     al, chrVar
        ToLower

        ToLower chrVar          ;Uses ToLowerCS

        ToLower [wPtr]          ;Uses ToLowerStk

        ToLower [dPtr]          ;Uses ToLowerStk

        ToLower 'a'             ;Uses ToLowerTOS


3.10 ToUpper

ToUpper checks a character to see if it is a lower case character {'a' - 'z'}. If it is, this routine converts that character to the corresponding upper case character. If the character is not alphabetic or it is already upper case, this function does not change it's value.


3.10.1 Calling Conventions and Assertions


3.10.2 ToUpper Addressing Modes

The following versions of ToUpper are available:

ToUpper Addressing Modes
Name Plain CS TOS Stk X CSi
ToUpper X X X X - -

 

The ToUpper macro allows the following operands:

ToUpper Extended Syntax
Name   byteVar Num const [word Var] [dword Var] String Const
ToUpper X X X X X -


3.10.3 Syntax & Examples

The following examples assume the following declarations:

 

 




chrVar  byte    ?
wPtr    word    chrVar
dPtr    dword   chrVar

         .
         .
         .

        mov     al, chrVar
        ToUpper

        ToUpperCS
        dword   chrVar

        push    wPtr            ;or push seg chrVar, push offset chrVar
        ToUpperStk

        push    word ptr chrVar
        ToUpperTOS

; Alternate syntax using stdlib addressing modes:

        mov     al, chrVar
        ToUpper

        ToUpper chrVar          ;Uses ToUpperCS

        ToUpper [wPtr]          ;Uses ToUpperStk

        ToUpper [dPtr]          ;Uses ToUpperStk

        ToUpper 'a'             ;Uses ToUpperTOS


3.11 Implementations

The following sections provide the implementations for the various CHAR routines.

 





3.11.1 IsAlNum Implementations

The following sections provide the source code for the four different "IsAlNum" routines (as of 11/96).

3.11.1.1 IsAlNum Implementation

This routine begins by checking the value in AL to see if it is in the range '0'..'9'. If AL's value is less than '0' this code returns (note that the zero flag will always be clear if this is the case). If the value is between '0' and '9', this code branches to the "IsAN" (Is AlphaNumeric) label that sets the zero flag before returning. If this code drops through the check for '0'..'9', we know the value must be greater than 39h (the ASCII code for '9'). This code logically ORs the value in AL with 20h. If we had an upper case character, this OR operation will convert it to lower case. Next, this code subtracts the ASCII code for 'a' from AL. If we had an alphabetic character (remember, 'A'..'Z' was converted to 'a'..'z') then the resulting value in AL is between zero and 25. The routine compares AL against this value and jumps to NotAN (Not an AlphaNumeric) if outside this range. Note, again, that the zero flag is automatically cleared if AL's value is outside the range 0..25. Of course, like any code procedure, this function preserves the value in AL if it has to modify it. For efficiency reasons, this code only pushes and pops the AX register if it actually changes the value in AL (as opposed to always pushing and popping AL upon entry/exit.

 




                include char.a

                echo    IsALNum 

ucrlib          segment para public 'ucrlib'
                assume  cs:ucrlib,ds:nothing


; IsAlNum-
;               Checks a character to see if it is alphanumeric.
;               Returns the status in the zero flag.
;               ZF=1 if character is in the set 
;                       {'0'..'9', 'A'..'Z', 'a'..'z'}
;               ZF=0 if the character is not in this set.
;       
;               Checks the character passed in the AL register.


                public  $IsAlNum
$IsAlNum        proc    far

                cmp     al, '0'         ;See if in the range '0'..'9'.
                jb      NotAN
                cmp     al, '9'
                jbe     IsAN

                push    ax
                or      al, 20h         ;Convert UC -> LC
                sub     al, 'a'         ;Convert 'a'..'z' -> 0..25
                cmp     al, 'z'-'a'     ;Is alpha if 25 or less.
                pop     ax
                jnbe    NotAN

; Down here, we've got an alphanumeric character.  Set the
; zero flag and return to the caller.

IsAN:           cmp     al, al

; If we branch down to this point, then the character is *not*
; an alphanumeric character.  Furthermore, you will notice that
; the zero flag is always clear if we branch to this point.

NotAN:          ret
$IsAlNum        endp
ucrlib          ends
                end

3.11.1.2 IsAlNumTOS Implementatiion

IsAlNumTOS fetches its parameter from the top of the stack. Upon entry, the stack looks something like the following:

 

Upon entry, the IsAlNumTOS function fetches this value from the stack and then checks it to see if it is in the set {'0'..'9', 'A'..'Z', 'a'..'z'} using the same technique that IsAlNum uses. On return, IsAlNumTOS automatically removes the two-byte parameter from the stack by executing the "ret 2" instruction.

 

Note: For details concerning how this function accesses data on the stack, see Chapter 11 of "The Art of Assembly Language Programming" (http://webster.ucr.edu).

 

 

 




                include char.a

                echo    IsALNumTOS 

ucrlib          segment para public 'ucrlib'
                assume  cs:ucrlib,ds:nothing


; IsAlNumTOS-
;               Checks a character to see if it is alphanumeric.
;               Returns the status in the zero flag.
;               ZF=1 if character is in the set 
;                       {'0'..'9', 'A'..'Z', 'a'..'z'}
;               ZF=0 if the character is not in this set.
;       
;               The character to check is in the L.O. byte of the
;               word passed as a parameter on the TOS.  On return,
;               this function pops that parameter off the stack.
;
; Typical Calling Sequence:
;
;               push    word ptr CharToTest     ;Ignores H.O. byte
;               call    $IsAlNumTOS
;               je      IsAlphaNumeric
;
;
;               push    bx
;               call    $IsAlNumTOS
;               jne     BXNotAN
 

                public  $IsAlNumTOS
$IsAlNumTOS     proc    far
                push    bp
                mov     bp, sp
                push    ax
                mov     al, [bp+6]      ;Get the character to test.

                cmp     al, '0'         ;See if in the range '0'..'9'.
                jb      NotAN
                cmp     al, '9'
                jbe     IsAN

                or      al, 20h         ;Convert UC -> LC
                sub     al, 'a'         ;Convert 'a'..'z' -> 0..25
                cmp     al, 'z'-'a'     ;Is alpha if 25 or less.
                jnbe    NotAN

; Note: if the code above branches to "NotAN" the zero flag is
; guaranteed to be clear.  But if we branch (or fall through) to
; IsAN, we must explicitly set the zero flag.

IsAN:           cmp     al, al
NotAN:          pop     ax
                pop     bp
                ret     2               ;Remove parameter from stack.
$IsAlNumTOS     endp
ucrlib          ends
                end

3.11.1.3 IsAlNumStk Implementation

IsAlNumStk expects a far pointer to a character variable. You must pass this address on the stack. Upon entry, the IsAlNumStk expects the stack to look like the following:

 

Upon entry, IsAlNumStk fetches the character pointed at by the pointer on the top of the stack and then checks it against the set {'0'..'9', 'A'..'Z', 'a'..'z'} in a manner identical to IsAlNum. On return, IsAlNumStk automatically pops the four-byte pointer to the character from the stack using a "ret 4" instruction.

 

Note: For details concerning how this function accesses data on the stack, see Chapter 11 of "The Art of Assembly Language Programming" (http://webster.ucr.edu).

 

 

 




                include char.a

                echo    IsALNum 

ucrlib          segment para public 'ucrlib'
                assume  cs:ucrlib,ds:nothing


; IsAlNumStk-
;               Checks a character to see if it is alphanumeric.
;               Returns the status in the zero flag.
;               ZF=1 if character is in the set 
;                       {'0'..'9', 'A'..'Z', 'a'..'z'}
;               ZF=0 if the character is not in this set.
;       
;               Far pointer to character is on the TOS.
;               Code removes the pointer upon return.
;
; Typical Calling Sequence:
;
;               pshadrs CharToTest
;               call    $IsAlNumStk



                public  $IsAlNum
                public  $IsAlNumStk
$IsAlNumStk     proc    far
                push    bp
                mov     bp, sp
                push    ds
                push    si
                push    ax
                
                lds     si, [bp+6]      ;Get the ptr to the char.
                mov     al, [si]        ;Fetch the char.

                cmp     al, '0'         ;See if in the range '0'..'9'.
                jb      NotAN
                cmp     al, '9'
                jbe     IsAN

                or      al, 20h         ;Convert UC -> LC
                sub     al, 'a'         ;Convert 'a'..'z' -> 0..25
                cmp     al, 'z'-'a'     ;Is alpha if 25 or less.
                jnbe    NotAN

; Note: If the code above branches the "NotAN" the zero flag is
; guaranteed to be clear.  But if it branches or falls through
; to "IsAN" we have to explicitly set the zero flag.

IsAN:           cmp     al, al
NotAN:          pop     ax
                pop     si
                pop     ds
                pop     bp
                ret     4               ;Removes ptr from the stack.
$IsAlNumStk     endp
ucrlib          ends
                end

3.11.1.4 IsAlNumCS Implementation

IsAlNumCS uses the return address as the pointer to a four-byte pointer to the actual character to test (that is, the address of the character to test immediately follows the call in the code stream). After fetching the pointer to the character, the IsAlNumCS code increments the return address (offset portion) on the stack by four so that it will skip over the address in the code stream when returning from the call. On entry, the stack looks like the following:

 

 

Note: For details concerning how this function accesses data in the code stream, see Chapter 11 of "The Art of Assembly Language Programming" (http://webster.ucr.edu).

 

 




                include char.a

                echo    IsALNumCS

ucrlib          segment para public 'ucrlib'
                assume  cs:ucrlib,ds:nothing


; IsAlNumCS-
;               Checks a character to see if it is alphanumeric.
;               Returns the status in the zero flag.
;               ZF=1 if character is in the set 
;                       {'0'..'9', 'A'..'Z', 'a'..'z'}
;               ZF=0 if the character is not in this set.
;       
;               Far pointer to character to test follows call.
;
;
; Typical Calling Sequence:
;
;               call    $IsAlNumCS
;               dword   CharToTest



                public  $IsAlNumCS
$IsAlNumCS      proc    far
                push    bp
                mov     bp, sp
                push    ax
                push    ds
                push    si

                lds     si, [bp+2]              ;Get return address.
                add     word ptr [bp+2], 4      ;Skip ptr to char on 
return.
                lds     si, [si]                ;Get ptr to char.
                mov     al, [si]                ;Get the char.

                cmp     al, '0'                 ;See if in the range 
'0'..'9'.
                jb      NotAN
                cmp     al, '9'
                jbe     IsAN

                or      al, 20h                 ;Convert UC -> LC
                sub     al, 'a'                 ;Convert 'a'..'z' -> 
0..25
                cmp     al, 'z'-'a'             ;Is alpha if 25 or less.
                jnbe    NotAN

IsAN:           cmp     al, al
NotAN:          pop     si
                pop     ds
                pop     ax
                pop     bp
                ret
$IsAlNumCS      endp
ucrlib          ends
                end


3.11.2 IsAlpha Implementations

The following sections provide the code for the IsAlpha routines as of 11/96.

 

3.11.2.1 IsAlpha Implementation

IsAlpha begins by logically ORing the character in AL with the value 20h. If the value in AL is an uppercase alphabetic, this converts it to lower case (it also converts control characters to something else, but it turns out we don't care about this). Next, it subtracts the ASCII code for 'a' from the value in AL. If AL contained an alphabetic character upon entry to IsAlpha, it will now contain a value in the range 0..25. IsAlpha compares this value against 25 and returns (with the zero flag implicitly cleared) if it is outside this range. Otherwise, it sets the zero flag and returns. Of course, IsAlpha preserves the value in the AL register.

 




                include char.a

                echo    IsAlpha 

ucrlib          segment para public 'ucrlib'
                assume  cs:ucrlib,ds:nothing


; IsAlpha-      Checks to see if a character is alphabetic.
;
;       Returns:
;
;               ZF = 1 if the character is alphabetic.
;               ZF = 0 if the character is not alphabetic.
;
;               This routine tests the character value passed in the
;               AL register.


                public  $IsAlpha
$IsAlpha        proc    far
                push    ax

                or      al, 20h         ;maps UC -> LC.
                sub     al, 'a'         ;maps 'a'..'z' -> 0..25.
                cmp     al, 'z'-'a'     ;If al > 25 then it's not alpha.
                ja      NotAlpha

; Note: If the code above branches to "NotAlpha" then the zero 
flag
; is guaranteed to be clear and we don't have to do anything about it.
; If we fall through to "IsAl" then we have to explicitly set the
; zero flag.

IsAl:           cmp     al, al          ;Sets zero flag
NotAlpha:       
                pop     ax
                ret
$IsAlpha        endp
ucrlib          ends
                end

3.11.2.2 IsAlphaTOS Implementation

IsAlphaTOS fetches its parameter from the top of the stack. Upon entry, the stack looks something like the following:

 

Upon entry, the IsAlphaTOS function fetches this value from the stack and then checks it to see if it is in the set {'A'..'Z', 'a'..'z'} using the same technique that IsAlpha uses. On return, IsAlphaTOS automatically removes the two-byte parameter from the stack by executing the "ret 2" instruction.

 

Note: For details concerning how this function accesses data on the stack, see Chapter 11 of "The Art of Assembly Language Programming" (http://webster.ucr.edu).

 

 




                include char.a

                echo    IsAlphaTOS 

ucrlib          segment para public 'ucrlib'
                assume  cs:ucrlib,ds:nothing


; IsAlphaTOS-   Checks to see if a character is alphabetic.
;
;       Returns:
;
;               ZF = 1 if the character is alphabetic.
;               ZF = 0 if the character is not alphabetic.
;
;               This routine tests the character value passed in the
;               L.O. byte of the word on the TOS.
;
;               This function automatically removes the parameter from
;               the stack for the caller.
;
; Typical Calling Sequence:
;
;       push    word ptr CharToTest     ;Ignores H.O. byte
;       call    $IsAlphaTOS
;
;        .
;        .
;        .
;
;       push    bx
;       call    $IsAlphaTOS

                public  $IsAlphaTOS
$IsAlphaTOS     proc    far
                push    bp
                mov     bp, sp
                push    ax
                mov     al, [bp+6]      ;Get the char.

                or      al, 20h         ;maps UC -> LC.
                sub     al, 'a'         ;maps 'a'..'z' -> 0..25.
                cmp     al, 'z'-'a'     ;If al > 25 then it's not alpha.
                ja      NotAlpha

; Note: If the code above branches to "NotAlpha" then the zero 
flag
; is guaranteed to be clear and we don't have to do anything about it.
; If we fall through to "IsAl" then we have to explicitly set the
; zero flag.

IsAl:           cmp     al, al          ;Sets zero flag
NotAlpha:       
                pop     ax
                pop     bp
                ret     2               ;Remove parameter from stack.
$IsAlphaTOS     endp
ucrlib          ends
                end

3.11.2.3 IsAlphaStk Implementation

IsAlphaStk expects a far pointer to a character variable. You must pass this address on the stack. Upon entry, the IsAlphaStk expects the stack to look like the following:

 

Upon entry, IsAlphaStk fetches the character pointed at by the pointer on the top of the stack and then checks it against the set {'A'..'Z', 'a'..'z'} in a manner identical to IsAlpha. On return, IsAlphaStk automatically pops the four-byte pointer to the character from the stack using a "ret 4" instruction.

 

Note: For details concerning how this function accesses data on the stack, see Chapter 11 of "The Art of Assembly Language Programming" (http://webster.ucr.edu).

 

 




                include char.a

                echo    IsAlphaStk 

ucrlib          segment para public 'ucrlib'
                assume  cs:ucrlib,ds:nothing


; IsAlphaStk-   Checks to see if a character is alphabetic.
;
;       Returns:
;
;               ZF = 1 if the character is alphabetic.
;               ZF = 0 if the character is not alphabetic.
;
;               This routine expects the (far) address of a character
;               variable on the TOS.  It fetches and tests that character
;               to see if it is alphabetic.  On return, this procedure
;               removes the pointer from the stack.
;
; Typical Calling Sequence:
;
;       pshadrs CharToTest
;       call    $IsAlphaStk




                public  $IsAlphaStk
$IsAlphaStk     proc    far
                push    bp
                mov     bp, sp
                push    ds
                push    si
                push    ax
                
                lds     si, [bp+6]      ;Get ptr to char
                mov     al, [si]        ;Get the char.

                or      al, 20h         ;maps UC -> LC.
                sub     al, 'a'         ;maps 'a'..'z' -> 0..25.
                cmp     al, 'z'-'a'     ;If al > 25 then it's not alpha.
                ja      NotAlpha

; Note: If the code above branches to "NotAlpha" then the zero 
flag
; is guaranteed to be clear and we don't have to do anything about it.
; If we fall through to "IsAl" then we have to explicitly set the
; zero flag.

IsAl:           cmp     al, al          ;Sets zero flag
NotAlpha:       pop     ax
                pop     si
                pop     ds
                pop     bp
                ret     4               ;Remove pointer from stk on return.
$IsAlphaStk     endp
ucrlib          ends
                end

3.11.2.4 IsAlphaCS Implementation

IsAlphaCS uses the return address as the pointer to a four-byte pointer to the actual character to test (that is, the address of the character to test immediately follows the call in the code stream). After fetching the pointer to the character, the IsAlphaCS code increments the return address (offset portion) on the stack by four so that it will skip over the address in the code stream when returning from the call. On entry, the stack looks like the following:

 

 

Note: For details concerning how this function accesses data in the code stream, see Chapter 11 of "The Art of Assembly Language Programming" (http://webster.ucr.edu).

 

 




                include char.a

                echo    IsAlphaCS

ucrlib          segment para public 'ucrlib'
                assume  cs:ucrlib,ds:nothing


; IsAlphaCS-    Checks to see if a character is alphabetic.
;
;       Returns:
;
;               ZF = 1 if the character is alphabetic.
;               ZF = 0 if the character is not alphabetic.
;
;               This routine expects a pointer to a character
;               variable.  The pointer must immediately follow
;               the call in the code stream.
;
; Typical Calling Sequence:
;
;       call    $IsAlphaCS
;       dword   CharToTest



                public  $IsAlphaCS
$IsAlphaCS      proc    far
                push    bp
                mov     bp, sp
                push    ax
                push    ds
                push    si

                lds     si, [bp+2]              ;Get return address.
                add     word ptr [bp+2], 4      ;Skip ptr to char.
                lds     si, [si]                ;Get ptr to char.
                mov     al, [si]                ;Get the char.

                or      al, 20h                 ;maps UC -> LC.
                sub     al, 'a'                 ;maps 'a'..'z' -> 0..25.
                cmp     al, 'z'-'a'             ;If al > 25 then it's 
not alpha.
                ja      NotAlpha

; Note: If the code above branches to "NotAlpha" then the zero 
flag
; is guaranteed to be clear and we don't have to do anything about it.
; If we fall through to "IsAl" then we have to explicitly set the
; zero flag.

IsAl:           cmp     al, al          ;Sets zero flag
NotAlpha:       
                pop     si
                pop     ds
                pop     ax
                pop     bp
                ret
$IsAlphaCS      endp
ucrlib          ends
                end


3.11.3 IsDigit Implementations

The following sections provide the source code for the IsDigit implementations as of 11/96.

3.11.3.1 IsDigit Implementation

Of all the Isxxxx routines, the IsDigit routines have the most obvious implementation. The IsDigit routine simply compares the value in AL against the characters "0" and "9" and branches (with the zero flag implicitly cleared) if the character is outside this range. They set the zero flag (by comparing AL with itself) if AL is within this range. Given the triviality of this function, it should really be a macro; it is not because I wanted to use a consistent procedure call interface across all IsDigitxxx routines.

 




                include char.a

                echo    IsDigit

ucrlib          segment para public 'ucrlib'
                assume  cs:ucrlib,ds:nothing


; IsDigit-      Checks a character to see if it is a decimal digit.
;
; IsDigit-      Checks character in AL.
; IsDigitCS-    Dword pointer after call points at character.
; IsDigitStk-   Dword pointer to character is on TOS.
; IsDigitTOS-   Character to test is on TOS.

                public  $IsDigit
$IsDigit        proc    far

                cmp     al, '0'
                jb      NotDigit
                cmp     al, '9'
                ja      NotDigit
                cmp     al, al                  ;Sets zero flag.
NotDigit:       
                ret
$IsDigit        endp
ucrlib          ends
                end

3.11.3.2 IsDigitTOS Implementation




                include char.a

                echo    IsDigitTOS

ucrlib          segment para public 'ucrlib'
                assume  cs:ucrlib,ds:nothing


; IsDigitTOS-   Checks a character to see if it is a decimal digit.
;               The character to test appears in the L.O. byte of the
;               word on the TOS.
;
;       On Return:
;
;               ZF=1 if this is a decimal digit character.
;               ZF=0 if it is not a digit.
;
;
;       Automatically removes the parameter from the stack.

                public  $IsDigitTOS
$IsDigitTOS     proc    far
                push    bp
                mov     bp, sp
                push    ax
                mov     al, [bp+6]      ;Fetch character to test.

; Note that the following code guarantees that the zero flag is
; clear if the code *branches* to location NotDigit.
; We have to explicitly set the zero flag if we've got a digit.

                cmp     al, '0'
                jb      NotDigit
                cmp     al, '9'
                ja      NotDigit
                cmp     al, al          ;Sets zero flag.
NotDigit:       
                pop     ax
                pop     bp
                ret     2               ;Remove word on TOS.
$IsDigitTOS     endp
ucrlib          ends
                end

3.11.3.3 IsDigitStk Implementation




                include char.a

                echo    IsDigitStk

ucrlib          segment para public 'ucrlib'
                assume  cs:ucrlib,ds:nothing


; IsDigitStk-   Checks a character to see if it is a decimal digit.
;               A far pointer to the character to test appears on
;               the top of the stack.
;
;       On Return:
;
;               ZF=1 if this is a decimal digit character.
;               ZF=0 if it is not a digit.
;
;
;       Automatically removes the parameter from the stack.

                public  $IsDigitStk
$IsDigitStk     proc    far
                push    bp
                mov     bp, sp
                push    ds
                push    si
                push    ax
                
                lds     si, [bp+6]      ;Fetch pointer to character.
                mov     al, [si]        ;Fetch the character.

; Note that the following code guarantees that the zero flag is
; clear if the code *branches* to location NotDigit.
; We have to explicitly set the zero flag if we've got a digit.

                cmp     al, '0'         ;See if it is numeric.
                jb      NotDigit
                cmp     al, '9'
                ja      NotDigit
                cmp     al, al          ;Sets zero flag.
NotDigit:       
                pop     ax
                pop     si
                pop     ds
                pop     bp
                ret     4               ;Remove ptr from stack.
$IsDigitStk     endp
ucrlib          ends
                end

3.11.3.4 IsDigitCS Implementation




                include char.a

                echo    IsDigitCS

ucrlib          segment para public 'ucrlib'
                assume  cs:ucrlib,ds:nothing


; IsDigitCS-    Checks a character to see if it is a decimal digit.
;               Far pointer to character immediately follows the
;               call in the code stream.
;
;       On Return:
;
;               ZF=1 if this is a decimal digit character.
;               ZF=0 if it is not a digit.
;
;
;       Automatically skips over the far address in the code stream.


                public  $IsDigitCS
$IsDigitCS      proc    far
                push    bp
                mov     bp, sp
                push    ax
                push    ds
                push    si

                lds     si, [bp+2]              ;Get return address.
                add     word ptr [bp+2], 4      ;Skip ptr to char.
                lds     si, [si]                ;Get ptr to char.
                mov     al, [si]                ;Get the char.

; Note that the following code guarantees that the zero flag is
; clear if the code *branches* to location NotDigit.
; We have to explicitly set the zero flag if we've got a digit.

                cmp     al, '0'                 ;See if it's a digit.
                jb      NotDigit
                cmp     al, '9'
                ja      NotDigit
                cmp     al, al                  ;Sets zero flag.
NotDigit:       

                pop     si
                pop     ds
                pop     ax
                pop     bp
                ret
$IsDigitCS      endp
ucrlib          ends
                end


3.11.4 IsLower Implementations

The following sections provide the implementations of the IsLower routines as of 11/96.

3.11.4.1 IsLower Implementation




                include char.a

                echo    IsLower

ucrlib          segment para public 'ucrlib'
                assume  cs:ucrlib,ds:nothing


; IsLower-      Checks to see if a character is lower case.
;
;       Returns:
;
;               ZF=1 if the character is a lower case alphabetic character.
;               ZF=0 if it is not lower case.
;
;               IsLower expects the character to test in the AL register.
;
; Typical Calling Sequence
;
;       mov     al, CharToTest
;       call    $IsLower
;       je      IsLowerCase


                public  $IsLower
$IsLower        proc    far
                cmp     al, 'a'
                jb      NotLower
                cmp     al, 'z'
                ja      IsLow
IsLow:          cmp     al, al                  ;Sets zero flag
NotLower:       ret
$IsLower        endp
ucrlib          ends
                end

3.11.4.2 IsLowerTOS




                include char.a

                echo    IsLowerTOS

ucrlib          segment para public 'ucrlib'
                assume  cs:ucrlib,ds:nothing


; IsLower-      Checks to see if a character is lower case.
;
;       Returns:
;
;               ZF=1 if the character is a lower case alphabetic character.
;               ZF=0 if it is not lower case.
;
;               This routine expects the character to test in the L.O. byte
;               of the word appearing on TOS.
;
; Typical Calling Sequence
;
;       push    word ptr CharToTest     ;Ignores H.O. byte
;       call    $IsLowerTOS
;       je      IsLowerCase
;
;       push    bx
;       call    $IsLowerTOS
;       je      AnotherLC



                public  $IsLowerTOS
$IsLowerTOS     proc    far
                push    bp
                mov     bp, sp
                push    ax

                mov     al, [bp+6]              ;Get the char.
                cmp     al, 'a'                 ;See if it is
                jb      NotLower                ; lowercase.
                cmp     al, 'z'
                ja      IsLow
IsLow:          cmp     al, al                  ;Sets zero flag if lower 
case.
NotLower:                                       ;ZF automatically clear if
                pop     ax                      ; not lower case.
                pop     bp
                ret     2                       ;Remove parameter from 
stack.
$IsLowerTOS     endp
ucrlib          ends
                end

3.11.4.3 IsLowerStk Implementation




                include char.a

                echo    IsLowerStk

ucrlib          segment para public 'ucrlib'
                assume  cs:ucrlib,ds:nothing


; IsLower-      Checks to see if a character is lower case.
;
;       Returns:
;
;               ZF=1 if the character is a lower case alphabetic character.
;               ZF=0 if it is not lower case.
;
;               This routine expects a pointer to the character to test
;               on the top of the stack.
;
; Typical Calling Sequence
;
;       pshadrs CharToTest
;       call    $IsLowerStk
;       je      IsLowerCase



                public  $IsLowerStk
$IsLowerStk     proc    far
                push    bp
                mov     bp, sp
                push    ds
                push    si
                push    ax
                
                lds     si, [bp+6]              ;Get ptr to char
                mov     al, [si]                ;Get the char.

                cmp     al, 'a'                 ;See if the character
                jb      NotLower                ; is lower case.
                cmp     al, 'z'
                ja      IsLow
IsLow:          cmp     al, al                  ;Sets zero flag
NotLower:                                       ;If LC, zero flag is clear
                pop     ax                      ; by default.
                pop     si
                pop     ds
                pop     bp
                ret     4                       ;Remove ptr from stack.
$IsLowerStk     endp
ucrlib          ends
                end

3.11.4.4 IsLowerCS Implementation




                include char.a

                echo    IsLowerCS

ucrlib          segment para public 'ucrlib'
                assume  cs:ucrlib,ds:nothing


; IsLower-      Checks to see if a character is lower case.
;
;       Returns:
;
;               ZF=1 if the character is a lower case alphabetic character.
;               ZF=0 if it is not lower case.
;
;               A far pointer to the character to test follows the
;               call in the code stream.
;
; Typical Calling Sequence
;
;       call    $IsLower
;       dword   CharToTest
;       je      IsLowerCase


                public  $IsLowerCS
$IsLowerCS      proc    far
                push    bp
                mov     bp, sp
                push    ax
                push    ds
                push    si

                lds     si, [bp+2]              ;Get return address.
                lds     si, [si]                ;Get ptr to char.
                mov     al, [si]                ;Get the char.
                add     word ptr [bp+2], 4      ;Skip ptr to char.

                cmp     al, 'a'                 ;See if we have
                jb      NotLower                ; a lower case
                cmp     al, 'z'                 ; character.
                ja      IsLow
IsLow:          cmp     al, al                  ;Sets zero flag if LC.
NotLower:                                       ;ZF clear if not LC.
                pop     si
                pop     ds
                pop     ax
                pop     bp
                ret
$IsLowerCS      endp
ucrlib          ends
                end


3.11.5 IsUpper Implementations

The following sections provide the source for for the IsUpper routines as of 11/96.

3.11.5.1 IsUpper Implementation




                include char.a

                echo    IsUpper

ucrlib          segment para public 'ucrlib'
                assume  cs:ucrlib,ds:nothing



; IsUpper-      Checks to see if a character is upper case.
;
;       Returns:
;
;               ZF=1 if the character is upper case.
;               ZF=0 if the character is not lower case.
;
;               Tests the character passed in the AL register.
;
;
; Typical Calling Sequence
;
;       mov     al, CharToTest
;       call    $IsUpper
;       je      IsAnUpperCase



                public  $IsUpper
$IsUpper        proc    far
                cmp     al, 'A'                 ;Check to see if this is 
UC.
                jb      NotUpper                ;Note that if we branch to
                cmp     al, 'Z'                 ; the NotUpper label, the 
zero
                ja      NotUpper                ; flag is automatically 
cleared.
IsUp:           cmp     al, al                  ;Sets zero flag
NotUpper:       ret
$IsUpper        endp
ucrlib          ends
                end

3.11.5.2 IsUpperTOS Implementation




                include char.a

                echo    IsUpperTOS

ucrlib          segment para public 'ucrlib'
                assume  cs:ucrlib,ds:nothing



; IsUpperTOS-   Checks to see if a character is upper case.
;
;       Returns:
;
;               ZF=1 if the character is upper case.
;               ZF=0 if the character is not lower case.
;
;               Tests the character passed in the L.O. byte of the
;               word pushed on the stack before the call.
;
;
; Typical Calling Sequence
;
;       push    word ptr CharToTest     ;Ignores H.O. byte
;       call    $IsUpperTOS
;       je      IsAnUpperCase




                public  $IsUpperTOS
$IsUpperTOS     proc    far
                push    bp
                mov     bp, sp
                push    ax
                mov     al, [bp+6]              ;Get the char.

                cmp     al, 'A'                 ;Check to see if this is 
UC.
                jb      NotUpper                ;Note that if we branch to
                cmp     al, 'Z'                 ; the NotUpper label, the 
zero
                ja      NotUpper                ; flag is automatically 
cleared.
IsUp:           cmp     al, al                  ;Sets zero flag
NotUpper:
                pop     ax
                pop     bp
                ret     2                       ;Remove parameter from 
stack.
$IsUpperTOS     endp
ucrlib          ends
                end

3.11.5.3 IsUpperStk Implementation




                include char.a

                echo    IsUpperSTK

ucrlib          segment para public 'ucrlib'
                assume  cs:ucrlib,ds:nothing



; IsUpperSTK-   Checks to see if a character is upper case.
;
;       Returns:
;
;               ZF=1 if the character is upper case.
;               ZF=0 if the character is not lower case.
;
;               A far pointer to the character appears on the TOS.
;
;
; Typical Calling Sequence
;
;       pshadrs CharToTest
;       call    $IsUpperSTK
;       je      IsAnUpperCase



                public  $IsUpperStk
$IsUpperStk     proc    far
                push    bp
                mov     bp, sp
                push    ds
                push    si
                push    ax
                
                lds     si, [bp+6]              ;Get ptr to char
                mov     al, [si]                ;Get the char.

                cmp     al, 'A'                 ;Check to see if this is 
UC.
                jb      NotUpper                ;Note that if we branch to
                cmp     al, 'Z'                 ; the NotUpper label, the 
zero
                ja      NotUpper                ; flag is automatically 
cleared.
IsUp:           cmp     al, al                  ;Sets zero flag
NotUpper:
                pop     ax
                pop     si
                pop     ds
                pop     bp
                ret     4                       ;Remove pointer from stack.
$IsUpperStk     endp
ucrlib          ends
                end

3.11.5.4 IsUpperCS Implementation




                include char.a

                echo    IsUpperCS

ucrlib          segment para public 'ucrlib'
                assume  cs:ucrlib,ds:nothing



; IsUpperCS-    Checks to see if a character is upper case.
;
;       Returns:
;
;               ZF=1 if the character is upper case.
;               ZF=0 if the character is not lower case.
;
;               A pointer to the character to test follows in
;               the code stream.
;
;
; Typical Calling Sequence
;
;       call    $IsUpperCS
;       dword   CharToTest
;       je      IsAnUpperCase



                public  $IsUpperCS
$IsUpperCS      proc    far
                push    bp
                mov     bp, sp
                push    ax
                push    ds
                push    si

                lds     si, [bp+2]              ;Get return address.
                lds     si, [si]                ;Get ptr to char.
                mov     al, [si]                ;Get the char.
                add     word ptr [bp+2], 4      ;Skip ptr to char.

                cmp     al, 'A'                 ;Check to see if this is 
UC.
                jb      NotUpper                ;Note that if we branch to
                cmp     al, 'Z'                 ; the NotUpper label, the 
zero
                ja      NotUpper                ; flag is automatically 
cleared.
IsUp:           cmp     al, al                  ;Sets zero flag
NotUpper:
                pop     si
                pop     ds
                pop     ax
                pop     bp
                ret
$IsUpperCS      endp
ucrlib          ends
                end


3.11.6 IsXDigit Implementations

The following sections provide the implementations for the IsXDigit routines as of 11/96.

 

3.11.6.1 IsXDigit Implementation




                include char.a

                echo    IsXDigit 

ucrlib          segment para public 'ucrlib'
                assume  cs:ucrlib,ds:nothing


; IsxDigit-     Checks a character to see if it is a hex digit 
;                       {'0'..'9', 'A'..'F', 'a'..'f'}.
;
;               This routine expects the character to test in the
;               AL register.
;
;       Returns:
;
;               ZF=1 if it is a hexadecimal character.
;               ZF=0 if it is not a hex character.
;
; Typical Calling Sequence:
;
;       mov     al, CharToTest
;       call    $IsxDigit
;       je      IsHexChar


                public  $IsxDigit
$IsxDigit       proc    far
                push    ax

                sub     al, '0'         ;'0'..'9' -> 0..9
                cmp     al, 9
                jbe     IsX

                and     al, 0dfh        ;lc -> UC.
                sub     al, 'A'-'0'     ;'A'..'Z' -> 0..25
                cmp     al, 'Z'-'0'
                ja      NotX

; If we branch or fall through to "IsX" then we have no idea
; what the state of the zero flag is.  We must explicitly set
; it.  However, if we branch to "NotX" then we know that the
; zero flag is clear.

IsX:            cmp     al, al          ;Sets zero flag
NotX:           
                pop     ax
                ret     
$IsxDigit       endp
ucrlib          ends
                end

3.11.6.2 IsXDigitTOS Implementation




                include char.a

                echo    IsXDigitTOS 

ucrlib          segment para public 'ucrlib'
                assume  cs:ucrlib,ds:nothing


; IsxDigitTOS-  Checks a character to see if it is a hex digit 
;                       {'0'..'9', 'A'..'F', 'a'..'f'}.
;
;               This routine expects the character to test in the
;               L.O byte of the word on TOS.
;
;       Returns:
;
;               ZF=1 if it is a hexadecimal character.
;               ZF=0 if it is not a hex character.
;
; Typical Calling Sequence:
;
;       push    word ptr CharToTest     ;Ignores H.O. byte
;       call    $IsxDigitTOS
;       je      IsHexChar


                public  $IsXDigitTOS
$IsXDigitTOS    proc    far
                push    bp
                mov     bp, sp
                push    ax
                mov     al, [bp+6]

                sub     al, '0'         ;'0'..'9' -> 0..9
                cmp     al, 9
                jbe     IsX

                and     al, 0dfh        ;lc -> UC.
                sub     al, 'A'-'0'     ;'A'..'Z' -> 0..25
                cmp     al, 'Z'-'0'
                ja      NotX

; If we branch or fall through to "IsX" then we have no idea
; what the state of the zero flag is.  We must explicitly set
; it.  However, if we branch to "NotX" then we know that the
; zero flag is clear.

IsX:            cmp     al, al          ;Sets zero flag
NotX:
                pop     ax
                pop     bp
                ret     2               ;Pops parameter off stack.
$IsXDigitTOS    endp
ucrlib          ends
                end

3.11.6.3 IsXDigitStk Implementation




                include char.a

                echo    IsXDigitStk 

ucrlib          segment para public 'ucrlib'
                assume  cs:ucrlib,ds:nothing


; IsxDigitStk-  Checks a character to see if it is a hex digit 
;                       {'0'..'9', 'A'..'F', 'a'..'f'}.
;
;               A far pointer to the character to test appears on
;               the top of the stack.
;
;       Returns:
;
;               ZF=1 if it is a hexadecimal character.
;               ZF=0 if it is not a hex character.
;
; Typical Calling Sequence:
;
;       pshadrs CharToTest
;       call    $IsxDigitStk
;       je      IsHexChar


                public  $IsXDigitStk
$IsXDigitStk    proc    far
                push    bp
                mov     bp, sp
                push    ds
                push    si
                push    ax
                
                lds     si, [bp+6]
                mov     al, [si]

                sub     al, '0'         ;'0'..'9' -> 0..9
                cmp     al, 9
                jbe     IsX

                and     al, 0dfh        ;lc -> UC.
                sub     al, 'A'-'0'     ;'A'..'Z' -> 0..25
                cmp     al, 'Z'-'0'
                ja      NotX

; If we branch or fall through to "IsX" then we have no idea
; what the state of the zero flag is.  We must explicitly set
; it.  However, if we branch to "NotX" then we know that the
; zero flag is clear.

IsX:            cmp     al, al          ;Sets zero flag
NotX:                   
                pop     ax
                pop     si
                pop     ds
                pop     bp
                ret     4
$IsXDigitStk    endp
ucrlib          ends
                end

3.11.6.4 IsXDigitCS Implementation




                include char.a

                echo    IsXDigitCS 

ucrlib          segment para public 'ucrlib'
                assume  cs:ucrlib,ds:nothing


; IsxDigitCS-   Checks a character to see if it is a hex digit 
;                       {'0'..'9', 'A'..'F', 'a'..'f'}.
;
;               A far pointer to the character to test follows
;               the call in the code stream.
;
;       Returns:
;
;               ZF=1 if it is a hexadecimal character.
;               ZF=0 if it is not a hex character.
;
; Typical Calling Sequence:
;
;       call    $IsxDigitCS
;       dword   CharToTest
;       je      IsHexChar



                public  $IsXDigitCS
$IsXDigitCS     proc    far
                push    bp
                mov     bp, sp
                push    ax
                push    ds
                push    si

                lds     si, [bp+2]              ;Get return address.
                lds     si, [si]                ;Get ptr to char.
                mov     al, [si]                ;Get the char.
                add     word ptr [bp+2], 4      ;Skip ptr to char.

                sub     al, '0'         ;'0'..'9' -> 0..9
                cmp     al, 9
                jbe     IsX

                and     al, 0dfh        ;lc -> UC.
                sub     al, 'A'-'0'     ;'A'..'Z' -> 0..25
                cmp     al, 'Z'-'0'
                ja      NotX

; If we branch or fall through to "IsX" then we have no idea
; what the state of the zero flag is.  We must explicitly set
; it.  However, if we branch to "NotX" then we know that the
; zero flag is clear.

IsX:            cmp     al, al          ;Sets zero flag
NotX:   
                pop     si
                pop     ds
                pop     ax
                pop     bp
                ret
$IsXDigitCS     endp
ucrlib          ends
                end


3.11.7 ToLower Implementations

The following sections provide the implementations for the ToLower routines as o 11/96.

 

3.11.7.1 ToLower Implementation




                include char.a

                echo    ToLower

ucrlib          segment para public 'ucrlib'
                assume  cs:ucrlib,ds:nothing



; ToLower-
;
;       Converts upper case ASCII characters to lower case.
;       If the character is not an upper case character, this
;       routine leaves it unchanged.
;
;       AL contains the character to convert to lower case.
;       It returns the converted character in AL.
;
; Typical Calling Sequence:
;
;       mov     al, CharToConvert
;       call    $ToLower
;       mov     ConvertedChar, al


                public  $ToLower
$ToLower        proc    far
                cmp     al, 'A'                 ;See if it's an upper
                jb      NotUpper                ; case character.
                cmp     al, 'Z'
                ja      NotUpper
                and     al, 5fh                 ;Convert UC -> lc.
NotUpper:       ret
$ToLower        endp
ucrlib          ends
                end

3.11.7.2 ToLowerTOS Implementation




                include char.a

                echo    ToLowerTOS

ucrlib          segment para public 'ucrlib'
                assume  cs:ucrlib,ds:nothing



; ToLowerTOS-
;
;       Converts upper case ASCII characters to lower case.
;       If the character is not an upper case character, this
;       routine leaves it unchanged.
;
;       The L.O. byte of the word on TOS contains the character
;       to convert.  On return, this routine leaves that word
;       (containing the converted character) on the TOS.
;
; Typical Calling Sequence:
;
;       push    word ptr CharToConvert  ;Ignores H.O. byte
;       call    $ToLower
;       pop     ax
;       mov     ConvertedChar, al


                public  $ToLowerTOS
$ToLowerTOS     proc    far
                push    bp
                mov     bp, sp
                push    ax
                mov     al, [bp+6]      ;Get the char to convert.
                cmp     al, 'A'         ;See if it's an upper
                jb      NotUpper        ; case character.
                cmp     al, 'Z'
                ja      NotUpper
                and     al, 5fh         ;Convert UC -> lc.
NotUpper:       mov     [bp+6], al      ;Store back onto TOS.

                pop     ax
                pop     bp
                ret
$ToLowerTOS     endp
ucrlib          ends
                end

3.11.7.3 ToLowerStk Implementation





                include char.a

                echo    ToLowerStk

ucrlib          segment para public 'ucrlib'
                assume  cs:ucrlib,ds:nothing



; ToLowerStk-
;
;       Converts upper case ASCII characters to lower case.
;       If the character is not an upper case character, this
;       routine leaves it unchanged.
;
;       The TOS contains a far pointer to the character to convert.
;       This code fetches that character, converts it to lower case
;       (if applicable) and then stores the character back to its
;       original location.
;
;       This routine removes the pointer from the stack upon returning.
;
; Typical Calling Sequence:
;
;       lesi    CharToConvert
;       call    $ToLowerStk


                public  $ToLowerStk
$ToLowerStk     proc    far
                push    bp
                mov     bp, sp
                push    ds
                push    si
                push    ax
                
                lds     si, [bp+6]      ;Get ptr to the character.
                mov     al, [si]        ;Fetch the character.
                cmp     al, 'A'         ;See if it's an upper
                jb      NotUpper        ; case character.
                cmp     al, 'Z'
                ja      NotUpper
                and     al, 5fh         ;Convert UC -> lc.
NotUpper:       mov     [si], al        ;Store result.

                pop     ax
                pop     si
                pop     ds
                pop     bp
                ret     4               ;Remove ptr from stack.
$ToLowerStk     endp
ucrlib          ends
                end

3.11.7.4 ToLowerCS Implementation




                include char.a

                echo    ToLowerCS

ucrlib          segment para public 'ucrlib'
                assume  cs:ucrlib,ds:nothing



; ToLowerCS-
;
;       Converts upper case ASCII characters to lower case.
;       If the character is not an upper case character, this
;       routine leaves it unchanged.
;
;       A far pointer to the character to convert follows in
;       the code stream.
;
; Typical Calling Sequence:
;
;       call    $ToLowerCS
;       dword   CharToConvert


                public  $ToLowerCS
$ToLowerCS      proc    far
                push    bp
                mov     bp, sp
                push    ax
                push    ds
                push    si

                lds     si, [bp+2]              ;Get return address.
                add     word ptr [bp+2], 4      ;Skip ptr to char.
                lds     si, [si]                ;Get ptr to char.
                mov     al, [si]                ;Get the char.

                cmp     al, 'A'                 ;See if it's an upper
                jb      NotUpper                ; case character.
                cmp     al, 'Z'
                ja      NotUpper
                and     al, 5fh                 ;Convert UC -> lc.
NotUpper:       mov     [si], al                ;Store the character.

                pop     si
                pop     ds
                pop     ax
                pop     bp
                ret
$ToLowerCS      endp
ucrlib          ends
                end


3.11.8 ToUpper Implementations

The following sections provide the implementation of the ToUpper routines as of 11/96.

 

3.11.8.1 ToUpper Implementation




                include char.a

                echo    ToUpper 

ucrlib          segment para public 'ucrlib'
                assume  cs:ucrlib,ds:nothing




; ToUpper-
;
;       Converts lower case ASCII characters to upper case.
;       If the character is not a lower case character, this
;       routine leaves it unchanged.
;
;       The AL register contains the character to convert to upper case.
;       This function returns the converted character in AL.
;
; Typical Calling Sequence:
;
;       mov     al, CharToConvert
;       call    $ToUpper
;       mov     ConvertedChar, al


                public  $ToUpper
$ToUpper        proc    far
                cmp     al, 'a'                 ;See if we've got a
                jb      NotLower                ; lower case character
                cmp     al, 'z'                 ; to convert.
                ja      NotLower
                and     al, 05fh                ;Convert lc -> UC.
NotLower:       ret
$ToUpper        endp
ucrlib          ends
                end

3.11.8.2 ToUpperTOS Implementation




                include char.a

                echo    ToUpperTOS 

ucrlib          segment para public 'ucrlib'
                assume  cs:ucrlib,ds:nothing




; ToUpperTOS-
;
;       Converts lower case ASCII characters to upper case.
;       If the character is not a lower case character, this
;       routine leaves it unchanged.
;
;       The L.O. byte of the TOS contains the character to convert.
;       This routine converts it to upper case (if necessary) and then
;       leaves the result on the TOS upon return.
;
; Typical Calling Sequence:
;
;       push    word ptr CharToConvert  ;Ignores H.O. byte
;       call    $ToUpperTOS
;       pop     ax
;       mov     ConvertedChar, al


                public  $ToUpperTOS
                public  $ToUpperTOS
$ToUpperTOS     proc    far
                push    bp
                mov     bp, sp
                push    ax
                mov     al, [bp+6]      ;Get char to convert from stack.

                cmp     al, 'a'         ;See if we've got a
                jb      NotLower        ; lower case character
                cmp     al, 'z'         ; to convert.
                ja      NotLower
                and     al, 5fh         ;Convert lc -> UC.
NotLower:
                mov     [bp+6], al      ;Save result back on TOS.

                pop     ax
                pop     bp
                ret
$ToUpperTOS     endp
ucrlib          ends
                end

3.11.8.3 ToUpperStk Implementation




                include char.a

                echo    ToUpperStk 

ucrlib          segment para public 'ucrlib'
                assume  cs:ucrlib,ds:nothing




; ToUpperStk-
;
;       Converts lower case ASCII characters to upper case.
;       If the character is not a lower case character, this
;       routine leaves it unchanged.
;
;       The TOS contains a far pointer to a character.  This
;       routine converts that character (if necessary) and stores
;       the result back to its original location.
;
; Typical Calling Sequence:
;
;       pshadrs CharToConvert
;       call    $ToUpperStk


                public  $ToUpperStk
$ToUpperStk     proc    far
                push    bp
                mov     bp, sp
                push    ds
                push    si
                push    ax
                
                lds     si, [bp+6]      ;Get pointer to character.
                mov     al, [si]        ;Fetch the char to convert.
                cmp     al, 'a'         ;See if we've got a
                jb      NotLower        ; lower case character
                cmp     al, 'z'         ; to convert.
                ja      NotLower
                and     al, 5fh         ;Convert lc -> UC.
NotLower:
                mov     [si], al        ;Store result.

                pop     ax
                pop     si
                pop     ds
                pop     bp
                ret     4               ;Remove ptr from stack.
$ToUpperStk     endp
ucrlib          ends
                end

3.11.8.4 ToUpperCS Implementation




                include char.a

                echo    ToUpperCS 

ucrlib          segment para public 'ucrlib'
                assume  cs:ucrlib,ds:nothing




; ToUpperCS-
;
;       Converts lower case ASCII characters to upper case.
;       If the character is not a lower case character, this
;       routine leaves it unchanged.
;
;       A far pointer to the character to convert follows the
;       call in the code stream.  This routine fetches that
;       character, converts it (if necessary), and stores the
;       character back to that location.
;
; Typical Calling Sequence:
;
;       call    $ToUpperCS
;       dword   CharToConvert


                public  $ToUpperCS
$ToUpperCS      proc    far
                push    bp
                mov     bp, sp
                push    ax
                push    ds
                push    si

                lds     si, [bp+2]              ;Get return address.
                lds     si, [si]                ;Get ptr to char.
                mov     al, [si]                ;Get the char.
                add     word ptr [bp+2], 4      ;Skip ptr to char.

                cmp     al, 'a'                 ;See if we've got a
                jb      NotLower                ; lower case character
                cmp     al, 'z'                 ; to convert.
                ja      NotLower
                and     al, 5fh                 ;Convert lc -> UC.
NotLower:
                mov     [si], al                ;Store the character.

                pop     si
                pop     ds
                pop     ax
                pop     bp
                ret
$ToUpperCS      endp
ucrlib          ends
                end