Search code examples
assemblyinputoutputx86-16emu8086

Assembly 8086 overwrites text


I have this code were I need to insert text, and print it backwards, but when I print the text backwards, it overwrites a string I previously printed. Adding an image for a better understanding:

I can solve it, by adding a line before the printBackWards method. but I'd like to know why this happens

Thanks for your time.

;;deber#1-assembler RODRIGO MAIDANA
.model small
.stack 100h
.data   
    ;arreglo para colectar caracteres
    array db 256 dup('$'),'$'
    
    
    ;;Cadena de texto para solicitar valores y retornar valores
    msg db 10,13,7, "Ingrese un texto: $"
    resultado db 10,13,7, "El texto al reves es: $"
    
    msgERROR db 10,13,7, "VALOR INGRESADO NO ES CORRECTO$"  
    
.code
    

start:
    mov ax, @data
    mov ds, ax
    
    mov dx, offset msg
    call puts
    
    call readText
    
    mov cx, si
    dec si
    
    call putLine
    
    mov dx, offset resultado
    call puts
    
    ;;call putLine
    
    call printArrayBackwards
    
     
    call finish
    
    
    ;;Usamos contador para recorrer el array
    printArrayBackwards:
         mov dl, array[si]
         dec si
         call putc
         
         loop printArrayBackwards 
         ret
    
    ;;Lee el texto que ingresa el usuario hasta ingresar Enter(13) o Esc(27).
    readText:
        call getc               ;;Pedimos caracteres
        
        mov array[si],al        ;;Agregamos caracter al array
        inc si
        
        cmp al,13               ;;Verificamos si el caracter ingreado es ENTER 
        jne verifyEsc           ;;Si no es Enter(13) vamos a verifyEsc
        ret   
    
        verifyEsc: 
            cmp al,27           ;;Verificamos si el caracter ingreado es ESCAPE
            jne readText        ;;Si no es Esc(27) ejecutamos de vuelta la sub-rutina
            
            dec si
            mov array[si],0h    ;;Borramos tecla esc
            inc si
            ret
   
    ;;Agrega un salto de linea
    putLine:
        push ax
        push bx
        push cx
        push dx
        
        mov dl, 13d
        call putc
        
        mov dl, 10d
        call putc
        
        pop dx
        pop cx
        pop bx
        pop ax
        ret  
    
    ;;Ingresa chart por teclado
    getc:
        push bx
        push cx
        push dx 
        
        mov ah, 1h
        int 21h
        
        pop dx
        pop cx
        pop bx
        ret
    
    ;;Imprimimos un caracter   
    putc:     
        push ax
        push bx
        push cx
        push dx  
        
        mov ah, 2h
        int 21h  
        
        pop dx
        pop cx
        pop bx
        pop ax 
        ret 
    
   
    ;;Imprimimos un string
    puts:
        push ax
        push bx
        push cx
        push dx  
        
        mov ah, 9h
        int 21h
        
        pop dx
        pop cx
        pop bx
        pop ax
        ret
    
    ;;Reproduce DING
    putBeep:
        mov dl, 07h
        call putC
        ret 
    
    ;;Liberamos recursos del procesador
    finish:
        mov ax, 4c00h  
        int 21h
        ret

end start

Solution

  • call readText
    
    mov cx, si
    dec si
    

    @Jester's hunch was correct! Whenever the user input ends with a carriage return, your readText routine returns with the carriage return byte included in the count in the SI register. Because the instructions that follow setup a counter with that value and move the offset to that particular carriage return byte, it will be a carrriage return that the printArrayBackwards code outputs first. This will move the cursor to the beginning of the line where you wrote the message "El texto al reves es: ". The characters that are output next, will start overwritting the message.

    The simplest solution is probably to NOT include the terminator in the count that readText returns:

    readText:
        xor  si, si             ; Make sure you start at the beginning of the array
    PedimosCaracteres:
        call getc               ; -> AL
        cmp  al, 27
        je   esEsc
        cmp  al, 13
        je   esEnter
        mov  array[si], al
        inc  si                 ; Only counting 'true' characters
        jmp  PedimosCaracteres
    esEsc: 
        mov  al, 0
    esEnter:
        mov  array[si], al      ; Doesn't include the terminator {0,13} in the count
        ret