3

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
4
  • 1
    In two places you have 'S' where you should have '$' when you try to print out myBstr at the end you use the wrong interupt number. You use 0ah and it should be 09h for output. As well the string really starts at myBstr+2, not myBstr since the first 2 bytes are for the input interrupt call. You should skip over the two bytes when outputting. At the bottom change lea dx, myBStr to lea dx, [myBStr+2] Commented Oct 25, 2017 at 5:05
  • You may wish to change myBStr db 20, 21 dup(?) ,'S' to myBStr db 20, 22 dup('$') Commented Oct 25, 2017 at 5:08
  • 1
    Not related to your question, but you should load sp when you load ss. In the code as written, sp still contains an offset into the previous stack segment that is no longer valid. Commented Oct 25, 2017 at 5:26
  • @MichaelPetch Thank you so much! That was quick and it really helped! Just a minor question though, how can I keep the string printed out since after I hit enter? As of now, (after changing what you said) it only prints this: Enter a string (max 20 char.) The string you entered is: 012345678901234567890 Commented Oct 25, 2017 at 8:06

1 Answer 1

2

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.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.