FOR OPERATOR: "E97" BRICKS

Back to:
index Intel
I called bricks the short pieces of code, that "COMPAS" generate as a part of operator. Compiler builds result machine code from the bricks.

As it is clearly seen from logic of the structure, FOR construction consists from two blocks - before cycle body and after it.

Part before cycle body

Step 1 (extract value to begin cycle)

Step 2 (extract value to end cycle)

Step 3 (compare parameter's values and exit if incorrect)

Step 4 (store initial value into cycle variable)

Step 5 (save parameter address and last value)

Part after cycle body

Step 1 (restore parameter address and last value)

Step 2 (compare cycle parameter with end value, exit if equal)

Step 3 (make step)

Step 4 (go to repeat cycle)

And in the end example of full operator FOR


Before cycle: step 1 (extract value to begin cycle)

For this aim "COMPAS" uses standard bricks of assign operator, which extract value to R1.

Then "COMPAS" always moves this initial value into R2 by simple command
0112 R1 ==> R2



Back to:
index top Intel

Before cycle: step 2 (extract value to end cycle)

For this aim "COMPAS" also uses standard bricks of assign operator, which extract value to R1. Now the first value is stored in R2 and the last one - in R1.



Back to:
index top Intel

Before cycle: step 3 (compare parameter's values and exit if incorrect)

To compare the initial value and the last one "COMPAS" generates the following instructions:
TO cycleDOWNTO cycle
0412compare R2 with R1 0421compare R1 with R2
7C0D
{addr}
exit if > 0 7C0D
{addr}
exit if > 0
Instead of {addr} compiler will place the address of the first instruction after cycle.

As you can see from above, in both cases the cycle will be immediately finished if result > 0. Hence cycle with TO will be skipped if the initial value is greater than last one (R2 > R1) and in the opposite case for DOWNTO cycle. So incorrect cycles
FOR i := 10 TO 1 DO and FOR i := 1 DOWNTO 10 DO
will be ignored. This check prevents possible endless cycle.



Back to:
index top Intel

Before cycle: step 4 (store initial value into cycle variable)

This action is realized by the following commands:
01D3
{addr}
{addr} ==> R3 move address of the cycle parameter to R3
0127R2 ==> (R3) move initial value into variable
Instead of {addr} compiler will automatically place the address of the cycle variable.

I want to accent that now the last parameter value is still keeping in R1 and R3 stores the memory address of cycle variable. On the next step they will be saved in the stack.



Back to:
index top Intel

Before cycle: step 5 (save parameter address and last value)

This is the last step before cycle body. Because we know exactly that the cycle contents will change R1 and R3 values, we must save them somewhere. "COMPAS" uses stack for this purpose and always generates here the following code:
0E21R1 ==> stack
0E23R3 ==> stack

So the end parameter value (R1) and variable address (R3) is saved. After execution of the cycle body, these values will be restored by the first step.



Back to:
index top Intel

[here must be the cycle body]


After cycle: step 1 (restore parameter address and last value)

This is the first step after cycle body execution. It restores the parameter address value in R3 register and the end parameter value in R1. Note that the order of reading from stack is always opposite to writing one.
0E33stack ==> R3
0E31stack ==> R1



Back to:
index top Intel

After cycle: step 2 (compare cycle parameter with end value, exit if equal)

To analyze the exit of the cycle, "COMPAS" generate constant code
0471compare R1 with (R3) compare last parameter value with current one
5D06branch if = 0 exit from the cycle when equal
Remember that (R3) points to stored in memory value of the variable, that is cycle parameter. The next instruction skips 6 bytes (3 words), where 2 last steps are placed. So when the current parameter value is identical to the end value, this instruction provides jump out of the cycle. (If no - the cycle continues to work and we go to the next step.)



Back to:
index top Intel

After cycle: step 3 (make step)

The task of this step is to calculate next value for TO cycle and previous for DOWNTO
TODOWNTO
2217(R3) + 1 ==> (R3) inc variable value 2317(R3) - 1 ==> (R3) dec variable value



Back to:
index top Intel

After cycle: step 4 (go to repeat cycle)

This is just an unconditional brunch to repeat the cycle.
1C0D
{addr}
jump to {addr}
It's important to note, that this is jump to
step 5 before cycle, but not to beginning of the cycle body.



Back to:
index top Intel

Example of full operator FOR

Here you can find full results of cycle FOR compilation.

FOR i:=9 DOWNTO 0 DO WRITELN(i);
(DE - address of variable i)
AddrCodeOperationPascal commentsStep
0004 2191
9 ==> R1value to begin cycle step 1
0006 0112 R1 ==> R2initial cycle value to R2 step 2
0008 2101
0 ==> R1value to end cycle (in R1)
000A 0421 compare R1 with R2compare first and last values step 3
000C
000E
7C0D
0038

if > 0, jump to 38 exit if incorrect values
0010
0012
01D3
00DE

DE ==> R3address of cycle variable i step 4
0014 0127 R2 ==> (R3)assign initial value to i
0016 0E21 R1 ==> stacksave last parameter value step 5
0018 0E23 R3 ==> stacksave parameter address
001A
001C
01E1
00DE

(DF) ==> R1variable i value cycle
body
001E
0020
01D3
00E0

E0 ==> R3buffer address for converting
binary to string
0022
0024
9C0D
4068

call 4068call subroutine from ROM
(print integer value)
0026
0028
9C0D
40EC

call 40ECcall subroutine from ROM
(to next display line)
002A 0E33 stack ==> R3restore parameter address step 1
002C 0E31 stack ==> R1restore last parameter value
002E 0471 compare R1 with (R3)compare current value with end one step 2
0030 5D06 branch if = 0 (to 38)exit if equal
0032 2317 (R3) - 1 ==> (R3) parameter step (next number) step 3
0034
0036
1C0D
0016
jump to 16to repeat cycle step 4
0038 CF98 haltstop



Back to:
index top Intel