跳转到内容

360 汇编/360 指令/BCR

来自维基教科书,自由的教科书

BCR — 按条件寄存器分支 — 操作码 07 / 十进制 7 — 2 字节 RR 指令。


BCR mask_value,branch_register(两个值都为 0 到 15)
BCR 6,1


RR 指令(2 字节)
字节 1
位 (0-7)
字节 2
掩码值
(8-11)
分支寄存器
(12-15)
(以十六进制表示) 操作码
07
(4 位)
0..F / (十进制 0..15)
(4 位)
0..F / (十进制 0..15)
  • 第一个参数是一个掩码,它与条件码进行比较。
  • 第二个参数是源寄存器,其内容将用作目标地址,如果掩码与当前设置的条件码匹配。
  • 掩码值基址寄存器的值为 0 到 15。


可用性

[编辑源代码]

BCR 指令在所有型号上均可用,包括 360、370 和 z/System。


此指令提供三种类型的分支操作:无分支(相当于无操作)、根据掩码值进行条件分支和无条件分支。

 BCR   0,0  No branch

注意:由于可能难以理解掩码值和寄存器值之间的区别,为了区分掩码值和寄存器,寄存器将用“R”加上寄存器号来引用,例如 R5 表示寄存器 5,R6 表示寄存器 6,R14 表示寄存器 14 等等。

 BCR   2,R5
 BHR   R6 - Special opcode: Branch if High Register, same as BCR 2,R6
 BCR   1,R1
 BOR   R1 - Same as BC 1,R1
 BCR   15,R10
 BR    R10  - BR opcode is unconditional branch
              and is same as BCR 15,R10
 BCR   3,R6
  • 如果掩码基址寄存器为零,则该指令为无操作,不会进行分支。
  • 如果掩码为 15,则分支为无条件分支(除非基址寄存器为 0,在这种情况下,它不会进行分支)。所以在这两种情况下
 BCR   X,0
 BCR   0,X

其中 X 为 0 到 15 之间的任意值,分支不会执行。

执行执行算术、测试或比较操作的指令后,处理器会设置 PSW 寄存器中的“条件码”标志(位 18 和 19),允许检查条件码以确定潜在的分支。例如,假设我们正在使用一个算术指令,例如称为“AR”的算术加法指令。然后,在以下条件下,“条件码”的值将如下所示

条件 符号 PSW 中的条件码
结果为零 Z 0
结果为负 N 1
结果为正 P 2
结果溢出 O 3

然后以指令“BNZR”为例。它的掩码为 7。这是什么意思?此指令在结果不为零时进行分支,这意味着如果条件码的值不为零,则进行分支。所以它为 1、2 或 3。请考虑下表

Z N P O
0 1 1 1

上面的示例给了我们掩码 (0111) = 7。对于以下每个操作码,您可以构建表 ZNPO 并找到相应的掩码。

其他操作码

[编辑 | 编辑源代码]

汇编程序将掩码作为几个可选操作码的一部分提供。这些操作码只需要基址寄存器,该寄存器包含要跳转到的目标地址。操作码如下所示

操作码 掩码 用法 用途 相当于 在之后使用
NOPR 0 NOPR  R6 无操作 BCR   0,R6 在需要无操作/填充的任何地方。寄存器中包含的值被忽略。
BOR 1 BOR   R6 溢出/全 1 分支 BCR   1,R6 在算术运算或算术比较之后,如果发生算术溢出或结果全为 1
BHR 2 BHR   R6 分支(a 高) BCR   2,R6 在任何比较之后,如果比较中的第一个值高于第二个值(A > B),则进行分支
BPR 2 BPR   R6 正分支 BC    2,R6 在算术运算或算术比较之后,如果结果为正,则进行分支
BLR 4 BLR   R6 分支(a 低) BCR   4,R6 在任何比较之后,如果第一个值低于第二个值(A < B),则进行分支
BMR 4 BMR   R6 负/混合分支 BCR   4,R6 在算术运算或算术比较之后,如果结果为负或为 1 和 0 的混合,则进行分支
BNER 7 BNER  R6 不相等分支 BCR   7,R6 在任何比较之后,如果第一个值不等于第二个值(A <> BA ~= BA != B),则进行分支
BNZR 7 BNZR  R6 非零分支 BCR   7,R6 在算术运算或算术比较之后,如果结果不为零,则进行分支
BER 8 BER   R6 分支(a 等于 b) BCR   8,R6 在任何比较之后,如果第一个值等于第二个值(A = BA == B),则进行分支
BZR 8 BZR   R6 零分支 BCR   8,R6 在算术运算或算术比较之后,如果结果为零,则进行分支
BNLR 11 BNLR  R6 分支(a 不低) BCR   11,R6 在任何比较之后,如果第一个值不低于第二个值(A >= B),则进行分支
BNMR 11 BNMR  R6 非负分支 BCR   11,R6 在算术运算或算术比较之后,如果结果为零,则进行分支
BNHR 13 BNHR  R6 非高分支 BCR   13,R6 在任何比较之后,如果第一个值不高于第二个值 {A<=B),则进行分支
BNPR 13 BNPR  R6 非正分支 BCR   13,R6 在算术运算或算术比较之后,如果结果不为正,则进行分支
BNOR 14 BNOR  R6 非全 1 分支 BCR   14,R6 在算术运算或算术比较之后,如果结果不全为 1,则进行分支
BR 15 BR    R6 分支(无条件) BCR   15,R6 在所有情况下都进行分支(除非索引寄存器为 0;否则视为无操作)相当于高级语言中的 GOTO

可选格式

[编辑 | 编辑源代码]

掩码值被忽略

[编辑 | 编辑源代码]
07FE            BR    14     unconditional branch -  equivalent to BCR 15,14
0705            NOP   5      no-operation - BCR 0,5
07F0            BCR   15,0   despite the mask being 15, because the base register is 0,
         *                   this is also a no-op 

在 a 和 b 的标准比较之后使用

[编辑 | 编辑源代码]
0785            BER   5      branch if a equal b - BCR 8,5
0725            BHR   5      branch if a high - BCR 2,5
0745            BLR   5      branch if a low - BCR 4,5
0775            BNER  5      branch if a not equal b - BCR 7,5
07D5            BNHR  5      branch if a not high - BCR 13,5
0745            BNLR  5      branch if a not low - BCR 4,5

在算术运算之后使用

[编辑 | 编辑源代码]
0715            BOR   5      branch on overflow - BCR 1,label
0727            BPR   7      branch on plus - BCR 2,7
0745            BMR   5      branch on minus - BCR 4,5
0785            BZR   5      branch on zero - BCR 8,5
07E5            BNOR  5      branch on not ones - BCR 14,5
07D5            BNPR  5      branch on not plus - BCR 13,5
07B5            BNMR  5      branch on not minus - BCR 11,5
0775            BNZR  5      branch on not zero - BCR 7,5

在“按掩码测试”指令之后使用

[编辑 | 编辑源代码]
4717            BOR   7      branch on ones - BCR 1,7
474F            BMR   15     branch on mixed - BCR 4,15
478E            BZ    14     branch on zeroes - BCR 8,14
47E5            BNO   5      branch on not ones - BCR 14,5

可用性

[编辑 | 编辑源代码]

BCR 指令在所有型号的 360、370 和 z/System 上均可用。

执行算术运算或比较时,程序状态字中称为条件码的某些位会被设置或清除。在比较两个字段的情况下,左侧值被视为“A”值,右侧值被视为“B”值,而 A 与 B 的比较结果测试 A 如何与 B 比较,是低、高、相等还是不相等。

在进行算术运算时,会测试结果是否为正、负、零或发生溢出。

在进行带掩码指令的测试时,会测试结果是否全部为 1、全部为 0 或混合 1 和 0。

无条件跳转指令 (BCR 15, base_register) 等同于高级语言中的 **return** 语句或其他从过程或函数退出到调用过程或程序的语句。

根据条件寄存器跳转 指令用于在进行上述测试后比较条件码位和掩码值。如果掩码中设置的位与条件码中设置的位匹配(或掩码中的所有位都被设置),并且目标地址的基址寄存器不为 0,则目标地址基址寄存器中的目标地址将被置入 PSW 中,作为当前指令的新地址,并执行跳转。否则,将继续执行跳转条件寄存器指令后的下一条指令。

通常,根据条件寄存器跳转 指令最常用于模块间传输或从一个 CSECT 跳转到另一个 CSECT。如果在同一个模块或 CSECT 内使用条件跳转,则通常使用 根据条件跳转 ( BC ) 指令(或可选格式 BE、BNE 等)。

指令目的

[编辑 | 编辑源代码]

根据条件寄存器跳转 指令用于在程序中跳转。它有三种变体:不跳转或无操作、根据测试结果进行条件跳转或无条件跳转。

无操作

[编辑 | 编辑源代码]

不跳转 - BCR 0 - 或 NOPR 通常用于创建未绑定到现有指令的标签。宏可以使用它进行对齐,以强制指令或数据位于特定边界上,但如果跳转到该指令,不会导致程序异常。它还可以用于提供“空闲”空间,以便在不重新汇编程序的情况下允许稍后对二进制文件进行修补。无论掩码值如何,如果跳转的基址寄存器为零,也会出现 NOPR。

条件跳转

[编辑 | 编辑源代码]

条件跳转 中,掩码中的位与条件码中的位进行比较。如果掩码中的位与条件码中的位匹配(并且目标地址的基址寄存器不为零),则执行跳转。

无条件跳转

[编辑 | 编辑源代码]

通过设置掩码中的所有位,例如 BCR 15,或使用 BR 指令,可以执行跳转到另一个位置(等同于高级语言中的 GOTO,或者如果在过程或子例程中使用则等同于 RETURN)。只要基址寄存器不为零,跳转就会始终执行;如果基址寄存器为零,则跳转不会执行。

典型用法

[编辑 | 编辑源代码]

根据条件寄存器跳转指令及其可选格式通常用于执行比较或算术运算后。在以下代码中,会提出一个问题,将响应与“yes”或“no”进行比较,如果响应不是两者之一,则会重新提出问题。'CALL' 宏用于创建标准子例程链接。在本示例中,内部处理“no”响应(在标签 NO 处),而“yes”响应会将控制权转移到另一个例程(称为 YES)。

CHECKINQ NOP  0(0)  
* Optionally, the instruction 'CHECKINQ EQU *' could have been used. This would have
* generated no instructions.           
         BALR 3,0                             Come back here if neither Y nor N
* optionally, the instruction LA 3,CHECKINQ  could have been used.    :
         USING *,3                             Let Assembler ue R3 for local addresses
         L    4,YESRTN                         Place to go for Yes response
         LA   5,NO                             Place to go for No response
         CALL INQUIRE,(QUES,1,RESP)            Call an external module called INQUIRE 
         CLC  RESP(1),QY1                      Compare one byte for 'Y'
         BER  4                                "Resp" is the A value in an A:B comparison 
         CLC  RESP(1),QY2                      Now test (length 1) for 'y'
         BER  4 
         CLC  RESP(L'QN1),QN1                  Test 'N' (L' tells the assembler to use
*                                              the specied length of the named label)
         BER  5                                Answer was 'N'
         CLC  RESP(1),QN2                      Is it 'n'?
         BNER 3                                Something else, try again
         BR   5                                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'
YESRTN   DC   V(YES)                           External module YES
*
* This will handle a 'no' answer
==Typical Usage==

根据条件寄存器跳转指令及其可选格式通常用于执行比较或算术运算后。在以下代码中,会提出一个问题,将响应与“yes”或“no”进行比较,如果响应不是两者之一,则会重新提出问题。'CALL' 宏用于创建标准子例程链接。在本示例中,内部处理“no”响应(在标签 NO 处),而“yes”响应会将控制权转移到另一个例程(称为 YES)。

CHECKINQ NOP  0(0)  
* Optionally, the instruction 'CHECKINQ EQU *' could have been used. This would have
* generated no instructions.           
         BALR 3,0                             Come back here if neither Y nor N
* optionally, the instruction LA 3,CHECKINQ  could have been used.    :
         USING *,3                             Let Assembler ue R3 for local addresses
         L    4,YESRTN                         Place to go for Yes response
         LA   5,NO                             Place to go for No response
         CALL INQUIRE,(QUES,1,RESP)            Call an external module called INQUIRE 
         CLC  RESP(1),QY1                      Compare one byte for 'Y'
         BER  4                                "Resp" is the A value in an A:B comparison 
         CLC  RESP(1),QY2                      Now test (length 1) for 'y'
         BER  4 
         CLC  RESP(L'QN1),QN1                  Test 'N' (L' tells the assembler to use
*                                              the specied length of
         BER  5                                Answer was 'N'
         CLC  RESP(1),QN2                      Is it 'n'?
         BNER 3                                Something else, try again
         BR   5                                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'
YESRTN   DC   V(YES)                           External module YES
*
* This will handle a 'no' answer
         DROP 3                                Tell assembler Reg. 3 is no
*                                              longer available for addressing                                     
NO       NOP  0(0)                             Handle a no

异常和错误

[编辑 | 编辑源代码]
  • 基址寄存器中包含的目标地址不能是奇数,否则会发生操作异常。
  • 基址寄存器中包含的目标地址必须在有效内存范围内,否则会发生操作异常。
  • 基址寄存器中包含的目标地址的存储密钥必须与当前进程相同(或该进程的密钥必须为 0),否则会发生内存保护违规异常。

替代跳转指令

[编辑 | 编辑源代码]
  • BALR 指令用于跳转到寄存器中的地址,并将当前地址保存为返回地址,类似于高级语言中的过程或函数调用。
  • BC 指令的使用方式与 BCR 指令相同,但用于跳转到寄存器中包含的地址加上一个可能的索引寄存器和一个 12 位位移量,而不是寄存器中包含的地址。
  • BCTBCTR 指令用于递减第一个参数(一个寄存器)中的值,将结果存储回该寄存器,然后跳转到寄存器中的地址(对于 BCTR 指令),或者跳转到寄存器中包含的地址加上一个可能的索引寄存器和一个 12 位位移量,如果第一个参数寄存器中的结果值不为零。
  • BRC 指令的使用方式与 BCR 指令相同,但用于跳转到相对于当前程序计数器的地址,该地址包含在一个立即数(16 位)中。
  • BRCL 指令的使用方式与 BCR 指令相同,但用于跳转到相对于当前程序计数器的地址,该地址包含在一个立即数(32 位)中。
上一条指令
BC
360 汇编指令   下一条指令
BCT
上一个操作码
06
下一个操作码
08
360 汇编语言
360 系列 简介 · 基本常见问题解答 · 360 系列 · 360 架构
360 指令集 360 指令 · 跳转指令 · 数据传输指令 · 控制流指令 · 算术指令 · 逻辑指令 · 移位和旋转指令 · 特权指令 · 其他指令
语法和汇编器 360 汇编器 · 伪指令
指令扩展 浮点数 · 高级语言


华夏公益教科书