由于程序计数器(PC)寄存器用于确定下一条指令的位置,它不能像其他寄存器那样被访问——即不能使用MOV指令。相反,PC有自己特殊的一组指令。我们称这些为“跳转”,因为它们实际上对应于从一条指令跳转到另一条指令。其中最基本的是JMP指令。

模拟器中的程序计数器PC
在汇编中执行跳转时,应该对跳转的目标位置进行标记。标签可以是任何名称,包括字母、数字和下划线等,以冒号结束。例如,“L0:”、“MY_LABEL:”和“TOE_NAILS42:”都是有效标签的例子。要跳转到一个标签,使用JMP指令。
MOV A, #1
MOV R0, #2
JMP THIS_IS_A_LABEL
MOV R0, #3
THIS_IS_A_LABEL:
ADD A, R0
在上述代码中,立即值1和2分别被移动到A和R0中。然后JMP指令将程序移动到标签定义的位置,有效地跳过第三个MOV指令,然后添加A和R0。还要注意,虽然不是必需的,但习惯上会在标签后的代码进行缩进。

另一对跳转指令是JZ(Jump Zero)和JNZ(Jump If Not Zero)。这些被称为条件跳转,因为只有在某些条件为真时才会发生。特别是,JZ只有在累加器中的值为零时才跳转,而JNZ只有在累加器中的值不为零时才跳转(因此是N)。这些指令的语法与JMP相同。
练习5:
将A初始化为250。增加A的值。当A不为0时,返回初始化后的位置。使用JNZ指令。
MOV A, #250 ; Initialize A to 250 (0xFA)
AGAIN: ; Label for the loop
INC A ; Increment A
JNZ AGAIN ; If A is not zero, jump back to AGAIN
让我们一步一步看看发生了什么:
A = 250 (0xFA)
第一次循环:INC A:250 → 251 (0xFB),不为零,因此跳回。
第二次循环:INC A:251 → 252 (0xFC),不为零,因此跳回。
…依此类推,直到:
INC A:255 → 0
A 为零,因此退出循环
循环将迭代 6 次:
250 → 251
251 → 252
252 → 253
253 → 254
254 → 255
255 → 0(然后退出)
当 A 从 255 滚动到 0 时,JNZ 不会跳转,因为 A=0。
另一对跳转指令是JC和JNC。这些也是条件跳转。JC只有在进位标志被设置时才跳转,而JNC只有在进位标志未被设置时才跳转。这些指令的语法也与JMP相同。
练习6:
将A初始化为250,给A加上2,当进位标志未被设置时,返回初始化后的位置,使用JNC指令。
MOV A, #250 ; Initialize A to 250 (0xFA)
AGAIN: ; Label for the loop
ADD A, #02 ; Add 2 to A
JNC AGAIN ; If no carry (C=0), jump back to AGAIN
让我们一步一步看看发生了什么:
A = 250 (0xFA)
第一次循环:
ADD A, #02: 250 + 2 = 252 (0xFC),无进位,因此跳回。
第二次循环:
ADD A, #02: 252 + 2 = 254 (0xFE),无进位,因此跳回。
第三次循环:
ADD A, #02: 254 + 2 = 256
这超过了 255,因此:A 包含 0(环绕),进位标志已设置,JNC 不跳转(退出循环)。
循环运行 3 次:
250 → 252(无进位)
252 → 254(无进位)
254 → 0(设置进位,退出循环)

运行结果