;==========================================================
; File:    Length.asm
; Author:  Bary W Pollack
; Date:    Oct. 23, 2009
; Course:  GSP130
; Purpose: Determine the length of a string entered at
;          the keyboard. Stop on zero-length string. 
;          Show how an array of characters works.
;==========================================================
; GET_STRING - procedure to get a null terminated string from a user, 
;              the received string is written to buffer at DS:DI, 
;              buffer size should be in DX. Procedure stops the input 
;              when 'Enter' is pressed. To use it declare: DEFINE_GET_STRING.

include 'emu8086.inc'

       org  100h ; set location counter to 100h

       jmp  CodeStart

DataStart:

prompt   db  13, 10, 13, 10, "Test string> ", 0
lengthM1 db  "Length of ", 0  
lengthM2 db  " is ", 0
finMsg   db  13, 10, "Fini", 13, 10, 0
newline  db  13, 10, 0
buffer   db  100 dup(0)          ; allocate 100 bytes
lth      dw  ?

CodeStart:
       mov  si, offset prompt    ; request input string
       call print_string

       mov  dx, 100              ; read the string
       mov  di, offset buffer
       call get_string

       mov  si, offset newline   ; issue newline
       call print_string
       
       mov  si, offset buffer    ; find length
       call Length
       cmp  ax, 0
       je   Finish
       mov  lth, ax              ; save the length

       mov  si, offset lengthM1  ; diplay "Length of "
       call print_string
 
       mov  si, offset buffer    ; echo the string
       call print_string
       
       mov  si, offset lengthM2  ; display " is "
       call print_string
       
       mov  ax, lth              ; display the length
       call print_num

       jmp  CodeStart            ; go back for more

Finish:
       mov  si, offset finMsg    ; display "Fini"
       call print_string
       ret                       ; return to caller
                
; Length assumes that the address of the string is in DI
; Length returns the length in AX
Length PROC
       mov  ax, di               ; save address of string
Lup:
       mov  bl, [di]             ; get a byte
       cmp  bl, 0                ; see if it is NUL
       je   Done                 ; if it is, go to Done
       inc  di                   ; increment DI
       jmp  Lup                  ; do it again
Done:
       sub  di, ax               ; calculate length
       mov  ax, di               ; copy result to AX
       ret                       ; return to caller
Length ENDP       

DEFINE_GET_STRING
DEFINE_PRINT_STRING
DEFINE_PRINT_NUM 
DEFINE_PRINT_NUM_UNS
