Hardware Reference
In-Depth Information
the main program, which determines the names of the executable and the auxiliary
files. For example, for the program of Fig. C-17(a) use
as88 strngcpy.s stringpr.s
The program of Fig. C-17(b) outputs strings in reverse order. We will now look at
them in turn.
To demonstrate that the line numbers are really just comments, in Fig. C-17(a)
we have numbered the lines starting with the first label, omitting what comes
before them. The main program, on lines 2 through 8, first calls strngcpy with two
arguments, the source string, mesg2 , and the destination string, mesg1 , in order to
copy the source to the destination.
Now let us look at strngcpy , starting on line 9. It expects that the addresses of
the destination buffer and the string source have been pushed onto the stack just
before the subroutine is called. On lines 10 to 13, the registers used are saved by
pushing them onto the stack so that they can be restored later on lines 27 to 30. On
line 14, we copy SP to BP in the usual way. Now BP can be used to load the argu-
ments. Again, on line 26, we clean the stack by copying BP to SP .
The heart of the subroutine is the instruction REP MOVSB , on line 24. The
instruction MOVSB moves the byte pointed to by SI to the memory address pointed
to by DI . Both SI and DI are then incremented by 1. The REP creates a loop in
which this instruction is repeated, decrementing CX by 1 for each byte moved. The
loop is terminated when CX reaches 0.
Before we can run the REP MOVSB loop, however, we have to set up the regis-
ters, which is done in lines 15 through 22. The source index, SI , is copied from the
argument on the stack on line 21; the destination index, DI , is set up on line 22.
Obtaining the value of CX is more involved. Note that the end of a string is indi-
cated by a zero byte. The MOVSB instruction does not affect the zero flag, but the
instruction SCASB (scan byte string) does. It compares the value pointed to by DI
with the value in AL , and it increments DI on the fly. Moreover, it is repeatable like
MOVSB . So, on line 15 AX and hence AL is cleared, on line 16 the pointer for DI is
fetched from the stack, and CX is initialized to
1 on line 17. On line 18, we have
the REPNZ SCASB , which does the comparison in loop context, and sets the zero
flag on equality. At each step of the loop, CX is decremented, and the loop stops
when the zero flag is set, because the REPNZ checks both the zero flag and CX .
The number of steps for the MOVSB loop is now computed as the difference of the
current value of CX and the previous
1 on lines 19 and 20.
It is cumbersome that there are two repeatable instructions necessary, but this
is the price for the design choice that move instructions never affect the condition
codes. During the loops, the index registers have to be incremented, and to this
end it is necessary that the direction flag is cleared.
Lines 23 and 25 print the copied string by means of a subroutine, stringpr ,
which is in the examples directory. It is straightforward and will not be discussed
here.
Search WWH ::




Custom Search