Home > Software design >  String Reverse in FASM x86 architecture
String Reverse in FASM x86 architecture

Time:09-18

I am making a program that reverses a given string from the user. The problem that has appeared is that the program works well if the string is 5 bytes long but if the string is lower then the result doesn't appear when I execute it. The other problem is that if the string is more than 5 bytes long it reverses only the first five bytes.

Please keep in mind that I am new to assembly and this question may be basic but I would be grateful is someone tells me where the problem is.

Thank you to everyone, have a great day :)

P.S The file "training. inc" is a file that has "print_str, read_line" methods implemented.

 entry start

 include "win32a.inc"
 MAX_USER_STR = 5h
 section '.data' data readable writeable
    enter_string db "Enter a string : ", 0
    newline db 13,10,0
    user_str db MAX_USER_STR dup(?), 0
    

 section ".text" code readable executable
 start:
        mov esi, enter_string
        call print_str
        mov edi, user_str
        call read_line
        call str_len
        mov edx, MAX_USER_STR
        mov ebx, 0
        mov ecx, 0
        mov esi, user_str
        call print_str
        mov esi, newline
        call print_str
        mov esi, user_str
        for_loop : 
            push eax
            mov al, byte[esi]
            inc esi
            inc ebx
            call print_eax
            cmp edx, ebx
            jb clear_register
            jmp for_loop    
        
        for_loop2 :
            call print_eax  
            mov byte[esi], al
            inc esi
            inc ecx
            pop eax
            cmp ecx, edx
            ja break_loop
            jmp for_loop2
            
        break_loop:
            ;mov edi, 0
            mov esi, user_str
            call print_str
            push 0
            call [ExitProcess]
        
        clear_register : 
            mov esi, user_str
            jmp for_loop2
        
        str_len : 
            push ecx
            sub ecx, ecx
            mov ecx, -1
            sub al, al
            cld
            repne scasb
            neg ecx
            sub ecx, 1
            mov eax, ecx
            pop ecx
            ret
    
  include 'training.inc'

CodePudding user response:

MAX_USER_STR = 5h

The name MAX_ already says it, but a buffer is to be defined according to the worst case scenario. If you want to be able to deal with strings that could be longer than 5 characters, then raise this value.

MAX_USER_STR = 256   ; A decent buffer

... if the string is lower then the result doesn't appear when I execute it. The other problem is that if the string is more than 5 bytes long it reverses only the first five bytes.

That's because your code does not actually use the length of the string but rather the size of the smaller buffer. I hope you see that this should never happen, overflowing the buffer. Your code didn't complain too much since this buffer was the last item in the data section.
Your loops could use the true length if you write:

call str_len   ; -> EAX
mov  edx, eax

 for_loop : 
      push eax
      mov al, byte[esi]

If it's characters that you want to push, then I would expect the push eax to follow the load from the string!
Note that in a string-reversal, you never want to move the string terminator(s) to the front of the string.

This is your basic string reversal via the stack:

    mov   ecx, edx       ; EDX has StrLen
    mov   esi, user_str
loop1:
    movzx eax, byte [esi]
    inc   esi
    push  eax
    dec   ecx
    jnz   loop1

    mov   esi, user_str
loop2:
    pop   eax
    mov   [esi], al
    inc   esi
    dec   edx
    jnz   loop2
  • Related