An Assembly Language Program

Prog_Data    SEGMENT
Prompt       DB     16,"Input string -->"
Str          DB     80 DUP(32)
VideoSeg     EQU     0B800H
Prog_Data    ENDS


Prog_Code    SEGMENT 
             ASSUME CS:Prog_Code, DS:Prog_Data, SS:Prog_Stack

Main_Prog    PROC
             mov AX, Prog_Data
             mov DS, AX         ; load the offset of the Data segment

             mov DH, 10         ; cursor positioning (Y=10)
             mov DL, 15         ; cursor positioning (X=15)
             mov AH, 30         ; character attributes

             call ClrScr        ; clear screen

             mov SI, offset Prompt ; load offset of Prompt in SI
             call WriteLn       ; output prompt on the screen

             mov SI, offset Str
             call ReadLn        ; read string from the keyboard

             mov DH, 20
             mov DL, 15         ; new cursor ccordinates
             mov SI, offset Str ; load offset of input string to SI
             call WriteLn       ; output string
         
             mov AX, 4C00H      ; return to DOS
             int 21H
Main_Prog    ENDP


BinOut    PROC           ; outputs BX on the screen in binary form
          push BX        ; save the registers
          push CX

          mov CX, 16     ; word length
Nextbit:  shl BX, 1     
          jc one         
          mov AL, '0'    ; bit=0
          call PutChar   ; output it on the screen
          jmp weiter  
One:      mov AL, '1'    ; bit=1
          call PutChar   ; output it on the screen
Weiter:   inc DL         ; new cursor position
          loop nextbit   ; main loop over all bits

          pop CX         ; restore the registers
          pop BX
          ret
BinOut    ENDP


ReadLn    PROC           ; reads a string from the keyboard --> [SI]
          push DI        ; save registers
          push BX
          push CX
          mov DI, SI
          mov BX, 0      ; set string length =0

Nextchar: mov CH, AH     ; AH is used in GetChar
          call GetChar   ; get a char from the keyboard
          mov AH, CH     ; restore AH (color settings)

          cmp AL, 13     ; end of string ?
          je Done        ; YES

Proceed:  call PutChar   ; echo char on the screen
          inc DL         ; new cursor position
          inc SI         ; address of the new character
          mov [SI], AL   ; save the string character
          inc BX         ; increase the string length
          jmp Nextchar

Done:     mov [DI],BL    ; set the string length
          pop CX         ; restore the registers
          pop BX
          pop DI
          ret              
ReadLn    ENDP


GetChar   PROC       ; returns the ASCII code in AL
label1:   mov AH, 0  ; BIOS read key procedure
          int 16H
          cmp AL, 0  ; special key pressed ?
          je  label1 ; yes, wait for another key
          ret
GetChar   ENDP


WriteLn   PROC               ; writes a line on the screen starting with the
                             ; currect cursor position (X,Y)=(DL,DH)
                             ; SI points to the string 
          push AX
          push CX
          push SI

          mov CL, [SI]       ; CL := Length(Str)
          inc SI

outchar:  cmp CL, 0
          je  outdone
          MOV AL, [SI]       ; AL := next character
          call PutChar       ; output char to the screen
          inc SI             ; offset of the next character
          inc DL             ; new column
          dec CL
          jmp outchar

outdone:  pop SI
          pop CX
          pop AX
          ret
WriteLn   ENDP


PutChar   PROC    ; writes a character to VRAM. AL=char, AH=attribute
                  ; DH/DL = row/column (0-24, 0-79)

          push DI ; save the registers
          push ES
          push AX

          mov AX, VideoSeg ; B800H : video buffer segment
          mov ES, AX

          xor AX, AX ; clear AX
          mov AL, DH ; load the row number in AX
          shl AX, 1  ; multiply AX by 2^7=128
          shl AX, 1
          shl AX, 1
          shl AX, 1
          shl AX, 1
          shl AX, 1
          shl AX, 1
          mov DI, AX ; store the result in DI

          xor AX, AX ; clear AX
          mov AL, DH ; load the row number in AX
          shl AX, 1  ; multiply AX by 2^5=32
          shl AX, 1
          shl AX, 1
          shl AX, 1
          shl AX, 1
          add DI, AX ; DI:=DH*(128+32)=DH*160

          xor AX, AX ; clear AX
          mov AL, DL ; load the column number in AX
          shl AL, 1  ; multiply the column by 2
          add DI, AX ; DI:=offset of the screen byte

          pop AX     ; restore AX
          mov ES:[DI], AX ; store char/attribute

          pop ES     ; restore the registers
          pop DI

          ret        ; return to the calling program
PutChar   endp       ; end of the procedure


ClrScr    PROC       ; fill the screen with the BG color
          push CX
          push DI
          push ES
          mov DI, VideoSeg
          mov ES, DI
          mov AL, ' '
          mov DI, 0
          mov CX, 2000
          cld
          rep stosw
          pop ES
          pop DI
          pop CX
          ret
ClrScr    ENDP

Prog_Code ENDS

Prog_Stack   SEGMENT STACK
             DB   64 DUP(0) 
Prog_Stack   ENDS


END