Reputation: 366
This should compare a string given by user with each line of the text file
The line must be printed if equals
But program simply prints nothing even if correct string is provided
I'm probably doing something wrong with push
and pop
instructions
.model small
.stack 100h
.data
filename db 255 dup(0)
text db 255 dup(0)
char db ?
text1 db 0dh, 0ah, 'Enter a string to search for: $'
text2 db 0dh, 0ah, 'Enter a filename : $'
string db 255 dup(0)
filehandle dw ?
.code
newline macro ;NEW LINE
;
mov dl, 10 ;
mov ah, 02h ;
int 21h ;
;
mov dl, 13 ;
mov ah, 02h ; ;
int 21h ;
endm ;NEW LINE
main:
mov ax, @data
mov ds, ax
mov ah, 09h
lea dx, text1 ;'Enter a string to search for: $'
int 21h
lea si, string
mov ah, 01h ;read character
string_input:
int 21h
cmp al, 0dh ;end of string
je zero_terminator2
mov [si], al
inc si
jmp string_input
zero_terminator2:
mov byte ptr [si], 0
mov ah, 09h
lea dx, text2
int 21h
lea si, filename
mov ah, 01h ;read character
char_input:
int 21h
cmp al, 0dh ;end of string
je zero_terminator
mov [si], al
inc si
jmp char_input
zero_terminator:
mov byte ptr [si], 0
open_file:
lea dx, filename
mov al, 0
mov ah, 3Dh ;open file
int 21h
mov filehandle, ax
lea si, text
read_line:
mov ah, 3Fh ;read file
mov bx, filehandle
lea dx, char
mov cx, 1
int 21h
cmp ax, 0 ;EOF
je EO_file
mov al, char
cmp al, 0ah ; line feed
je compare ; compare line with string given by user
mov [si], al
inc si
jmp read_line
EO_file:
push dx ;save dx for later use
push cx ;
push si ;
xor dx, dx
xor si, si
xor di, di
lea si, text
lea di, string
loop_cmp_EOF:
mov al, [si] ;Get the next byte from text
mov bl, [di] ;Get the next byte from string
cmp al, bl ;Compare bytes
jne end_it ;end of program if not equal
cmp al, 0 ;End of string. text=string
je last_print ;Print that line from text
inc si
inc di
jmp loop_cmp_EOF
last_print:
pop dx
pop cx
pop si
newline
lea dx, text ;DX=offset(address) of text
mov ah, 40h ;print
mov cx, si ;CX = # characters. Move pointer to last char to it
sub cx, dx ;Subtract the offset of text (in DX) from CX
;To get the actual number of chars in the buffer
mov bx, 1
int 21h
end_it:
mov ah, 4ch
int 21h
LF_print:
pop dx
pop cx
pop si
newline ;Macro
lea dx, text ;DX=offset(address) of text
mov ah, 40h ;print
mov cx, si ;CX = # characters. Move pointer to last char to it
sub cx, dx ;Subtract the offset of text (in DX) from CX
;To get the actual number of chars in the buffer
mov bx, 1
int 21h
mov si, dx ;Start from beginning of buffer
;(DX=beginning of text buffer)
jmp read_line
compare:
push dx ;save dx for later use
push cx ;
push si ;
xor dx, dx
xor si, si
xor di, di
lea si, text
lea di, string
loop_cmp:
mov al, [si] ;Get the next byte from text
mov bl, [di] ;Get the next byte from string
cmp al, bl ;Compare bytes
jne read_line ;Do not print. Take another line from text
cmp al, 0 ;End of string. text=string
je LF_print ;Print that line from text
inc si
inc di
jmp loop_cmp
end main
Upvotes: 3
Views: 2975
Reputation: 39166
A few problems.
You have to pop
the registers in the reverse order.
push dx ;save dx for later use
push cx ;
push si ;
...
pop si
pop cx
pop dx
In loop_cmp you can not just jump back to read_line because you have 3 words pushed on the stack that will never get popped off!
loop_cmp:
mov al, [si] ;Get the next byte from text
mov bl, [di] ;Get the next byte from string
cmp al, bl ;Compare bytes
jne read_line ;Do not print. Take another line from text
In loop_cmp you compare with zero but you defined the end of the line to be a linefeed (=10). That's not consistent!
cmp al, 0 ;End of string. text=string
je LF_print ;Print that line from text
Upvotes: 3