1

The program needs to iterate trough the input that a user enters and replace every underscore character ("_") that it finds with "@".
The program does it, but just one time, then every underscore character that is found, stays the same.

.MODEL SMALL
.STACK
.DATA
    string_input DB "Enter a string: $"
    string_output DB "Your string is: $" 
 
 
    bufferLong db 250  
    inputLong db 0
    buffer db 250, 0, 250 dup ("$"), "$"
 
.CODE 
 
start:
    mov ax, @data
    mov ds, ax
 
    mov dx, offset string_input
    mov ah, 09h
    int 21h
 
    call inputString
 
   ;mov cl, al 
 
    mov dl, 0Ah
    mov ah, 02h
    int 21h
 
    mov dl, 0Dh
    mov ah, 02h
    int 21h
 
    mov dx, offset string_output
    mov ah, 09h
    int 21h
 
    ;mov al, cl
 
 
    call outputString
 
    mov ax, 4C00h
    int 21h
 
 
 
    inputString proc 
        mov dx, offset bufferLong
        mov ah, 0Ah
 
        int 21h 
        ret
        inputString endp
 
    outputString proc
        mov dx, offset buffer
        mov ah, 09h
        mov si,0
        mov cx, 0
        mov bl, "_"
 
        loop:
            cmp bl, buffer[si]
            je replace
            inc cx
            inc si
            jne loop 
 
        replace: 
            mov buffer[si], "@"
 
        int 21h
        ret
        outputString endp
 
    end start
Sep Roland
  • 33,889
  • 7
  • 43
  • 76
  • 1
    Read what your code does - not what you intend it to do, but what is actually written. (1) What happens after `mov buffer[si], "@"`? (2) How many times will `loop` iterate - under what conditions is the `jne loop` not taken? (3) When it finally is not taken, what happens next? – Nate Eldredge Oct 08 '21 at 19:35
  • Remember that `jne loop` jumps on the basis of the flags at the time it is executed, and `inc cx` and `inc si` modify those flags. So if you think it is jumping based on the result of `cmp bl, buffer[si]` you are mistaken. – Nate Eldredge Oct 08 '21 at 19:36
  • Stepping through this code with a debugger will help in understanding what it actually does - much more informative than trying to guess based on the output. – Nate Eldredge Oct 08 '21 at 19:38

1 Answers1

1
bufferLong db 250  
inputLong db 0
buffer db 250, 0, 250 dup ("$"), "$"

This looks like you don't truly know what the required input structure for this DOS.BufferedInput function 0Ah should look like. Read more about it at How buffered input works.
This is the correct definition:

bufferLong db 250  
inputLong db 0
buffer db 250 dup (0)

Upon the first replacement, you immediately print the result, where in fact you should continu the loop. Better change the conditional jump to the opposite like this (from je to jne):

        xor si, si
    loop:
        mov al, buffer[si]
        cmp al, 13
        je  print           ; Exit the loop upon finding 13
        cmp al, "_"
        jne skip            ; While skipping you stay in the loop
    replace: 
        mov buffer[si], "@"
    skip:
        inc si
        jmp loop            ; Unconditionally to the top where a possible exit can get detected

    print:
        mov buffer[si], "$"
        mov dx, offset buffer
        mov ah, 09h
        int 21h
        ret

What your 'loop' was missing is a clear way to exit. The string that you process ends with a carriage return (13). Use that to stop iterating. This could happen from the start if the user did not type in characters and just used enter.
Next you need to provide the correct string termination so DOS can print the result. Preloading the input buffer with $ characters serves no purpose. Just store one $ character either replacing the byte 13 or else right behind the byte 13.

Sep Roland
  • 33,889
  • 7
  • 43
  • 76