user8746929
user8746929

Reputation:

check whether string is a palindrome - assembly language

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

Answers (1)

Sep Roland
Sep Roland

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

Related Questions