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
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.