assemblymasmpalindromeirvine32

Palindrome Checking in MASM using IRVINE32.inc


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


Solution

  • 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