Search code examples
assemblytasm

assembly reverse a string


The string is read until 1 is pressed, and the 1 will be on the last position of the string. I don't know why my output is off, for example the input is: asd1 and the output is: $1111. Anyway, here is my code

data segment
msg db 0dh,0ah,"Your string: $"
rev db 0dh,0ah,"Reverted: $"
s1 db 20 dup('$')
s2 db 20 dup('$')
data ends

code segment
assume cs:code,ds:data

start:
mov ax,data
mov ds,ax

lea dx,msg
mov ah,09h
int 21h

lea si,s1
lea di,s2
mov bx,0
l1: mov ah,01h
int 21h
mov [si],al
inc bx
inc si
cmp al,31h
jnz l1


mov cx,bx
mov di,bx

dec1:   dec si
loop dec1

mov cx,bx
l2: mov al,[si]
mov [di],al
dec di
inc si
loop l2 

lea dx,rev
mov ah,09h
int 21h

mov cx,bx
l3: mov ah,02h
mov dl,[di]
int 21h
inc di
loop l3


mov ah,4ch
int 21h


code ends
end start

Edit:This is what my code looks now and if I input asd1, then I get 1dserted


Solution

  • EDIT: After Ped7g's comment, I reworked the code. This new one doesn't use the stack to reverse the string and the string is not read as a whole string, but it is read char by char until "Enter" is pressed. Below is the new code.

    assume cs:code, ds:data
    
    data segment
        message db 0Dh, 0Ah, "String: $"
        reverse db 0Dh, 0Ah, "Result: $"
        string db 255 dup(0)
        result db 255 dup('$')
    data ends
    
    code segment
    start:
        mov ax, data
        mov ds, ax
    
        ; Print "String: "
        mov ah, 09h
        lea dx, message
        int 21h
    
        ; Set SI where we read the string
        lea si, string
    
        read:
            ; Read a single character from the keyboard
            mov ah, 01h
            int 21h
    
            ; Save it in the memory
            mov [si], al
            inc si
    
            ; Check if Enter is pressed (if not, then repeat reading)
            cmp al, 0Dh
            jnz read
    
        ; Calculate the length of the string read
        mov ax, si
        lea bx, string
        sub ax, bx
    
        ; Set DI at the last char of result
        lea di, result
        add di, ax
    
        ; Decrement one byte to position DI on the last char
        ; of the string (the Carriage Return)
        dec di
    
        ; Decrement one byte because we don't want to consider
        ; the Carriage Return as a part of our reversed string
        dec di
    
        ; Set SI at the first char of string
        lea si, string
    
        reverse_string:
            ; Copy from the beginning of the initial string
            ; to the end of the reversed string
            mov al, [si]
            mov [di], al
    
            ; Step
            inc si
            dec di
    
            ; Verify if we have reached the end of the initial string
            ; (if the "current" char is Carriage Return)
            cmp byte ptr [si], 0Dh
            jnz reverse_string
    
        ; Print "Result: "
        mov ah, 09h
        lea dx, reverse
        int 21h 
    
        write:
            ; Write the whole reversed string on standard output
            mov ah, 09h
            lea dx, result
            int 21h
    
        mov ah, 4Ch
        int 21h
    code ends
    
    end start
    

    Old answer:

    You can try to use the LIFO property of stack. Below is an example of code that reverses a string using it. The algorithm puts every character from the beginning of the input string, and then pops out to the result (in the reverse order).

    assume cs:code, ds:data
    
    data segment
    
        msg db 0Dh, 0Ah, "String: $"
    
        rev db 0Dh, 0Ah, "Result: $"
    
        buffer label byte
        str_maxlen db 255
        str_length db 0
        str_string db 255 dup(0)
    
        result db 255 dup('$')
    
    data ends
    
    code segment
    
    start:
        mov ax,data
        mov ds,ax
    
        mov ah, 09h
        lea dx, msg
        int 21h         ; print "Your string"
    
        mov ah, 0Ah
        lea dx, buffer
        int 21h         ; read your string
    
        cmp str_length, 0
        je skip         ; check if the input is null
    
        mov ch, 0
        mov cl, str_length
        lea si, str_string
        put_on_stack:
            push [si]   ; copy on the stack (from string)
            inc si
            loop put_on_stack
    
        mov ch, 0
        mov cl, str_length
        lea di, result
        get_from_stack:
            pop [di]    ; copy back to memory (in result)
            inc di
            loop get_from_stack
    
        mov byte ptr [di], '$'
    
        skip:
        mov ah, 09h
        lea dx, rev
        int 21h         ; print "Result: "
    
        mov ah, 09h
        lea dx, result
        int 21h         ; print the result
    
        mov ah,4Ch
        int 21h
    
    code ends
    
    end start