0

Why when I try to get my output only get a half (or even less) of my original input buffer?

At first I enter random symbols and when I transfer them into new buffer, but a result I get half of that originally buffer and I don't know why

These are parts of my code:

My data segment:

.data
buff     db 255,?,255 dup("$")
result   db 255,?,255 dup(" ")
_result  db "Result: $"
endl     db 13,10,"$"

I scan with int21,0Ah:

    mov ah, 0Ah
    mov dx, offset buff
    int 21h

Here I transfer symbols to another buffer

    loop_tranfer:
        
        mov ah, [si]     ;source buffer     
        mov  [ di ], ah      ;ah move to result buffer 
        inc di               ;increase destination index
        inc si               ;increase source index
                                              
    loop loop_tranfer

Here I want to get a result, but I can't

    mov ah, 09h
    mov dx, offset _result ;message "Result:"
    int 21h
    
    mov ah, 40h
    mov bx, 1 
    xor cx, cx
    mov cl, result+1
    mov dx, offset result ; result ; here I get less than than entered
    int 21h

    mov ax, 4c00h ;exit
    int 21h 

end start

Peter Cordes
  • 328,167
  • 45
  • 605
  • 847
NewAtC
  • 55
  • 9
  • Any sugestions? – NewAtC Nov 11 '21 at 07:58
  • 1
    [loop uses cx](https://stackoverflow.com/questions/46881279/how-exactly-does-the-x86-loop-instruction-work), the snippets you're showing don't put anything meaningful into cx before the loop. –  Nov 11 '21 at 10:06

1 Answers1

2

I scan with int21,0Ah:

Do read How buffered input works

You don't show us how you initialized the CX, SI, and DI registers that you use in your loop_tranfer. That's rather essential!

(1) To copy one full buffer to the other:

mov   di, offset result
mov   si, offset buff
mov   cx, 2+255

(2) To copy only the inputted symbols to the other buffer (in sync)

mov   di, offset result+2
mov   si, offset buff+2
movzx cx, byte ptr [si-1]

(3) To copy only the inputted symbols to the other buffer (no sync)

mov   di, offset result
mov   si, offset buff+2
movzx cx, byte ptr [si-1]

mov dx, offset result

If the buffer copy that you made included the 2 header bytes (1), then it's conceivable that the value in the second byte (the actual length) could be interpreted as a special byte by the DOS.WriteToDevice function 40h. eg. A length of 8 will perform a backspace since you are sending the bytes to STDOUT aka the screen.

mov cl, result+1

If the buffer copy that you made only included the actual characters, but you copied these starting at result (3), then the length that you pass to the DOS function can vary a lot! The length will get derived from the ASCII code of a character.

Sep Roland
  • 33,889
  • 7
  • 43
  • 76
  • I use ```CX``` in ```xor cx, cx ;clear register```; and ```SI, DI``` as sourse and destination registers: ```mov si, offset buff+2 ;source``` ```mov di, offset result ;destination``` – NewAtC Nov 29 '21 at 23:19
  • 1
    @NewAtC If you started your *loop_tranfer* loop with a count `CX=0` then the `LOOP` instruction will have iterated 65536 times. This would have caused a serious shift in the data segment and can explain why you got only half or less of the desired output. Anyway, the pointers that you say you used match case (3) from my answer. – Sep Roland Nov 30 '21 at 00:46
  • I didn't use ```CX``` before loop, so maybe it was a mistake, but if I put ```movzx cx, byte ptr [si-1]``` in my code I get error ```Illeagal instructions``` – NewAtC Nov 30 '21 at 14:57
  • @NewAtC Depending on the coding/executing environment that you use, it is indeed possible that the `MOVZX` instruction is not available. You can substitute it easily: `xor cx, cx` `mov cl, [si-1]`. – Sep Roland Dec 01 '21 at 16:55