The Art of
ASSEMBLY LANGUAGE PROGRAMMING

Chapter Seven (Part 1)

Table of Content

Chapter Eight 

CHAPTER SEVEN:
THE UCR STANDARD LIBRARY (Part 2)
7.2 - Sample Programs
7.2.1 - Stripped SHELL.ASM File
7.2.2 - Numeric I/O

7.2 Sample Programs

The following programs demonstrate some common operations that use the Standard Library.

7.2.1 Stripped SHELL.ASM File

; Sample Starting SHELL.ASM file
;
; Randall Hyde
; Version 1.0
; 2/6/96
;
; This file shows what the SHELL.ASM file looks like without
; the superfluous comments that explain where to place objects
; in the source file.  Your programs should likewise begin
; with a stripped version of the SHELL.ASM file.  After all,
; the comments in the original SHELL.ASM file are four *your*
; consumption, not to be read by someone who sees the program
; you wind up writing.

                .xlist
                include         stdlib.a
                includelib      stdlib.lib
                .list

dseg            segment para public 'data'

dseg            ends

cseg            segment para public 'code'
                assume  cs:cseg, ds:dseg

Main            proc
                mov     ax, dseg
                mov     ds, ax
                mov     es, ax
                meminit





Quit:           ExitPgm
Main            endp

cseg            ends

sseg            segment para stack 'stack'
stk             db      1024 dup ("stack   ")
sseg            ends

zzzzzzseg       segment para public 'zzzzzz'
LastBytes       db      16 dup (?)
zzzzzzseg       ends
                end     Main
7.2.2 Numeric I/O
; Pgm7_2.asm - Numeric I/O.
;
; Randall Hyde
; 2/6/96
;
; The standard library routines do not provide simple to use numeric input
; routines.  This code demonstrates how to read decimal and hexadecimal values 
; from the user using the Getsm, ATOI, ATOU, ATOH, IsDigit, and IsXDigit routines.


                .xlist
                include                 stdlib.a
                includelib              stdlib.lib
                .list

dseg            segment para public 'data'

inputLine       byte    128 dup (0)

SignedInteger   sword   ?
UnsignedInt     word    ?
HexValue        word    ?

dseg            ends

cseg            segment para public 'code'
                assume  cs:cseg, ds:dseg

Main            proc
                mov     ax, dseg
                mov     ds, ax
                mov     es, ax
                meminit


; Read a signed integer value from the user.

InputInteger:   print
                byte    "Input a signed integer value: ",0

                lesi    inputLine               ;Point es:di at inputLine buffer
                gets                            ;Read a line of text from the user.

                mov     bx, -1
SkipSpcs1:      inc     bx
                cmp     inputLine[bx], ' '      ;Skip over any spaces.
                je      SkipSpcs1

                cmp     inputLine[bx], '-'      ;See if it's got a minus sign
                jne     NoSign
                inc     bx                      ;Skip if a negative number

NoSign:         dec     bx                      ;Back up one place.
TestDigs:       inc     bx                      ;Move on to next char
                mov     al, inputLine[bx]
                IsDigit                         ;See if it's a decimal digit.
                je      TestDigs                ;Repeat process if it is.

                cmp     inputLine[bx], ' '      ;See if we end with a 
                je      GoodDec                 ; reasonable character.
                cmp     inputLine[bx], ','
                je      GoodDec
                cmp     inputLine[bx], 0        ;Input line ends with a zero.
                je      GoodDec
                printf
                byte    "'%s' is an illegal signed integer.  "
                byte    "Please reenter.",cr,lf,0
                dword   inputLine
                jmp     InputInteger

; Okay, all the characters are cool, let's do the conversion here.  Note that 
; ES:DI is still pointing at inputLine.

GoodDec:        ATOI                            ;Do the conversion
                mov     SignedInteger, ax       ;Save the value away.

; Read an unsigned integer value from the user.

InputUnsigned:  print
                byte    "Input an unsigned integer value: ",0

                lesi    inputLine       ;Point es:di at inputLine buffer
                gets                    ;Read a line of text from the user.

; Note the sneakiness in the following code.  It starts with an index of -2
; and then increments it by one.  When accessing data in this loop it compares
; against locatoin inputLine[bx+1] which effectively starts bx at zero.  In the
; "TestUnsigned" loop below, this code increments bx again so that bx then 
; contains the index into the string when the action is occuring.

                mov     bx, -2
SkipSpcs2:      inc     bx
                cmp     inputLine[bx+1], ' '    ;Skip over any spaces.
                je      SkipSpcs2

TestUnsigned:   inc     bx                      ;Move on to next char
                mov     al, inputLine[bx]
                IsDigit                         ;See if it's a decimal digit.
                je      TestUnsigned            ;Repeat process if it is.

                cmp     inputLine[bx], ' '      ;See if we end with a 
                je      GoodUnSigned            ; reasonable character.
                cmp     inputLine[bx], ','
                je      GoodUnsigned
                cmp     inputLine[bx], 0        ;Input line ends with a zero.
                je      GoodUnsigned
                printf
                byte    "'%s' is an illegal unsigned integer.  "
                byte    "Please reenter.",cr,lf,0
                dword   inputLine
                jmp     InputUnsigned

; Okay, all the characters are cool, let's do the conversion here.  Note that 
; ES:DI is still pointing at inputLine.

GoodUnsigned:   ATOU                            ;Do the conversion
                mov     UnsignedInt, ax         ;Save the value away.


; Read a hexadecimal value from the user.

InputHex:       print
                byte    "Input a hexadecimal value: ",0

                lesi    inputLine       ;Point es:di at inputLine buffer
                gets                    ;Read a line of text from the user.

; The following code uses the same sneaky trick as the code above.

                mov     bx, -2
SkipSpcs3:              inc     bx
                cmp     inputLine[bx+1], ' '    ;Skip over any spaces.
                je      SkipSpcs3

TestHex:        inc     bx                      ;Move on to next char
                mov     al, inputLine[bx]
                IsXDigit                        ;See if it's a hex digit.
                je      TestHex                 ;Repeat process if it is.

                cmp     inputLine[bx], ' '      ;See if we end with a 
                je      GoodHex                 ; reasonable character.
                cmp     inputLine[bx], ','
                je      GoodHex
                cmp     inputLine[bx], 0        ;Input line ends with a zero.
                je      GoodHex
                printf
                byte    "'%s' is an illegal hexadecimal value.  "
                byte    "Please reenter.",cr,lf,0
                dword   inputLine
                jmp     InputHex

; Okay, all the characters are cool, let's do the conversion here.  Note that 
; ES:DI is still pointing at inputLine.

GoodHex:        ATOH                            ;Do the conversion
                mov     HexValue, ax            ;Save the value away.


; Display the results:

                printf
                byte    "Values input:",cr,lf
                byte    "Signed:   %4d",cr,lf
                byte    "Unsigned: %4d",cr,lf
                byte    "Hex:      %4x",cr,lf,0
                dword   SignedInteger, UnsignedInt, HexValue

Quit:           ExitPgm
Main            endp

cseg            ends

sseg            segment para stack 'stack'
stk             db      1024 dup ("stack   ")
sseg            ends

zzzzzzseg       segment para public 'zzzzzz'
LastBytes       db      16 dup (?)
zzzzzzseg       ends
                end     Main

Chapter Seven (Part 1)

Table of Content

Chapter Eight 

Chapter Seven: The UCR Standard Library (Part 2)
26 SEP 1996