2

The task sounds like: "Enter the s1 string at least 10 characters in length. Copy the last but one character three times and the first from string s1 to string s2. Display the lines s1 and s2."

I've tormented with this code for two days and still can't achieve the result, as well can't understand how to fix it. We've learnt for now only 0Ah, 02h, 09h and 40h functions besides int21h / 4ch. For the code below compilation doesn't allow me to enter anything and prints 3 symbols which are pretty similar to the 6.

.model small
.stack
.data

m1 db "Enter the string:", 10, 13,  "$"
maxlength db 11
clength db ?
s1 db 11 dup(?)
s2 db 5 dup(?)
nline db 10,13,"$"

.code

mov ax, @data
mov ds, ax

mov ah, 9
lea dx, m1
int 21h

mov ah, 0Ah
lea dx, s1
int 21h

mov bl, clength
mov bh, 0

mov AL, s1[BX-2]
mov s2+1, AL

mov AL, s1[BX-2]
mov s2+2, AL

mov AL, s1[BX-2]
mov s2+3, AL

mov AL, s1[BX+1]
mov s2+4, AL

mov s2+5, "$"
mov s1[bx], "$"

mov ah, 9
lea dx, s1
int 21h

mov ah, 9
lea dx, nline
int 21h

mov ah, 9
lea dx, s2
int 21h

mov ah, 9
lea dx, nline
int 21h

mov ah, 4ch
int 21h
end

I expect the output to be: Enter the string (the string I print)

(symbols copied from s1)

pcarter
  • 1,516
  • 14
  • 21
Darya Balu
  • 143
  • 1
  • 9
  • You should read the description [of `int 21h / 0ah`](http://spike.scu.edu.au/~barry/interrupts.html#ah0a). You haven't set up the buffer properly (or rather, you're passing the wrong offset in `dx`). – Michael Sep 23 '19 at 19:03
  • I undetstood nothing but thank you for the try. – Darya Balu Sep 24 '19 at 15:04

2 Answers2

1
mov ah, 0Ah
lea dx, s1
int 21h

In your program the address for this DOS function needs to become "maxlength".
You could also write this as lea dx, [s1-2].

The actual buffer that DOS requires is:

MyInput db 11, 0, 11 dup(?)

mov ah, 0Ah
lea dx, MyInput
int 21h

You can read more about the 0Ah DOS function in How buffered input works.


and the first from string s1

You've solved this by writing:

mov AL, s1[BX+1]
mov s2+4, AL

This is not correct. At s1[bx+1] there's only garbage in memory. You can fetch the 1st character of s1 via mov al, s1.


mov AL, s1[BX-2]
mov s2+1, AL
mov AL, s1[BX-2]
mov s2+2, AL
mov AL, s1[BX-2]
mov s2+3, AL
mov AL, s1[BX+1]
mov s2+4, AL
mov s2+5, "$"

The s2 string has but 5 positions available. Your adding of +1 to +5 will write behind this buffer! This will destroy your NewLine string.
You need to use additions from +0 to +4 to stay within the bounds of the buffer.

mov AL, s1[BX-2]
mov s2, AL            NEW
mov AL, s1[BX-2]
mov s2+1, AL          NEW
mov AL, s1[BX-2]
mov s2+2, AL          NEW
mov AL, s1            NEW
mov s2+3, AL          NEW
mov s2+4, "$"         NEW

And of course you don't need to read that second to last character 3 times.

mov al, s1[bx-2]
mov s2, al
mov s2+1, al
mov s2+2, al
mov al, s1
mov ah, "$"
mov s2+3, ax
Fifoernik
  • 9,779
  • 1
  • 21
  • 27
0

If you follow Michael's link to the description of int 21h / 0ah you can see that DS:DX is expected to point to a buffer where the first byte is the maximum number of characters, the second byte is the number of characters actually read, and then more bytes to store the read string. You do actually allocate those first two bytes (maxlength and clength), but you point DX to s1 which would be the first byte of the read characters, not the whole buffer. Also (assuming this is MASM syntax)

idspispopd
  • 404
  • 3
  • 10