I'm trying to work out if a string is a palindrome or not in Assembly. Essentially I attempt to copy the bytes backwards from string 'my_string' to 'tmp_str'. Then I attempt to compare both strings use repe and cmpsb.
The problem I'm facing is that the program randomly hangs or throws SIGILL's OR SIGSEV's when setting breakpoints in GDB. The behaviour is truly random, or random enough that I can't the source of the error to a single line. I am incredibly confused and would appreciate some insight in what may be causing these errors. Note, if I set no break points or some others such as line 25, 27, 28, it works fine.
I have checked, and the for loop does iterate the correct number of times, with the right values. The initial strings are also in the format I expect.
Example errors:
Hangs <- if break point is set to line 30
Program received signal SIGILL, Illegal instruction. _start.for_1.end () at 4.asm:32 32          jmp     .for_1.start <- when break point was set to line 28 (bug isn't reproducible but it did happen)
Program received signal SIGSEGV, Segmentation fault. 0x0000000000400feb in ?? () <- when break point was set to line 31
;; Write an assembly program to determine if a string stored in memory is a palindrome
;; (A palindrome is a string which is the same after being reversed, like "refer")
;; Use at least one repeat instruction
                segment .data
my_string       db              "bob", 0
                segment .bss
tmp_str         resb            4
                segment .text
                global _start
_start:
                ;/* Copy initial string BACKWARDS */
                xor             rcx, rcx                        ; have to use manual for loop
.for_1.start:
                cmp             ecx, 4
                je              .for_1.end
                mov             al, byte [my_string+ecx]        ; get character from original string from i'th place
                mov             rbx, tmp_str+2                  ; go to end of tmp_str (writing my_string to tmp_str backwards)
                sub             rbx, rcx                        ; we can't minus from address expression thingy, so just deduct from register stored above
                mov             [rbx], byte al                  ; copy byte in ebx into mem address stored atueax
                inc             ecx                             ; increment counter     
                jmp             .for_1.start                    ; unconditional start to stop (for loops check and do conditional jumps at top)
.for_1.end:
                ;/* Compare strings */
                mov             rsi, my_string                  ; now we want to compare strings (remember, pointer in reg moves in movsb)
                mov             rdi, tmp_str                    ; rdi, set to tmp_str address 
                mov             rcx, 2                          ; since rcx was modified by rep, we need to reset that though
                repe            cmpsb                           ; compare strings whilst each val (byte) is equal
                                                                ; now, if rcx is NOT 0, the bytes do not match and is not a palindrome!
                ;/* EOP */
                mov             eax, 1
                xor             ebx, ebx
                int 0x80
If anybody could offer some advice I would be greatly appreciative.
Compile commands: yasm -f elf64 -g dwarf2 <file>.asm ; ld <file>.o -o <file>
 
     
    