程序计数器和跳转
程序存放在内存中,每条指令取1或2个域元素(例如,当指令中使用立即数时,它需要 2 个域元素,其中第二个是立即数)。
程序计数器 (pc) 保存当前指令的地址。通常它根据指令的大小每条指令前进 1 或 2(当当前指令占用两个域元素时,程序计数器为下一条指令递增2)。
jmp
指令可用于跳转到不同的指令。 jmp 提供三种版本:
- 绝对跳转:跳转到给定地址(通过将程序计数器更改为给定值)。例如,
jmp abs 17
会将pc
更改为17
。 - 相对跳转:跳转到当前指令的偏移量处。例如,
jmp rel 17
会将pc
更改为pc + 17
。请注意,pc 指的是当前指令的程序计数器的值。因此,一个特例是指令jmp rel 0
它跳转到自身,从而创建一个无限循环。 - 跳转到标签:这转化为相对跳转,Cairo 编译器自动计算当前指令和标签之间的差异。这是最有用(和可读)的跳转。
条件跳转
另一种重要的指令类型是条件跳转。该指令的语法是 jmp <label> if [<expr>] != 0
;其中 <expr>
是 ap + offset
或 fp + offset
(可以省略 offset
)。如果对应的内存单元不为零,Cairo将跳转到给定的标签。否则,它将正常继续执行下一条指令。除了使用标签,您还可以使用与常规跳转类似的方式使用 rel <expr>
(例如 jmp rel 17 if [ap - 1] != 0;
)。
练习
原文连接:https://www.cairo-lang.org/docs/how_cairo_works/program_counter.html#program-counter-and-jumps