Hardware Reference
In-Depth Information
In the reverse print program shown in Fig. C-17(b), the first line includes the
usual system call numbers. On line 3, a dummy value is pushed onto the stack,
and on line 4, the base pointer, BP , is made to point to the current top of stack. The
program is going to print ASCII characters one by one, thus the numerical value
PUTCHAR is pushed onto the stack.
Note that BP points to the character to be
printed when a SYS call is made.
Line 2, 6 and 7 prepare the registers DI , AL and CX for the repeatable SCASB
instruction. The count register and the destination index are loaded in a similar
way as in the string copy routine, but the value of AL is the new line character,
instead of the value 0. In this way, the SCASB instruction will compare the charac-
ter values of the string str to \n instead of to 0, and set the zero flag whenever it is
found.
The REP SCASB increments the DI register, so, after a hit, the destination index
points at the zero character following the new line. On line 12, DI is decremented
by two to have it point to the last letter of the word.
If the string is scanned in reverse order and printed character by character, we
have obtained our goal, so on line 10 the direction flag is set to reverse the adjust-
ment of the index registers in the string instructions. Now the LODSB on line 14
copies the character in AL , and on line 15 this character is put just next to the
PUTCHAR on the stack, so the SYS instruction prints it.
The instructions on lines 18 and 19 print an additional new line and the pro-
gram closes with an EXIT call in the usual way.
The current version of the program contains a bug. It can be found if the pro-
gram is traced step by step.
The command /str will put the string str in the tracer data field. Since the
numerical value of the data address is also given, we can find out how the index
registers run through the data with respect to the position of the string.
The bug, however, is encountered only after hitting the return many times. By
using the tracer commands we can get to the problem faster. Start the tracer and
give the command 13 to put us in the middle of the loop. If we now give the com-
mand b we set a breakpoint on this line 15. If we give two new lines, then we see
that the final letter e is printed in the output field. The r command will keep the
tracer running until either a breakpoint or the end of the process is encountered. In
this way, we can run through the letters by giving the r command repeatedly until
we are close to the problem. From this point, we can run the tracer at one step at a
time until we see what happens at the critical instructions.
We can also put the breakpoint at a specific line, but then we must keep in
mind, that the file ../syscalnr is included, which causes the line numbers to be off-
set by 20. Consequently, the breakpoint on line 16 can be set by the command
36b . This is not an elegant solution, so it is much better to use the global label
start on line 2 before the instruction and give the command /start+14b , which puts
the breakpoint in the same place without having to keep track of the size of the
included file.
 
Search WWH ::




Custom Search