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).
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.
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.
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.
The following versions of IsAlNum are available:
| Name | Plain | CS | TOS | Stk | X | CSi |
|---|---|---|---|---|---|---|
| IsAlNum | X | X | X | X | - | - |
The IsAlNum macro allows the following operands:
| Name | byteVar | Num const | [word Var] | [dword Var] | String Const | |
|---|---|---|---|---|---|---|
| IsAlNum | X | X | X | X | X | - |
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
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.
The following versions of IsAlNum are available:
| Name | Plain | CS | TOS | Stk | X | CSi |
|---|---|---|---|---|---|---|
| IsAlpha | X | X | X | X | - | - |
The IsAlNum macro allows the following operands:
| Name | byteVar | Num const | [word Var] | [dword Var] | String Const | |
|---|---|---|---|---|---|---|
| IsAlpha | X | X | X | X | X | - |
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
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.
The following versions of IsDigit are available:
| Name | Plain | CS | TOS | Stk | X | CSi |
|---|---|---|---|---|---|---|
| IsDigit | X | X | X | X | - | - |
The IsDigit macro allows the following operands:
| Name | byteVar | Num const | [word Var] | [dword Var] | String Const | |
|---|---|---|---|---|---|---|
| IsDigit | X | X | X | X | X | - |
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
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.
The following versions of IsLower are available:
| Name | Plain | CS | TOS | Stk | X | CSi |
|---|---|---|---|---|---|---|
| IsLower | X | X | X | X | - | - |
The IsLower macro allows the following operands:
| Name | byteVar | Num const | [word Var] | [dword Var] | String Const | |
|---|---|---|---|---|---|---|
| IsLower | X | X | X | X | X | - |
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
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.
IsUpper:
The following versions of IsUpper are available:
| Name | Plain | CS | TOS | Stk | X | CSi |
|---|---|---|---|---|---|---|
| IsUpper | X | X | X | X | - | - |
The IsUpper macro allows the following operands:
| Name | byteVar | Num const | [word Var] | [dword Var] | String Const | |
|---|---|---|---|---|---|---|
| IsUpper | X | X | X | X | X | - |
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
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.
The following versions of IsXDigit are available:
| Name | Plain | CS | TOS | Stk | X | CSi |
|---|---|---|---|---|---|---|
| IsXDigit | X | X | X | X | - | - |
The IsXDigit macro allows the following operands:
| Name | byteVar | Num const | [word Var] | [dword Var] | String Const | |
|---|---|---|---|---|---|---|
| IsXDigit | X | X | X | X | X | - |
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
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.
The following versions of ToLower are available:
| Name | Plain | CS | TOS | Stk | X | CSi |
|---|---|---|---|---|---|---|
| ToLower | X | X | X | X | - | - |
The ToLower macro allows the following operands:
| Name | byteVar | Num const | [word Var] | [dword Var] | String Const | |
|---|---|---|---|---|---|---|
| ToLower | X | X | X | X | X | - |
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
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.
The following versions of ToUpper are available:
| Name | Plain | CS | TOS | Stk | X | CSi |
|---|---|---|---|---|---|---|
| ToUpper | X | X | X | X | - | - |
The ToUpper macro allows the following operands:
| Name | byteVar | Num const | [word Var] | [dword Var] | String Const | |
|---|---|---|---|---|---|---|
| ToUpper | X | X | X | X | X | - |
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
The following sections provide the implementations for the various CHAR routines.
The following sections provide the source code for the four different "IsAlNum" routines (as of 11/96).
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
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
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
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
The following sections provide the code for the IsAlpha routines as of 11/96.
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
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
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
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
The following sections provide the source code for the IsDigit implementations as of 11/96.
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
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
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
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
The following sections provide the implementations of the IsLower routines as of 11/96.
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
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
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
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
The following sections provide the source for for the IsUpper routines as of 11/96.
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
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
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
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
The following sections provide the implementations for the IsXDigit routines as of 11/96.
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
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
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
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
The following sections provide the implementations for the ToLower routines as o 11/96.
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
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
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
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
The following sections provide the implementation of the ToUpper routines as of 11/96.
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
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
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
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