360 汇编/360 指令/BC
BC - 条件分支 - RX 类型指令 - 操作码 47 / 十进制 71
BC 指令在所有型号的 360、370 和 z/System 上都可用。
- BC 2,LABEL
- BH LABEL - 特殊操作码,与 BC 2,LABEL 相同
- BC 1,L1
- BO L1 - 与 BC 1,L1 相同
- BC 15,106(0,10)
- B 106(0,10) - B 操作码是无条件分支,与 BC 15 相同
- BC 3,256(7,6)
具体的语法是
- BC 掩码,偏移量(索引寄存器,基址寄存器)
如果已使用USING伪指令,并且目标地址标签位于某个基址寄存器值的 4096 字节内,则汇编程序将自动确定偏移量、索引寄存器和基址寄存器的值。
RX 指令(4 字节) | ||||||
字节 1 | 字节 2 | 字节 3 和 4 | ||||
掩码 | 目标地址 | |||||
(8 位) 操作码 47 |
(4 位) 0..F |
(4 位) 索引 寄存器 0..F |
(4 位) 基址 寄存器 0..F |
(12 位) 偏移量 0..FFF |
- 第一个参数是掩码,条件码将与此掩码进行比较。
- 第二个参数是如果掩码与当前设置的条件码匹配则要转移到的位置。偏移量值将添加到基址和索引寄存器中的值以形成目标地址。大多数指令用法倾向于使用一个基址寄存器和一个索引寄存器零,但如果使用两个非零寄存器,则无论哪个寄存器是基址寄存器,哪个是索引寄存器,目标地址都将相同。
- 掩码、基址寄存器和索引寄存器的值为 0 到 15。偏移量值为 0 到 4095。
- 如果掩码或基址寄存器为零,则指令为无操作,不会分支。
- 如果掩码为 15,则分支为无条件(除非基址寄存器为 0,在这种情况下它不会分支)。
- 如果指定的索引寄存器为 0,则不使用索引寄存器中的值。
执行更改条件码的指令后,计算机将设置 PSW 中“条件码”字段中的 CC 标志位。然后,如果所选条件码与该指令中的掩码匹配,则此指令可以分支。例如,假设我们正在使用算术加寄存器“AR”。然后在以下条件下,“条件码”的值将如下所示
条件 | 符号 | PSW 中的条件码 |
---|---|---|
结果为零 | Z | 0 |
结果为负 | N | 1 |
结果为正 | P | 2 |
结果溢出 | O | 3 |
然后考虑指令“BNZ”(非零分支)。它的掩码是 7。这意味着什么?如果结果不为零,此指令将分支,这意味着如果条件码的值不为零,它将分支!所以它是 1、2 或 3。考虑下表
Z | N | P | O |
---|---|---|---|
0 | 1 | 1 | 1 |
上面的例子给了我们掩码 (0111) = 7。对于每个以下操作码,您可以构造表 ZNPO 并找到相应的掩码。
汇编程序将掩码作为几个可选操作码的一部分提供。这些只需要目标地址。这些操作码是
操作码 | 掩码 | 用法 | 目的 | 等价于 | 用法 |
---|---|---|---|---|---|
NOP | 0 | NOP LABEL | 无操作 | BC 0,LABEL | 任何需要无操作/填充的地方 |
BO | 1 | BO LABEL | 溢出/一分支 | BC 1,LABEL | 算术运算或算术比较后,如果发生算术溢出或结果全为一 |
BH | 2 | BH LABEL | 分支(高) | BC 2,LABEL | 任何比较之后,如果比较中的第一个值高于第二个值(A > B),则分支 |
BP | 2 | BP LABEL | 正分支 | BC 2,LABEL | 算术运算或算术比较后,如果结果为正,则分支 |
BL | 4 | BL LABEL | 分支(低) | BC 4,LABEL | 任何比较之后,如果第一个值低于第二个值(A < B),则分支 |
BM | 4 | BM LABEL | 负/混合分支 | BC 4,LABEL | 算术运算或算术比较后,如果结果为负或为一和零,则分支 |
BNE | 7 | BNE LABEL | 不相等分支 | BC 7,LABEL | 任何比较之后,如果第一个值不等于第二个值(A <> B 或 A ~= B 或 A != B),则分支 |
BNZ | 7 | BNZ LABEL | 非零分支 | BC 7,LABEL | 算术运算或算术比较后,如果结果不为零,则分支 |
BE | 8 | BE LABEL | 分支(a 等于 b) | BC 8,LABEL | 任何比较之后,如果第一个值等于第二个值(A = B 或 A == B),则分支 |
BZ | 8 | BZ LABEL | 零分支 | BC 8,LABEL | 算术运算或算术比较后,如果结果为零,则分支 |
BNL | 11 | BNL LABEL | 分支(a 不低) | BC 11,LABEL | 任何比较之后,如果第一个值不低于第二个值(A >= B),则分支 |
BNM | 11 | BNM LABEL | 非负分支 | BC 11,LABEL | 算术运算或算术比较后,如果结果为零,则分支 |
BNH | 13 | BNH LABEL | 非高分支 | BC 13,LABEL | 任何比较之后,如果第一个值不高于第二个值 {A<=B),则分支 |
BNP | 13 | BNP LABEL | 非正分支 | BC 13,LABEL | 算术运算或算术比较后,如果结果不为正,则分支 |
BNO | 14 | BNO LABEL | 非一分支 | BC 14,LABEL | 算术运算或算术比较后,如果结果不是全一,则分支 |
B | 15 | B LABEL | 分支(无条件) | BC 15,LABEL | 在所有情况下分支(除非索引寄存器为 0;否则视为无操作)等价于高级语言中的 GOTO |
对于左侧显示的示例机器代码,假设地址LABEL位于寄存器 10 的偏移量 106(06A 十六进制)处,并且地址 X1 假设位于基址寄存器 6 和索引寄存器 7 的和的偏移量 256(0100 十六进制)处。
47F0A06A B LABEL unconditional branch - equivalent to BC 15,label 47076100 NOP X1 no-operation - BC 0,X1 47FC0006 BC 15,6(12,0) despite the mask being 15, because the base register is 0, * this is also a no-op
4780A06A BE LABEL branch if a equal b - BC 8,label 4720A06A BH LABEL branch if a high - BC 2,label 4740A06A BL LABEL branch if a low - BC 4,label 47776100 BNE X1 branch if a not equal b - BC 7,X1 47D0A06A BNH LABEL branch if a not high - BC 13,label 4740A06A BNL LABEL branch if a not low - BC 4,label
4710A06A BO LABEL branch on overflow - BC 1,label 47276100 BP X1 branch on plus - BC 2,X1 4740A06A BM LABEL branch on minus - BC 4,label 4780A06A BZ LABEL branch on zero - BC 8,label 47D0A06A BNP LABEL branch on not plus - BC 13,label 47B0A06A BNM LABEL branch on not minus - BC 11,label 4770A06A BNZ LABEL branch on not zero - BC 7,label
47176100 BO X1 branch on ones - BC 1,X1 4740A06A BM LABEL branch on mixed - BC 4,label 4780A06A BZ LABEL branch on zeroes - BC 8,label 47E0A06A BNO LABEL branch on not ones - BC 14,label
执行算术运算或比较后,程序状态字中称为条件码的某些位会被设置或清除。在比较两个字段的情况下,左侧值被视为“A”值,右侧值被视为“B”值,并且A与B的比较结果测试A与B的比较方式,可以是低、高、相等或不相等。
在算术运算的情况下,会测试结果是正数、负数、零还是溢出。
在掩码测试指令的情况下,会测试结果是全1、全0还是混合的1和0。
条件分支指令用于在执行此类测试后,将条件码位与掩码值进行比较。如果掩码中设置的位与条件码中设置的位匹配(或掩码中的所有位都被设置),并且目标地址的基本寄存器不为0,则目标地址将被置入PSW作为当前指令的新地址,并执行分支。否则,执行将继续执行条件分支指令之后的下一条指令。
目标地址是通过将基本寄存器和索引寄存器的内容与偏移地址相加来构造的。如果索引寄存器为零,则不使用其值。
“条件分支”指令是程序中通用的分支指令。它有三种变体:无分支或无操作、根据测试进行条件分支或无条件分支。
“无分支” - BC 0 - 或“NOP”通常用于创建不与现有指令绑定的标签。宏可以使用它进行对齐,以强制将指令或数据放到特定的边界上,但在分支到该指令时不会导致程序异常。它还可以用于提供“空闲”空间,以便以后在不重新组装程序的情况下进行二进制补丁。如果分支的基本寄存器也为零,则无论掩码值如何,也会发生NOP。
掩码中的位与条件码中的位进行比较。如果掩码中的位与条件码中的位匹配(并且目标地址的基本寄存器不为零),则执行分支。
通过设置掩码中的所有位(例如BC 15)或使用B指令来执行到另一个位置的分支(相当于高级语言中的GOTO)。只要目标地址的基本寄存器不为零,分支将始终被执行。
条件分支和可选格式通常用于执行比较或算术运算之后。在以下代码中,会提出一个问题,将响应与是或否进行比较,如果都不是,则重新发出问题。“CALL”宏用于创建标准的子程序链接。
CHECKINQ NOP 0(0) CALL INQUIRE,(QUES,1,RESP) Call an external module called INQUIRE CLC RESP(1),QY1 Compare one byte BE YES "Resp" is the A value in an A:B comparison CLC RESP(1),QY2 BE YES CLC RESP(1),QN1 BE NO Answer was 'N' CLC RESP(1),QN2 Is it 'n'? BNE CHECKINQ Something else, try again B NO Answer was 'n' QUES DC C'Are you ready to start?' Construct a 'C' language-type DC X'00' string, zero terminated RESP DS C One byte response QY1 DC C'Y' Available responses QY2 DC C'y' QN1 DC C'N' QN2 DC C'n'
- 分支寄存器中包含的目标地址不能为奇数,否则会发生操作异常。
- 分支寄存器中包含的目标地址必须在有效内存范围内,否则会发生操作异常。
- 目标地址的存储密钥必须与当前进程相同(或此进程的密钥必须为0),否则会发生内存保护冲突异常。
- BALR指令用于分支到寄存器中的地址,并将当前地址保存为返回地址,类似于高级语言中的过程或函数调用。
- BCR指令的使用方式与BC指令相同,但用于分支到指定的第二个参数寄存器中的地址。
- BCT指令用于从寄存器中减去1,然后如果结果不为零,则分支到指定的地址。
- BCTR指令用于从寄存器中减去1,然后如果结果不为零,则分支到第二个参数中指定的寄存器中的地址。
- BRC指令用于分支到相对于当前程序计数器的地址,该地址包含在立即数(16位)值中。
- BRCL指令用于分支到相对于当前程序计数器的地址,该地址包含在立即数(32位)值中。
上一条指令 BASSM |
360汇编指令 | 下一条指令 BCR |
上一操作码 46 |
下一操作码 48 |