This gist hosts all required files. I'll first explain what I'm doing here.
The program should read two separate strings of various lengths, less than 200, terminated by a newline character. After reading the strings, search if either of the two string is a sub-string of another. In case that both of them are the same; return true.
TRUE
: One of the string IS a sub-string.FALSE
: Both strings are entirely different.What I'm doing in my program is:
STR1
and STR2
by calling the procedure READ_STR
. The procedure returns the length of strings in BX. I'm storing the length of first string in another variable L1
of type DW
.Compare the length of second string (now in BX
) with L1
.
CX
to 1CX = abs.( BX - L1 )
| Absolute of BX - L1
.This is to set how many times can a smaller string be iterated inside the larger one. Set the DI
to point to the longer string.
L1
to be the length of smaller string.DX
as 0. Start a loop with the value of CX
as set above.DX
to DI
and use CMPSB
to compare the shorter string SI
with longer one DI
. Update CX
to be L1
so that REPE CMPSB
can work. DX
if the search failed. Reset CX
, DI
and SI
. Start from step 4 after decrementing CX
by 1 (done by using the LOOP
operation).There is an extra line in the third output because of the following statements (line #72 & #73). The call to DISP_STR
failed.
NEWLINE
CALL DISP_STR
TITLE Assignment: Read two strings and ...
.MODEL SMALL
SAVE_REG MACRO REGS
IRP D, <REGS>
PUSH D
ENDM
ENDM
LOAD_REG MACRO REGS
IRP D, <REGS>
POP D
ENDM
ENDM
END_DOS MACRO
MOV AH, 76
INT 21H
ENDM
NEWLINE MACRO
SAVE_REG <AX, DX>
MOV AH, 2
MOV DL, 0AH
INT 21H
MOV DL, 0DH
INT 21H
LOAD_REG <DX, AX>
ENDM
.STACK 100H
.DATA
STR1 DB 200 DUP(65)
STR2 DB 200 DUP(0)
PROMPT DB "Enter string "
NUM DB "1: $"
L1 DW 0
UNEQL DB "No substring found$"
EQUAL DB "Substring was found$"
.CODE
MAIN PROC
MOV AX, @DATA
MOV DS, AX
MOV ES, AX
MOV AH, 9
LEA DX, PROMPT
INT 21H
LEA DI, STR1
CALL READ_STR
MOV L1, BX
NEWLINE
MOV NUM, '2'
INT 21H
CALL READ_STR
LEA SI, STR1
LEA DI, STR2 ; DI stores the longer string
CMP L1, BX
JE EQL
CMP L1, BX
JG INV
MOV CX, BX
SUB CX, L1
JMP COMPARE
INV:
MOV CX, L1
SUB CX, BX
MOV L1, BX
LEA SI, STR2
LEA DI, STR1 ; DI stores longer string
NEWLINE
CALL DISP_STR
JMP COMPARE
EQL:
MOV CX, 1
COMPARE:
XOR DX, DX
TOP:
SAVE_REG <DI, SI>
ADD DI, DX
PUSH CX
MOV CX, L1
REPE CMPSB
JCXZ FOUND
INC DX
POP CX
LOAD_REG <SI, DI>
LOOP TOP
NOT_FOUND:
NEWLINE
LEA DX, UNEQL
MOV AH, 9
INT 21H
END_DOS
FOUND:
POP CX
LOAD_REG <SI, DI>
NEWLINE
LEA DX, EQUAL
MOV AH, 9
INT 21H
END_DOS
MAIN ENDP
INCLUDE READSTR.ASM
INCLUDE DISPSTR.ASM
END MAIN
DISP_STR PROC
SAVE_REG <AX, CX, DX, SI>
MOV CX, BX
CLD
MOV AH, 2
DISP_LOOP:
LODSB
MOV DL, AL
INT 21H
LOOP DISP_LOOP
LOAD_REG <SI, DX, CX, AX>
RET
DISP_STR ENDP
READ_STR PROC
SAVE_REG <AX, DI>
XOR BX, BX
CLD
MOV AH, 1
INT 21H
WHILE_LOOP:
CMP AL, 0DH
JE END_WHILE
CMP AL, 08H
JNE STORAGE
DEC BX
DEC DI
JMP NEXT
STORAGE:
STOSB
INC BX
NEXT:
INT 21H
JMP WHILE_LOOP
END_WHILE:
LOAD_REG <DI, AX>
RET
READ_STR ENDP
You should learn to use a debugger so you can fix your code yourself.
Anyway, from a quick glance, the first obvious problem is that when you use READ_STR
to read the second string you don't set up DI
to point at STR2
. As such, since READ_STR
preserves DI
, the second string will be read into STR1
too, overwriting the first. Solution: move the LEA DI, STR2
on line 58 up to before line 56. If there are no other errors lurking, that should fix it.