Reputation: 19
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
Upvotes: 0
Views: 5400
Reputation: 10381
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
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