i'm trying to check if a string is palindrome or not. I'm trying to use stack for this i.e., pushing the string on the stack and popping it in another string and then comparing them two. But my function always end up saying 'Not a palindrome' even if it is.
Edit: I took str1 as an input from the user.
str1 BYTE 30 DUP('$')
Following is the function i wrote
checkPalindrome PROC
pop address
mov esi , offset str1
mov ecx, lengthof str1
;push till last index of str1
L1:
cmp BYTE PTR [esi], '$'
je exitLoop
push [esi]
inc esi
loop L1
exitLoop:
mov edi, 0
sub ecx, 30
neg ecx
mov lengthStr, ecx
sub ecx, 1
L2:
pop eax
mov str2[edi], al
inc edi
loop L2
mov str2[edi], '$'
;this displays nothing when i assemble
mov edx, offset str2
call writeString
mov esi, offset str1
mov edi, offset str2
mov ecx, lengthStr
sub ecx, 1
L0:
mov eax, [esi]
mov ebx, [edi]
cmp al, bl
jne notPalind
inc esi
inc edi
loop L0
isPalind:
mov edx, offset isPalindrome
call writeString
jmp quit
notPalind:
mov edx, offset notPalindrome
call writeString
quit:
push address
ret
checkPalindrome ENDP
CodePudding user response:
Irvine32 doesn't do $-terminated strings. That a DOS thingy!
Given your all-$ definition str1 BYTE 30 DUP('$')
, and taking eg. the input of "ABBA", the buffer would look like:
65, 66, 66, 65, 0, 36, 36, 36, 36, 36, ...
Your first loop will push 5 items to the stack before it exits on finding the '$' character.
00000041
00000042
00000042
00000041
00000000 <-- ESP
sub ecx, 30 neg ecx mov lengthStr, ecx sub ecx, 1
And the above calculation will set lengthStr=5
which you found is already 1 more than the actual input and so you subtracted 1. Nonetheless this doesn't help because the stack still contains 5 items and the first item that comes off will be that terminating zero that later messes up comparing for palindrome.
This is how str2 will look like after you have $-terminated it:
0, 65, 66, 66, 34
You wrote about str2 "this displays nothing when i assemble". That's because Irvine32 only sees an empty string. A string that starts with a 0.
And checking for palindrome will fail because this is how both strings look like in the end (the parts that you compare):
str1 65, 66, 66, 65
str2 0, 65, 66, 66
Solution
Change cmp BYTE PTR [esi], '$'
into cmp byte ptr [esi], 0
Remove sub ecx, 1
Change mov str2[edi], '$'
into mov str2[edi], 0
Remove sub ecx, 1