Saturday, June 16, 2007

String Instructions' Exercise

String Instructions' Task

  1. Read a string from user using single character input service until the user presses enter character. Store the string in memory
  2. Copy this string to another memory location
  3. Retrieve the new string from memory and display it to the user in new line using single character output service.
  4. Take another single character input from user and find the number of occurrences of this character in the string.
  5. Input another string from the user and find the points of differences between this and old string.
Notes
  • The strings can not be more than 20 characters long.
  • All the task points are designed to make use of string instructions. Other ways to do these tasks are not valid.

Solution

.model small
.stack 100h
.data

string1 db 21 dup(0)
string2 db 21 dup( 0)

msg1 db "The character '", 0
msg2 db "' is repeated " , 0
msg3 db " time", 0
msg4 db "Please enter a string of 20 character at most: ", 0
msg5 db "Please enter the character to be found in the string: " , 0
msg6 db "Please enter another string of 20 characters at most: ", 0
msg7 db "The points of differences in both strings are ", 0

.code

; Macro to print a new line
mNewLine macro

mov ah, 02h
mov dl, 0dh
int 21h
mov dl, 0ah
int 21h

endm

; Procedure to input a string, 20 characters max
; Expects offset of memory in di
pStringInput proc

mov cx, 20 ; 20 charcters max

start1:

mov ah, 01h ; Take single character input
int 21h ; its in al now

cmp al, 0dh ; if its enter, exit
je exit1

stosb ; store the new character in the memory at di

loop start1

exit1:

ret

pStringInput endp

; Procedure to copy a string to another
; Expects offset of source in si and destination in di
pCopyString proc

mov cx, 20 ; 20 chars max
rep movsb ; copy from si to di
ret

pCopyString endp

; Procedure to display a null terminated string
; Expects offset of memory in si
pDisplayString proc

mov ah, 02h ; Single character output

start3:

lodsb ; load value in al from memory

cmp al, 0 ; if its 0 (null),
je exit3 ; exit

mov dl, al ; put the value in dl
int 21h ; and call the interrupt

jmp start3

exit3:

ret

pDisplayString endp

; Procedure to count occurences of some character in another string
; Expects the offset of memory in di
pCountChar proc

mov ah, 01h ; Get the character to be searched
int 21h

mov cx, 20 ; look in 20 charcters long string
mov dx, 0

start4:

repne scasb ; repeat if not found, stop if found
cmp cx, 0 ; either the character in found or cx is 0
je exit4 ; if cx is 0, means string finished, exit
inc dx ; otherwise, the character is found, increment dx to count it

jmp start4 ; go back and seacrh again until cx is 0

exit4:

dec di ; the last scasb had incremented di to 21st position, come back to 20th
cmp [di], al ; compare if the last character, when cx was zero, is same as we are searching for
jne skip ; no? skip

inc dx ; yes? count this one too

skip:

mov cl, al ; save the required character
mov ch, dl ; save the number of occurences

mNewLine

mov si, offset msg1
call pDisplayString

mov dl, cl ; print the character
mov ah, 02h
int 21h

mov si, offset msg2
call pDisplayString

mov ax, 0 ; print the number of occurences
mov al, ch
call pDecDisplay

mov si , offset msg3
call pDisplayString

ret

pCountChar endp

; Procedure to count number of difference between two strings
; Expects offsets in si and di
pPointsOfDiffs proc

mov dx, 0
mov cx, 20
start5:

repe cmpsb ; repeat until equal, stop when not equal
cmp cx, 0 ; either cx is 0 or the character are not equal
je exit5 ; if cx is 0, exit
inc dx ; count the point of difference

jmp start5 ; go back until cx is 0

exit5:

dec di
dec si
mov al, [si]
cmp [ di], al ; check if the last onew were different
je skip ; no? skip

inc dx ; yes? count this one as well

skip:

mov ax, dx ; display
call pDecDisplay

ret

pPointsOfDiffs endp

; Procduer to display a number in decimal
; Expect the number in ax
pDecDisplay proc

mov si, 10
mov cx, 0

start6:

mov dx, 0
div si
push dx
inc cx
cmp ax, 0

jne start6

mov ah, 02h

start7:

pop dx
add dl , 30h
int 21h

loop start7

ret

pDecDisplay endp

main:

; Set the data segment and extra segment
mov ax, @data
mov ds, ax
mov es, ax

; Display the message
mov si, offset msg4
call pDisplayString

; Input the string Task 1
mov di, offset string1
call pStringInput

; Come to new line
mNewLine

; Copy the string to new location Task 2
mov si, offset string1
mov di, offset string2
call pCopyString

; Display the new string Task 3
mov si, offset string2
call pDisplayString

; Display new line
mNewLine

; Print the message
mov si, offset msg5
call pDisplayString

; Count the number of occurences Task 4
; of some in the string
mov di, offset string1
call pCountChar

; new line
mNewLine

; Display message
mov si, offset msg6
call pDisplayString

; Get a new string input
mov di, offset string2
call pStringInput

; new line
mNewLine

; Display message
mov si, offset msg7
call pDisplayString

; Count the points of differences Task 5
; between the strings
mov si, offset string1
mov di, offset string2
call pPointsOfDiffs

; Exit
mov ah, 4ch
int 21h

end main

No comments: