The program counter (pc)¶
Program counter and jumps¶
The program is stored in memory, where each instruction takes 1 or 2 field elements (for example, when an immediate value is used in the instruction, it takes 2 field elements, where the second one is the immediate value).
The program counter (pc
) keeps the address of the current instruction.
Usually it advances by 1 or 2 per instruction according to the size of the instruction
(when the current instruction occupies two field elements, the program counter advances by 2 for
the next instruction).
A jmp
instruction may be used to jump to a different instruction.
jmp
is available in three flavors:
Absolute jump: jumps to a given address (by changing the program counter to the given value). For example,
jmp abs 17;
will changepc
to 17.Relative jump: jumps to an offset from the current instruction. For example,
jmp rel 17;
will changepc
topc + 17
. Note thatpc
refers to the value of the program counter of the current instruction. Thus, a special case is the instructionjmp rel 0;
which jumps to itself, thus creating an infinite loop.Jump to a label: this translates to a relative jump where the Cairo compiler is automatically computing the difference between the current instruction and the label. This is the most useful (and readable) jump.
Exercise¶
What does the following code do? (run with --no_end --step=16
to avoid the
End of program was not reached
error)
func main() {
[ap] = 2, ap++;
my_loop:
[ap] = [ap - 1] * [ap - 1], ap++;
[ap] = [ap - 1] + 1, ap++;
jmp my_loop;
}
Bonus exercise¶
What happens in the following code?
(you can start by running it and looking at the memory; note that you will need the
--no_end
flag)
func main() {
[fp + 1] = 2, ap++;
[fp] = 5201798304953761792, ap++;
jmp rel -1;
}
Conditional jumps¶
Another important type of instruction is the conditional jump.
The syntax of the instruction is jmp <label> if [<expr>] != 0;
where <expr>
is either ap + offset
or fp + offset
(offset
may be omitted).
If the corresponding memory cell is not zero,
the Cairo machine will jump to the given label. Otherwise,
it will continue to the next instruction normally.
Instead of using a label, you may also use rel <expr>
in a similar way to
a regular jump (for example jmp rel 17 if [ap - 1] != 0;
).
Exercise¶
Edit the loop my_loop
in the exercise above
so that it starts by writing 10 to [ap]
,
continues by writing the decreasing sequence \(9, 8, 7, \ldots, 0\)
and then returns. Don’t forget the ret
instruction.
Verify that your code works as expected by looking at the memory.