UMBC CMSC 211

CSEE |


Array Applications

Reading a Whole Line from the Keyboard

As you should remember from C, when doing keyboard input, you have to define the area where the input will be stored. That means you might have something like:
    char	CharStr[80];
  
To get the input, you might use something like the function gets(). If you need to know how many characters the user typed in, you call strlen(). Seems simple enough. Now we can do the same type of thing in assembly using the macro: _getStr GetBuf But, we have to define GetStruct as:
MAXCHAR EQU 80 ; seems a reasonable size
; But must fit into a unsigned byte
; (255 max)
GetBuf DB MAXCHAR ; Maximum allowed characters
GetCnt DB ? ; The operating system will tell us how
; many there really were
CharStr DB MAXCHAR DUP (?) ; Put it here
The MAXCHAR includes the carriage return (13). The system will not accept more characters, it will beep at you if you try to exceed the limit!

The value stored in GetCnt will be MAXCHAR - 1, because the last position will be the carriage return!

Suppose I type in "Gary is wonderful!", I will have in memory:

GetBuf: GetCnt: CharSTr::
  80 18 'G' 'a' 'r' 'y' ' ' 'i' 's' ' ' 'w' 'o' 'n' 'd' 'e' 'r' 'f' 'u' 'l' '!' 13  
Unforunately, the _getStr will echo what you type, including the carriage return, but there is no line feed. You must put that in yourself, so you code must include:
_getStr GetStruct
_putCh 10

Now, let's have fun and print that input out backwards.


        .model  small
        .stack  100h
        .data
MAXBUF  EQU     100
GetBuf  db      MAXBUF
GetCnt  db      ?
CharStr db      MAXBUF DUP ( ? )

prompt  db      'Please enter a string: ', 10, 13, '$'
msg1    db      'Using the first method', 10, 13, '$'
msg2    db      'Using the second method', 10, 13, '$'
msg3    db      'Using the third method', 10, 13, '$'
        .code
main    PROC
        include pcmac.inc
        _begin

        _PutStr prompt

; Get the string once

        _GetStr GetBuf
        _PutCh  10

; There are three ways to print out the characters in reverse
; order.

;
; First way!!
;

        _PutStr msg1
        mov     bl, GetCnt
        test    bl, bl
        jz      Done1
        sub     bh, bh

Reverse1:
        _PutCh  [CharStr -1 + bx]
        dec     bx
        jnz     Reverse1

Done1:
        _PutCh  10,13

;
; Second way!!  Question: Could this also be done with the cx register?
;
        
        _PutStr msg2
        mov     bl, GetCnt
        test    bl, bl
        jz      Done2
        sub     bh, bh
        mov     di, OFFSET CharStr-1

Reverse2:
        _PutCh  [bx + di]
        dec     bx
        jnz     Reverse2

Done2:
        _PutCh  10, 13

;
; Third way
;

        _PutStr msg3
        mov     bl, GetCnt
        test    bl, bl
        je      Done3
        sub     bh, bh

Reverse3:
        _PutCh  [CharStr - 1 + bx]
        dec     bx
        jne     Reverse3

Done3:
        _PutCh  10, 13

        _exit
main    ENDP
        END     main

Conversion Tables

There is an underrated instruction xlatthat will allow you to convert one byte to another based on a table lookup, where the table is a series of bytes. This requires the AL register to hold the raw value and the BX register should point to a table in member of the corresponding values. When the instruction has executed, AL holds the new value. A simple-to-understand method of converting a binary value in the range of 0 to 16, would be to have a simple table:


        .model  small

        .stack  100h

        .data
HexDigit   DB       '0123456789ABCDEF'   ;
Mybyte     DB       27h                  ;
                                                   
        .code
main    PROC
        include pcmac.inc
        _begin

        mov      bx, OFFSET HexDigit  ; Point to the table                 
        mov      al, mybyte           ;                                    
        mov      cl, 4                ;                                   
        shr      al, cl               ; do the high bits first             
        xlat                          ; Get the ASCII value for this number
        _PutCh   al                   ;                                    
        mov      al, mybyte           ;                                    
        and      al, 0Fh              ; do the low bits next               
        xlat                          ; Get the ASCII value for this number
        _PutCh   al                   ;                                    

        _PutCh  10, 13

       _exit
main    ENDP
        END     main

Remember that this only works when everything is able to be reduced into a byte-sized values. Actually, there are ways to force other things into byte-sized value, when the value is an index into another array!


UMBC | CSEE |