• No results found

A Cintsys Console Session

When the Cintsys system is started (on a machine called c223) in the directory bcplprogs/demo, its opening message is as follows:

c223$ cintsys

BCPL Cintcode System (30 Sept 2010) 0.000>

The characters 0.000> are followed by a space character and is the command language prompt string inviting the user to type a command. The number gives the execution time in seconds of the preceeding command. A program called fact.b in directory com to compute factorials can be displayed using the type command as follows:

0.000> type com/fact.b GET "libhdr"

LET start() = VALOF

{ FOR i = 1 TO 5 DO writef("fact(%n) = %i4*n", i, fact(i)) RESULTIS 0

}

AND fact(n) = n=0 -> 1, n*fact(n-1) 0.000>

The directive GET "libhdr" causes the standard library declarations to be inserted at that position. The text:

1

LET start() = VALOF

is the heading for the declaration of the function start which, by convention, is the first function to be called when a program is run. The empty parentheses () indicate that the routine expects no arguments. The text

FOR i = 1 TO 5 DO

introduces a for-loop whose control variable i successively takes the values from 1 to 5. The body of the for-loop is a call of the library function writef whose effect is to output the format string after replacing the substitution items %n and %i4 by appropriately formatted representations of i and fact(i). Within the string *n represents the newline character. The statement RESULTIS 0 exits from the VALOF construct providing the result of start that indicates the program completed successfully. The text:

AND fact(n) =

introduces the definition of the function fact which take one argument (n) and yields n factorial. The word AND causes fact to available to the previously defined function. This program can be compiled by using the following command:

0.000> bcpl com/fact.b to fact BCPL (5 Oct 2010)

Code size = 104 bytes 0.030>

This command compiles the source file fact.b creating an executable object module in the file called fact. The program can then be run by simply typing the name of this file.

0.030> fact fact(1) = 1 fact(2) = 2 fact(3) = 6 fact(4) = 24 fact(5) = 120 0.000>

When the BCPL compiler is invoked, it can be given additional arguments that control the compiler options. One of these (d1) directs the compiler to output the compiled code in a readable form, as follows:

10> bcpl com/fact.b to fact d1 BCPL (5 Oct 2010)

0: DATAW 0x00000000 4: DATAW 0x0000DFDF

1.1. A CINTSYS CONSOLE SESSION 3

This output shows the sequence of Cintcode instructions compiled for the both functions start and fact. In addition to these instructions, there are some data words holding the string constant, initialisation data and symbolic information for

the debugger. The data word at location 4 holds a special bit pattern indicating the presence of a function name placed just before the entry point. As can be seen the name in this case is start. Similar information is packed at location 60 for the function fact. Most Cintcode instructions occupy one byte and perform simple operations on the registers and memory of the Cintcode machine. For instance, the first two instructions of start (L1 and SP3 at locations 20 and 21) load the constant 1 into the Cintcode A register and then stores it at word 3 of the current stack frame (pointed to by P). This corresponds to the initialisation of the for-loop control variable i. The start of the for-loop body has label L4 corresponding to location 22. The compilation of fact(i) is LP3 LF L2 K9 which loads i and the entry address of fact and enters the function incrementing P by 9 locations). The result of this function is returned in A which is stored in the stack using SP9 in the appropriate position for the third argument of the call of writef.

The second argument, i, is setup using LP3 SP8, and the first argument which is the format string is loaded by LLL L9920. The next instruction (K4G 94) causes the routine writef, whose entry point is in global variable 94, to be called incrementing P by 4 words as it does so. Thus the compilation of the call writef("fact(%n) = %i5*n", i, f(i))occupies just 11 bytes from location 22 to 32, plus the 16 bytes at location 44 where the string is packed. The next three instructions (L1 AP3 SP3) increment i, and L5 JNE L4 jumps to label L4 if i is still less than 5. If the jump is not taken, control falls through to the instructions L0 RTN causing start to return with result 0. Each instruction of this function occupies one byte except for the LF, LLL, K4G and JNE instructions which each occupy two. The body of the function fact is equally easy to understand. It first tests whether its argument is zero (JNE0 L5). If it is, it returns one (L1 RTN).

Otherwise, it computes n-1 by loading -1 and adding n (LM1 AP3) before calling fact (LF L2 K4). The result is then multiplied by n (LP3 MUL) and returning (RTN). The space occupied by this code is just 12 bytes.

The debugger can be entered using the abort command.

0.030> abort

!! ABORT 99: User requested

*

The asterisk is the prompt inviting the user to enter a debugging command. The debugger provides facilities for inspecting and changing memory as well as setting breakpoints and performing single step execution. As an example, a breakpoint is placed at the first instruction of the routine clihook which is used by the command language interpreter (CLI) to transfer control to a command. Consider the following commands:

* g4 b1

* b

1: clihook

*

1.1. A CINTSYS CONSOLE SESSION 5

This first loads the entry point of clihook (held in global variable 4) and sets (b1) a breakpoint numbered 1 at this position. The command b, without an argument, lists the current breakpoints confirming that the correct one has been set. Normal execution is continued using the c command.

* c 0.010>

If we now try to execute the factorial program, we immediately hit the break-point.

0> fact

!! BPT 1: clihook

A= 0 B= 0 17940: K4G 1

*

This indicates that the breakpoint occurred when the Cintcode registers A and B were both zero, and that the program counter is set to 17940 where the next instruction to be obeyed is K4G 1. Single step exection can now be performed using the \ command.

* \ A= 0 B= 0 46276: L1

* \ A= 1 B= 0 46277: SP3

* \ A= 1 B= 0 46278: LP3

*

After each single step execution a summary of the current state is printed. In the above sequence we see that the execution of the instruction L1 loading 1 into the A register. The execution of SP3 does not have an immediately observable effect since it updates a local variable held in the current stack frame, but the stack frame can be displayed using the t command.

* p t4

P 0: 46420 17942 start 1

*

This confirms that location P3 contains the value 1 corresponding to the initial value of the for-loop control variable i. At this stage it is possible to change its value to 3, say.

* 3 sp3

* p t4

P 0: 46420 17942 start 3

*

If single stepping is continued for a while we observe the evaluation of the recursive call fact(3).

* \ A= 3 B= 1 46279: LF 46332

At this moment the routine writef is just about to be entered to print an message about factorial 3. We can unset breakpoint 1 and continue normal execution by typing 0b1 c.

As one final example in this session we will re-compile the BCPL compiler.

0.010> bcpl com/bcpl.b to junk BCPL (5 Oct 2010)

Code size = 22076 bytes Code size = 12500 bytes 0.280>