Reputation: 366
Okay, all I want to do is just read line by line from text and then output it.
Things I do:
Problems:
.txt example
some random text
.model small
.stack 100h
.data
filename db 255 dup(0)
text db 255 dup(0)
char db ?
line 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
lea si, filename
mov ah, 01h ;read character
char_input:
int 21h
cmp al, 0dh ;enter
je zero_terminator
mov [si], al
inc si
jmp char_input
zero_terminator:
mov [si], 0
open_file:
lea dx, filename
mov al, 0
mov ah, 3Dh ;open file
int 21h
mov filehandle, ax
lea si, text
newline
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 LF
mov [si], al
inc si
jmp read_line:
EO_file:
lea dx, text
mov ah, 40h ;print
mov cx, 255
mov bx, 1
int 21h
mov ah, 4ch
int 21h
LF:
lea dx, text
mov ah, 40h ;print
mov cx, 255
mov bx, 1
int 21h
inc si
jmp read_line
end main
Upvotes: 1
Views: 11249
Reputation: 47573
This is meant to get you going, not to solve all the bugs in your code:
You have:
zero_terminator:
mov [si], 0
The idea is to move a 0 byte to the location pointed to by SI. TASM doesn't understand that you want to move a single byte to [SI] so it should be told explicitly that is what you intend:
mov byte ptr [si], 0
You have a typo on this line with a colon on the end:
jmp read_line:
It should be:
jmp read_line
The primary issue with your code is that when going to print out the characters read into the text
character array you need to specify the number of characters to print in CX . You specify 255 with code like this:
LF:
lea dx, text
mov ah, 40h ;print
mov cx, 255
Since SI contains a pointer to the last character read, you can subtract the address (offset) of text from SI to get the number of characters in the buffer. So what is above could be changed to:
LF:
lea dx, 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
Once you print out a line you inc SI and return to reading characters. Since you have printed out the line, you may as well restart from the beginning of the text buffer by resetting SI back to the start with:
mov si, dx ; start from beginning of buffer (DX=beginning of text buffer)
or you can just mov DX which contains the offset of text already and set SI to it with:
This is the same way you originally set things up at the start of reading data.
The EOF code you have has a similar issue where it requires the number of bytes in the buffer to be placed in ECX. So this code:
EO_file:
lea dx, text
mov ah, 40h ;print
mov cx, 255
mov bx, 1
int 21h
Can be changed to:
LF:
lea dx, 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
With all these changes you would get a program like:
.model small
.stack 100h
.data
filename db 255 dup(0)
text db 255 dup(0)
char db ?
line 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
lea si, filename
mov ah, 01h ;read character
char_input:
int 21h
cmp al, 0dh ;enter
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
newline
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 LF
mov [si], al
inc si
jmp read_line
EO_file:
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 ah, 4ch
int 21h
LF:
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
end main
Upvotes: 3