-3

I'm stuck on how to check for a palindrome using MASM.

#include <iostream>
#include <cstring>
#include<string>
#include <algorithm>
using namespace std;

extern "C"
char test(char*, int);


int main()
{
char arr[] = {NULL};


cout << "Enter a string: " << endl;
cin >> arr;



int name = strlen(arr);
test(arr, name);
if (name == 1)
{
    cout << "It is a palindrome! " << endl;

}
else
    cout << "Not a palindrome. " << endl;

return 0;
  }

I asked the user for a string and insert it to an array. I send it to the assembly file and it would return a '1' if its true or '0' if false.

.686
.model flat

.code


_test PROC ;named _test because C automatically prepends an underscode, it is needed to interoperate
push ebp
mov ebp,esp ;stack pointer to ebp

mov eax,[ebp+8]
mov ecx,[ebp+12]
mov ebp,0
mov edi,0
mov edx,0



loopMe: 
cmp ebp,ecx
je True

mov al,[eax+edi]
mov bl,[edx+esi]
cmp al,bl   ;compare 
jne false   ;if not equal then jump to false
inc edi     
dec esi
jmp loopMe

True:
mov eax,1
jmp allDone

False:
mov eax,0
jmp allDone


allDone:    
pop ebp
ret
_test ENDP

END 

when I enter a string it seems to always return 0. I checked the debugger and it would always jump to the False label even though the values are equal. Any help is appreciated.

  • 2
    _`cin >> arr;`_ Is undefined behavior. – πάντα ῥεῖ Dec 01 '16 at 03:20
  • Why not write the code fully in C++, and then use something like [this](https://gcc.godbolt.org/) to determine what the assembly code will look like? You know the generated assembly would be correct, since the C++ program would be correct. Then if necessary, adjust the assembly code produced. – PaulMcKenzie Dec 01 '16 at 03:26

2 Answers2

0

You are in C++ use string.

replace

char arr[] = {NULL}; // by the way NULL here has no sence.

by

std::string arr;

And use method of string to do what you want:

Stargateur
  • 24,473
  • 8
  • 65
  • 91
-1

so I ended up changing the code a bit and got it to work.

int main()
{
char arr[32] = {NULL};


cout << "Enter a string: " << endl;
cin >> arr;



int name = strlen(arr);
int palindrome= test(arr, name);

if (palindrome )
{
    cout << "It is a palindrome! " << endl;

}
else
    cout << "Not a palindrome. " << endl;

return 0;
}

then for the asm file

.686
.model flat

.code


_test PROC ;named _test because C automatically prepends an underscode, it   is needed to interoperate
push ebp
mov ebp,esp ;stack pointer to ebp

mov ebx,[ebp+8]
mov ecx,[ebp+12]
mov edx,ebx
add edx,ecx
dec edx




loopMe: 
cmp ebx,edx
jge True

mov ch,[ebx]
mov cl,[edx]
cmp ch,cl   ;compare 
jne false   ;if not equal then jump to false
inc ebx     
dec edx
jmp loopMe

True:
mov eax,1
jmp allDone

False:
mov eax,0
jmp allDone


allDone:    
pop ebp
ret
_test ENDP

 END 

My only problem now is if I input Mom instead of mom it would say that its not a palindrome. I just need to figure out how to ignore cases in assembly.

  • Convert all alphabetic characters to lowercase. If they're in the uppercase range, OR with `0x20`. – Peter Cordes Dec 01 '16 at 04:47
  • Thanks for the help. – Emanuel Carmona Dec 01 '16 at 04:55
  • or ch,32 and or cl,32 did it for me. – Emanuel Carmona Dec 01 '16 at 04:56
  • note that that makes `@` into `\`` (back-quote), and `[` into `{`, and so on, for non alphabetic characters. (http://www.asciitable.com/). This is why I suggested doing it conditionally, in case you care about non-alphabetic characters. (Interestingly, the digits 0-9 and `' '` (space) all have that bit set already, so they're unmodified. So OR with 0x20 works in more non-alphabetic cases than AND with `~0x20`) – Peter Cordes Dec 01 '16 at 06:08