Chouny
Chouny

Reputation: 19

Printing a String with a Start and Length Assembly Language

I was trying to build an Assembly Code, that ask for a string, start where the string would be printed and the desired length to be printed. assume start and length are always valid Can you help me to determine the start and length.

How it should work:

Enter String: Hello World
Enter Start: 3
Enter Length: 5
Mid-String: llo W

So I have a problem on how to determine the start and length of the string. I tried several things which is shown in my code below:

.model small
.stack
.data
msg1 db "Enter String:$"
msg2 db 13,10,"Enter Start:$"
msg3 db 13,10,"Enter Length:$"
msg4 db 13,10,"Mid-String:$"
nwln db 13,10
mySample label byte
maxlen db 10
actlen db 0
string db 19 dup (?)
.code
mov ax,@data
mov ds,ax
    lea dx, msg1 ;print msg1
    mov ah,9
    int 21h

    lea dx,mySample ;accept string
    mov ah,0Ah
    int 21h

    mov bh,0
    mov bl,maxlen
    mov string[bx],'$'
    mov ah,9
    lea dx,string   ;print string accept
    int 21h

    lea dx, msg2    ;print msg2 and accept start
    mov ah,9
    int 21h
    mov ah,1
    int 21h
    sub al,30h
    mov bh,0
    mov bl,al

    lea dx, msg3    ;print msg3 and accept length
    mov ah,9
    int 21h
    mov ah,1
    int 21h
    sub al,30h
    mov dl,al

    ;mov maxlen,dl
    mov bh,0
    mov bl,maxlen
    mov string[bx],'$'
    lea dx,msg4     ;print msg4
    mov ah,9
    int 21h
    lea dx,string   ;print mid-string
    int 21h
mov ah,4ch
int 21h
END

OUTPUT LOOKS LIKE: output from the code above

Upvotes: 0

Views: 5400

Answers (2)

I made some little changes to your code to make it work, those little changes are commented, basically, it was a matter of using pointers properly (pointers to start position and length), that I replaced by registers SI and DI :

.model small
.stack
.data
msg1 db "Enter String:$"
msg2 db 13,10,"Enter Start:$"
msg3 db 13,10,"Enter Length:$"
msg4 db 13,10,"Mid-String:$"
nwln db 13,10
mySample label byte
maxlen db 10
actlen db 0
string db 19 dup (?)
.code
mov ax,@data
mov ds,ax
    lea dx, msg1 ;print msg1
    mov ah,9
    int 21h

    lea dx,mySample ;accept string
    mov ah,0Ah
    int 21h

    mov bh,0
    mov bl,actlen   ;◄■■■ NOT MAXLEN.
    mov string[bx],'$'
    mov ah,9
    lea dx,string   ;print string accept
    int 21h

    lea dx, msg2    ;print msg2 and accept start
    mov ah,9
    int 21h
    mov ah,1
    int 21h
    sub al,30h
    mov bh,0
    mov bl,al
    mov si,bx       ;◄■■■ SAVE BX IN SI, BECAUSE WE WILL NEED
                    ;◄■■■  BX FOR SOMETHING ELSE (SI = "START").

    lea dx, msg3    ;print msg3 and accept length
    mov ah,9
    int 21h
    mov ah,1
    int 21h
    sub al,30h
    mov bl,al       ;◄■■■ REPLACE DL BY BL BECAUSE DX WILL
                    ;◄■■■ BE USED TO DISPLAY WITH INT 21H.
    ;mov maxlen,dl
    mov bh,0        ;◄■■■ NOW BX = "LENGTH". BUT WE WILL NEED
    mov di,bx       ;◄■■■ BX AGAIN, SO LET'S MOVE "LENGTH" TO DI.

    ;mov bl,maxlen
    add di, si         ;◄■■■ CALCULATE END POSITION.
    dec di, 1          ;◄■■■ MINUS 1 BECAUSE IT STARTS IN 0.
    mov string[di],'$'
    lea dx,msg4     ;print msg4
    mov ah,9
    int 21h
    ;lea dx,string   ;print mid-string
    mov dx,offset string
    add dx,si
    int 21h
mov ah,4ch
int 21h
END

Upvotes: 1

Peter Cordes
Peter Cordes

Reputation: 365257

Based on a quick look at the last few instructions, where you actually do the offset and print (assuming the rest of your code just prints and reads strings correctly):

You forgot to convert from ASCII to an integer, so you write the terminating $ many bytes past the end of the string ('0' to be precise: the ASCII encoding of 0).

You also don't appear to use the start offset for anything. It would be easy to do something like lea dx, [string + bx] after getting atoi(start_offset_string) into BX.

Your length counts from the beginning of the original string, not from the offset position. You might want to do the offset first.

Upvotes: 2

Related Questions