8051模拟器汇编入门(3)标签和跳转

由于程序计数器(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(设置进位,退出循环)

图片

运行结果