Hardware Reference
In-Depth Information
After returning from fillbuf , line 24 checks whether anything was actually read.
If not, we jump out of the buffered read loop to the second part of the program in
line 25.
Now we are ready to scan the buffer. The symbol \n (line feed) is loaded into
AL on line 26, and in line 27 this value is scanned for by REP SCASB and com-
pared to the symbols in the buffer. There are two ways to exit the loop: either
when CX hits zero or when a scanned symbol is a new line character. If the zero
flag is set, then the last symbol scanned was a \n and the file position of the current
symbol (one after the new line), is to be stored in the linh array. The count is then
incremented and the file position is computed from BX and the number of charac-
ters still available is in CX (lines 29 through 31). Lines 32 through 34 perform the
actual store, but since STOS assumes that the destination is in DI instead of in SI ,
these registers are exchanged before and after the STOS . Lines 35 through 37
check whether more data is available in the buffer, and jump according to the value
of CX .
When the end of the file is reached, we have a complete list of file positions of
the heads of the lines. Because we started the linh array witha0word, we know
that the first line started at address 0, and that the next line starts at the position
given by linh
+
2 etc. The size of line n can be found from the starting address of
line n
1 minus the start address of line n .
The aim of the rest of the program is to read the number of a line, to read that
line into the buffer, and to output it by means of a write call. All the necessary
information can be found in the linh array, whose n th entry contains the position of
the start of line n in the file. If the line number requested is either 0 or out of
range, the program exits by jumping to label 7.
This part of the program starts with a call to the getnum subroutine on line 46.
This routine reads a line from standard input and stores it in the linein buffer, (on
lines 95 through 103). Next, we prepare for the SSCANF call. Considering the
reverse order of the arguments, we first push the address of curlin , which can hold
an integer value, then the address of the integer format string numfmt , and finally
the address of the buffer linein containing the number in decimal notation. The
system subroutine SSCANF puts the binary value in curlin if possible. On failure, it
returnsa0in AX . This return value is tested on line 48; on failure, the program
generates an error message through label 8.
If the getnum subroutine returns a valid integer in curlin , then we first copy it
in BX . Next we test the value against the range in lines 49 through 53, generating
an EXIT if the line number is out of range.
Then we must find the end of the selected line in the file and the number of
bytes to be read, so we multiply BX by 2 with a left shift SHL . The file position of
the intended line is copied to AX on line 55. The file position of the next line is in
CX and will be used to compute the number of bytes in the current line.
To do a random read from a file, an lseek call is needed to set the file offset to
the byte to be read next. The lseek is performed with respect to the start of the file,
+
Search WWH ::




Custom Search