2

So I'm programming code in Intel 8086 assembly where I want to input two strings(one string in one line) and a want to save them to the variables. Each string can contain up to 100 utf8 characters. In the output, I try to change the order of then (the first line is going to be the second string from the input) but I get an error that the service 21h is trying to read from an undefined byte. Can you explain to me what I Should change in my code?

cpu 8086
segment code
..start mov ax, data
        mov ds, ax
        mov bx,stack
        mov ss,bx
        mov sp,dno


input1  mov ah,0x0a
        mov dx, load
        int 21h
        mov bl,[load+1]
        mov [chars1+bx],byte '$'

input2  mov ah,0x0a
        mov dx, load
        int 21h
        mov bl,[load+1]
        mov [chars2+bx],byte '$'

output  mov dx,chars2
        mov ah,9
        int 21h

        mov dx,chars1
        mov ah,9
        int 21h

 end    hlt

 segment data
 load   db 200, ?
 chars1     db ?
 resb 100

 chars2 db ?
 resb 100

 segment    stack
 resb 100
 dno:    db ?
Sep Roland
  • 33,889
  • 7
  • 43
  • 76

1 Answers1

1

but I get an error that the service 21h is trying to read from an undefined byte. Can you explain to me what I Should change in my code?

You are not loading the address of the input structure that is required by the DOS.BufferedInput function 0Ah. Read all about it in How buffered input works.

Emu8086 follows MASM programming style where mov dx, load will set the DX register equal to the word stored at the address load. To actually receive the address itself, you'll need to write mov dx, offset load.

A further problem is that both input1 and input2 try to use the same load input structure but with different buffer memories. The buffer has to be part of the input structure for this DOS function; it always has to reside at offset 2 from the provided address (load in your case).

This is how you can solve it:

 ...

input1: mov ah, 0Ah
        mov dx, OFFSET loadA
        int 21h
        mov bl, [loadA+1]
        mov bh, 0
        mov [charsA+bx], byte '$'

input2: mov ah, 0Ah
        mov dx, OFFSET loadB
        int 21h
        mov bl, [loadB+1]
        mov bh, 0
        mov [charsB+bx], byte '$'

output: mov dx, OFFSET charsB
        mov ah, 09h
        int 21h

        mov dx, OFFSET crlf
        mov ah, 09h
        int 21h

        mov dx, OFFSET charsA
        mov ah, 09h
        int 21h

 ...

loadA   db  101, 0
charsA  db  101 dup (0)
loadB   db  101, 0
charsB  db  101 dup (0)
crlf    db  13, 10, "$"
 ...
  • 101 provides room for 100 characters and 1 terminating carriage return.
  • Don't trust too much registers that you didn't set yourself! Write an explicite mov bh, 0 before using the whole of BX.
  • Since you want these strings outputted on different lines, I've added code to move to the start of the following line. See the crlf.
Sep Roland
  • 33,889
  • 7
  • 43
  • 76