Reputation:
I am trying to solve a question that asks a user to input a username. If that username is a palindrome (i.e., the reverse of the string is same as the original string), then it should print "Retype Username" and get input again. If not, it should print 'OK' and terminate. I have written the following code and have been unable to find fallacies in it. It would be great help if someone could point out my mistake. Thanks in advance.
data segment
str0 db 'Enter username: $'
str db '$'
str1 db 'OK$'
str2 db 'Retype Username$'
data ends
code segment
assume cs:code, ds:data
start: mov bx, data
mov ds, bx
mov es, bx
mov bl, '$' ;terminating point of all strings
mov cl, 00h ;counter value in case of loop use
lea dx, str0 ;to display 'Enter username: '
mov ah, 09h
int 21h
lab0: lea si, str ;to read the username
lab: mov ah, 01h
int 21h
mov [si], al ;the input is read character by character. To avoid termination after just one character, the characters are read till the end is determined
inc si
inc cl
cmp al, bl
jne lab
lea si, str ;loading string for front end
dec si
lea di, str ;loading string for rear end
dec di
lab1: inc di
cmp [di], bl ;comparing to find '$'
jne lab1
lab2: inc si
mov bh, [si]
dec di
cmp [di], bh ;comparing letters from front and rear end
jne lab3 ;if not equal then not a palindrome
loop lab2
lea dx, str2 ;to display 'Retype username' when username is a palindrome
mov ah, 09h
int 21h
jmp lab0
lab3: lea dx, str1 ;to display 'OK' when the username is not a palindrome
mov ah, 09h
int 21h
mov ah, 4ch
int 21h
code ends
end start
Upvotes: 0
Views: 7312
Reputation: 39166
str db '$'
This is supposed to be the place where you store the inputted username.
What this db
directive did is reserve you a single byte of memory. Certainly not enough to store a complete name. What then happens in your program is that the input routine (that is almost well written) starts overwriting the rest of the program data and worse the program code.
A decent buffer for storing your input is defined by:
str db 255 dup (0)
To end the input, you normally push Enter. Logically this means that your code needs to check for it. The value that DOS will give you for it is 13, so definitely not the '$' that you used!
mov bl, '$' ;terminating point of all strings
mov cx, 0 ;counter value in case of loop use
lab0:
lea di, str ;to read the username
lab:
mov ah, 01h
int 21h
cmp al, 13 ;13 is code for carriage return
je OK
mov [di], al ;the input is read character by character.
inc di
inc cx
jmp lab
OK:
mov [di], bl
lea si, str ;loading string for front end dec si lea di, str ;loading string for rear end dec di lab1: inc di cmp [di], bl ;comparing to find '$' jne lab1
Why would you need to search for the end of your string? At the conclusion of the input, the indexregister DI
will already conveniently point at it.
lea si, str ; -> SI=first character
dec di ; -> DI=last character
1st tip : Because you used loop
, you should have cleared CX
, not just CL
!
2nd tip : Don't start comparing characters if the counter in CX
is zero!
3rd tip : You only need to do CX / 2
iterations!
Golden tip : You don't need any counter at all. End (or don't start) the loop when the rear index is below or equal to the front index!
Upvotes: 2