How to prompt user for string and display it again in Assembly Language Programming

Bts is life picture Bts is life · Oct 25, 2017 · Viewed 11k times · Source

I'm having trouble with my assembly language code.

We were asked to prompt user for input string and we're supposed to display it again or echo it to the command line. We need to assume that it's only up to 20 characters (in the string)

This is the sample output:

Enter a string (max 20 char.)

012345678901234567890

The string you entered is:

012345678901234567890

When I run my code in DOSBOX, I enter: 0123456789 After hitting enter it shows me a bunch of characters and symbols that look weird...

Here is my code:

.186 

data    segment                         

message1 db "Enter a string (max 20 char.): " ,13, 10, '$'

message2 db "The string you entered is: " , 13, 10, 'S'

myBStr db 20, 21 dup(?) ,'S' 

data    ends
stack1  segment stack       
    db  100 dup(?)                  ; This is the stack of 100 bytes
stack1  ends


code    segment
    assume  cs:code, ds:data, ss:stack1

start: 
    mov ax, data                    
    mov ds, ax                      
    mov ax, stack1                  
    mov ss, ax      


    lea dx, message1                    ;load message to dx
    mov ah, 9h                          ;show this message
    int 21h

    mov ah, 0Ah                         
    lea dx, myBStr                      ;Load address of string
    int 21h

    mov ah, 9h                          ; show message of entered string
    int 21h

    lea dx, message2                    ;load second message to dx
    mov ah, 9h                          ;show this message
    int 21h

    mov ah, 0Ah                         
    lea dx, myBStr                      ;Load address of string
    int 21h 

    mov ah, 4ch                     ;Set up code to specify return to dos
    int 21h                     
code    ends
end     start

Answer

Sep Roland picture Sep Roland · Oct 29, 2017

Enter a string (max 20 char.)

012345678901234567890

Weird that when asking for an input of at most 20 characters you could receive 21 characters!


 1 mov ah, 0Ah                         
 2 lea dx, myBStr                      ;Load address of string
 3 int 21h
 4 mov ah, 9h                          ; show message of entered string
 5 int 21h
 6 lea dx, message2                    ;load second message to dx
 7 mov ah, 9h                          ;show this message
 8 int 21h
 9 mov ah, 0Ah                         
10 lea dx, myBStr                      ;Load address of string
11 int 21h 

Lines 4 and 5 are out of place. You need this code after displaying the 2nd message.
Lines 9, 10, and 11 currently re-input the string, when in fact you want to display it.

lea dx, myBStr       ;Load address of INPUT STRUCTURE
mov ah, 0Ah          ;Buffered input
int 21h
lea dx, message2     ;Load second message
mov ah, 09h          ;Show this message
int 21h
lea dx, myBStr + 2   ;Load address of string
mov ah, 09h          ;Show entered string
int 21h

The string starts at the 3rd byte of the input structure. That's why you need to write lea dx, myBStr + 2.


message2 db "The string you entered is: " , 13, 10, 'S'

The 'S' at the end serves no real purpose. Let's agree it's a typo and write:

message2 db "The string you entered is: " , 13, 10, '$'

Since you want to be able to get a 20-character string, you'll need to setup the input structure for the DOS.BufferedInput function 0Ah differently:

myBStr   db 21, 0, 21 dup(0) 

The 1st byte (21) tells DOS that the storage space (21 dup(0)) has room for 20 characters and 1 mandatory carriage return CR.
The 2nd byte (0) will be set by DOS with the number of characters that were actually entered (not including the CR). You use this byte to properly '$'-terminate the string before you output it.

mov bl, [myBStr + 1]                 ;Get length of string
mov bh, 0
mov byte ptr [myBStr + 2 + bx], '$'  ;Replace CR with '$'
lea dx, myBStr + 2                   ;Load address of string
mov ah, 09h                          ;Show entered string
int 21h

As prl noted, if you're going to set the SS segment register, then also set the SP register:

mov ax, stack1                  
mov ss, ax
mov sp, 100

Normally however you would not need to write these lines at all.


From comments

Just a minor question though, how can I keep the string printed out

Simply wait for the user to press any key before exiting to DOS.

mov ah, 07h        ;DOS.InputCharacterWithoutEcho
int 21h
mov ax, 4C00h      ;DOS.TerminateWithExitcode
int 21h                

Do note that it would be better to actually specify an exitcode with DOS function 4Ch. The zero in AL signals a normal program termination.