I came across a code where the assembly program can check if the string is a palindrome, except the string was hardcoded. I wanted to practice and modify the code to do the same thing except that the program will take a user's input for the string.
I got the main code from this post: Palindrome using NASM: answer by user1157391
Below is the code I came up with, except I keep getting the errors: line 39: invalid operand type and line 41: division operator may only be applied to scalar values
section .data
msg db "Please provide a word: ",0
len equ $ - msg
msg1 db "The word is a palindrome",0
len1 equ $ - msg1
msg2 db "The word is not pallindrome",0
len2 equ $ - msg2
nline db 0xA
nlen equ $ - nline
segment .bss
input resb 10 ; reserve 10 bytes for input
length resb 10
section .text
global _start
_start:
mov edx, len ; number of bytes to write
mov ecx, msg ; ECX will point to the address of the string msg
mov ebx, 1 ; write to the STDOUT file
mov eax, 4 ; invoke SYS_WRITE (kernel opcode 4)
int 0x80
mov edx, 11 ; number of bytes to read
mov ecx, input ; reserve space for the user's input
mov ebx, 0 ; write to the STDIN file
mov eax, 3 ; invoke SYS_READ (kernel opcode 3)
int 0x80
mov eax, input
call strlen
mov [length], eax
mov ebx, input ; start of word
mov eax, (input + length - 1) ; end of word
mov ecx, (length / 2) ; check will run for half of the word
check:
mov dl, [ebx] ; compare first and last letters
cmp [eax], dl
jne failure
inc ebx
dec eax
loop check
;; success
mov edx, len1
mov ecx, msg1
mov ebx, 1
mov eax, 4
int 0x80
add esp,4
jmp done
failure:
mov edx, len2
mov ecx, msg2
mov ebx, 1
mov eax, 4
int 0x80
add esp,4
done:
ret
strlen:
push ebx
mov ebx, eax
nextchar:
cmp byte [eax], 0
jz finished
inc eax
jmp nextchar
finished:
sub eax, ebx
pop ebx
ret
I've only started studying assembly language so it would be really nice if someone helps me out here. I've been losing my sanity for the whole day over this. Thank you!
UPDATE: Thank you to all of the answers and comments and @/Peter Cordes for the helpful suggestions. Because of those, I came up with the following (completely different approach) code. I also watched another video on how to check strings that has varying capitalization.
This doesn't work (for me) unless I input exactly 10 characters. However, when I hardcode the input, it works even with less than 10 characters.
msg db "Please provide a word: ",0
len equ $ - msg
palindrome db 'The word is a palindrome'
lenP equ $ - palindrome
notPalindrome db 'The word is not a palindrome'
lenNP equ $ - notPalindrome
segment .bss
input resb 10 ; reserve 10 bytes for input
length equ $ - input
section .text
global _start
_start:
mov edx, len ; number of bytes to write
mov ecx, msg ; ECX will point to the address of the string msg
mov ebx, 1 ; write to the STDOUT file
mov eax, 4 ; invoke SYS_WRITE (kernel opcode 4)
int 0x80
mov edx, 10 ; number of bytes to read
mov ecx, input ; reserve space for the user's input
mov ebx, 0 ; write to the STDIN file
mov eax, 3 ; invoke SYS_READ (kernel opcode 3)
int 0x80 ; start of word
add eax, ecx
dec eax
capitalizer:
cmp byte[ecx], 0
je finished
mov bl, byte[ecx] ;start
mov dl, byte[eax] ;end
cmp bl, 90
jle uppercase ;start is uppercase
sub bl, 32
uppercase:
cmp dl, 90
jle check ;end is uppercase
sub dl, 32
check:
cmp dl, bl
jne fail
inc ecx
dec eax
jmp capitalizer
finished:
mov edx, lenP
mov ecx, palindrome
mov ebx, 1
mov eax, 4
int 0x80
jmp exit
fail:
mov edx, lenNP
mov ecx, notPalindrome
mov ebx, 1
mov eax, 4
int 0x80
exit:
mov eax, 1
mov ebx, 0
int 0x80```