跳转到内容

360 汇编/分支指令

来自维基教科书,开放世界中的开放书籍

360 系列大型机计算机的分支指令分为两种类型:提供返回地址的分支指令(如子程序调用)和不提供返回地址的单向分支指令。

所有分支指令都采用 3 种形式:完全不分支,也称为无操作或 NO-OP,条件分支和无条件分支。

在下面的示例中,假设 R0、R1、R14、R15 是分别等于这些示例中等效寄存器(0、1、14 和 15)的标签,以提供交叉引用列表。示例在没有 **R** 前缀的情况下也能正常运行,但程序员通常使用等于每个数字的标签,因为对寄存器的引用不会出现在交叉引用列表中,而对符号的引用则会。

提供返回地址的分支

[编辑 | 编辑源代码]

以下指令提供指向另一个地址的分支,其中提供一个寄存器来存储分支后一条指令的地址,以提供返回调用点的机制。

以下指令适用于 360 系列的所有型号:360、370、390、390/ESA 和 z/System。
* BAL - 分支并链接 * BALR - 分支并链接寄存器
以下指令仅在 370 及更高版本上可用:370、390、390/ESA 和 z/System。
* BAS - 分支并保存 * BASR - 分支并保存寄存器

无返回分支

[编辑 | 编辑源代码]

以下指令适用于 360 系列的所有型号,包括 360、370、390 和 z/System。

* BC - 根据条件分支[1] * BCR - 根据条件寄存器分支[1] * BCT - 根据计数分支 * BCTR - 根据计数寄存器分支

[1] 扩展助记符提供条件测试,包括 BR 和 B 用于无条件分支;BNO、BE、BNE、BH、BL 和 BM 等

这些指令的一般使用方法解释如下。

无分支

[编辑 | 编辑源代码]

某些类型的分支指令被视为无分支或无操作(NO-OP)。通常它们涉及使用寄存器 0 或掩码值为 0。这些是

  • 目标寄存器为寄存器 0 的寄存器分支
  • 寄存器到存储器分支(无论掩码如何),其中索引寄存器为 0
  • 掩码为 0 的寄存器到存储器分支
Label1    BR    R0            No branch
          BC    0,Label1      Branch not taken; mask is 0
          BALR  R14,R0        Branch not taken; this is used at the start of a 
*                             CSECT/START module to load the left register with the 
*                             address of the next instruction to establish addressing
          BC   15,100(R1,R0)  Because R0 is the Index Register, the branch is not taken
*                             even though the mask indicates an unconditional branch
          BCT  R1,16(R0)      Subtract 1 from the contents of R1, but since the base 
*                             register of the branch address is 0, no branch will occur
          BCTR R1,R0          Subtract 1 from the contents of R1, but since the target
*                             branch register is 0, do not branch

无条件分支

[编辑 | 编辑源代码]

无条件分支指令会导致程序位置计数器 (PSW) 设置为寄存器中指定的地址,或寄存器加上 12 位偏移量,或寄存器和偏移量加上额外的“索引”寄存器的值。

如果 BR 指令使用寄存器 0,则分支不会发生,并且被视为无操作。如果 BALR 指令中的右寄存器为 0,则分支不会发生,并且被视为将下一条指令的地址加载到左寄存器中的指令。如果索引寄存器为 0,则不会发生任何条件分支 - 包括无条件分支。

这些指令可能属于以下类型之一:-

  • 寄存器到寄存器 (RR)
Example1  BR    R15              Branch to the location whose address is in Register 15
Example2  BR    R0               No Branch - Acts like no-op
Example3  BALR  R14,R15          Branch to the location whose address is in Register 15, put
*                                return address in R14
Example4  BALR  R12,R0           Load Register 12 with the address of the next instruction, 
*                                but do not branch
  • 存储器 (RS)
Example1  B     4(R15)           Branch to the location in R15 plus the (12 bit)
*                                    decimal displacement of 4
Example2  B     X'010'(R15)      Branch to the location in R15 plus the (12 bit) hex
*                                displacement of decimal 16
Example3   B     LABEL1           Branch to the location with the specified address (Base & 
*                                displacement set by the Assembler)
Example4   BAL   R14,X'010'(R15)  Branch to location in (R15 plus displacement), put 
*                                return address in R14.
LABEL1   EQU   *               A location (within the range of the base register
*                              for the program) 
*          B     106(R0)          Do not branch; treat as NO-OP
  • 索引 (RX)
Example1   B     4(R15,R1)        Branch to location whose address is calculated from R15
*                                 plus 4 plus R1
Example2   B     10(R12,R0)       No branch because index register is 0; treated as NO-OP
Example3   B     10(R0,R12)       This is standard, and will branch to the address at the 
*                                 location in Register 12 + a displacement of 10

条件分支

[编辑 | 编辑源代码]

条件分支指令会导致 PSW 中的位置计数器设置到寄存器中指定的地址,或寄存器加上 12 位偏移量,前提是满足条件(并且寄存器不为 0)。有两种类型,掩码条件和索引条件。

条件分支可能属于以下类型之一:-

  • 掩码条件,存储器 (RS)
Example   BE     4(R15)          Branch to the location in (R15 plus 4), if previous 
*                                comparison gave "Equal" condition (8)
Example   BE     12(R0)          As specified earlier, branch on R0 is treated as a NO-OP
*                                and does not branch
Example   BC     8,4(R15)        Branch to the location in (R15 plus 4), if previous 
*                                comparison gave "Equal" condition (8)
*                                (same as above but specifying actual condition code 
*                                 value = 8)
Example   BC     7,X'010'(R15)   Branch to the location in (R15 plus X'010') if previous
*                                comparison gave "Unequal" (Branch Not Equal) condition (7)
  • 索引条件,存储器 (RX)
Example   BCT   R1,4(R15)        Reduce value in R1 by 1 and, if it is not zero, branch
*                                to location in (R15 plus 4 )
Example   BCT   R1,12(R0)        The register is reduced by 1, but the branch will never occur
  • 索引条件,寄存器 (RR)
Example   BCTR   R1,R15          Reduce value in R1 by 1 and, if it is not zero, branch
*                                to address in R15
Example   BCTR   R1,R0           Reduce R1 by 1 but do not branch.  This instruction is often
*                                used to subtract 1 from a register

分支表(技术)

[编辑 | 编辑源代码]

分支表实际上是一组连续的无条件分支指令,它们长度相同(通常为 4 字节),用于使用索引非常有效地直接分支到这组指令中的一个。该索引通常从一些源输入值生成,该值本身可能是非顺序的,如下面的示例所示。该方法比使用二分搜索或顺序表查找快得多。查找涉及比较指令和随后的条件分支。在示例中只使用了 5 条指令(其中 2 条是条件分支),它们执行以下操作:-

  • 1. 验证输入(将除 A、S、M、D 以外的任何输入值转换为空索引值)
  • 2. 使用索引转换输入值(使用插入字符 (IC) 指令)转换为 0、4、8、12 或 16(索引)。该技术的早期版本使用了 (TR) 和 (IC) 指令,速度比使用两个 (IC) 指令慢 4 到 5 倍。
  • 3. 使用索引无条件地分支到适当的无条件分支指令 - 零值会导致分支到错误例程。(无条件分支不依赖于之前的字符或数字比较指令)
示例 考虑一个范围为 A-Z 的单个字节字符的输入变量,其中特定值(如 A、S、M、D)决定程序中的处理逻辑。在本例中,A=加法、S=减法、M=乘法和 D=除法。

在以下两个示例中,执行有效性并转到适当标签的时间是固定的,与不同有效单字节输入字符的数量无关。

使用分支指令表的示例

[编辑 | 编辑源代码]
             SR    R15,R15             Clear index register to zero  (32 bits)
             IC    R15,INPUT           Insert input byte into low order bits of R15
*                                      (bits 24-31 forming X'000000C1' for "A")
             IC    R15,TABLE2(R15)     Use R15 as Index to extract a 0,4,8,12 or 16 from 
*                                       the 2nd Table
             B     TABLE1(R15)         Branch using the index now in R15
TABLE1       EQU   *                ---Start of Branch table--- (each branch instruction
*                                       is 4 bytes long and unconditional)
             B     ERROR               00 = Invalid input value         (that is, any byte 
*                                                                        not = A,S,M or D)
             B     ADD                 04 = Input value was "A"
             B     SUBTRACT            08 = Input value was "S"
             B     MULTIPLY            12 = Input value was "M"
             B     DIVIDE              16 = Input value was "D"
*                                   ---End of Branch table
ERROR        EQU   *
* print or display error message or similar
ADD          EQU   *
* perform addition and continue with rest of program
             B    NEXT
SUBTRACT     EQU   * 
* etc. 
INPUT        DS   C                     The input character is in this byte.
TABLE2       DC   Al1(00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00)    X'00'-X'0F'
             DC   Al1(00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00)    X'10'...
             DC   Al1(00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00) 
             DC   Al1(00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00) 
             DC   Al1(00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00) 
             DC   Al1(00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00) 
             DC   Al1(00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00) 
             DC   Al1(00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00) 
             DC   Al1(00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00) 
             DC   Al1(00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00) 
             DC   Al1(00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00) 
             DC   Al1(00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00) 
             DC   Al1(00,04,00,00,16,00,00,00,00,00,00,00,00,12,00,00)
*                        x'C0' - X'CF' (04 is at offset X'C1')
             DC   Al1(00,00,00,08,00,00,00,00,00,00)00,00,00,00,00,00)    x'D0' - X'DF' 
             DC   Al1(00,00,00,00,00,00,00,00,00,00)00,00,00,00,00,00) 
             DC   Al1(00,00,00,00,00,00,00,00,00,00)00,00,00,00,00,00)
* the above table can be automated if the Assembler is allowed to calculate & place the
* index values but it is not shown here for simplicity. If validation is not required, the
* size of this translate table need only be the size of the range of all possible input
* values - in this case A through to M (18 bytes).

使用 2 字节偏移量的示例

[编辑 | 编辑源代码]

可以使用另一种与上述分支表非常类似的技术。汇编程序可以构建绝对或相对地址(偏移量)表,而不是分支指令表。这只需要一个额外的指令,但将分支范围扩展到 64K,而无需额外的基址寄存器覆盖,并将表的大小减少一半。

             SR    R15,R15             Clear index register to zero  (32 bits)
             IC    R15,INPUT           Insert input byte into low order bits of R15 
*                                      (bits 24-31 - forming X'000000C1' for "A")
             IC    R15,TABLE2(R15)     Use R15 as Index to extract a 0,2,4,6 or 8 from
*                                      the 2nd Table
             LH    R15,TABLE1(R15)     extract two byte offset into low order bits of R15
             B     TABLE1(R15)         Branch using the table address plus offset now in R15
TABLE1       DS    0H               ---Start of Offset table--- (each is 2 bytes long) 
             DC    Al2(ERROR-TABLE1)               00 = Invalid input value         
             DC    AL2(ADD-TABLE1)                 02 = Input value was "A"
             DC    AL2(SUBTRACT-TABLE1)            04 = Input value was "S"
             DC    AL2(MULTIPLY-TABLE1)            06 = Input value was "M"
             DC    AL2(DIVIDE-TABLE1)              08 = Input value was "D"
*                                   ---End of Branch table
ERROR        EQU   *
* print or display error message or similar
ADD          EQU   *
* perform addition and continue with rest of program
             B    NEXT
SUBTRACT     EQU   * 
* etc. 
INPUT        DS   C                    The input character is in this byte.
TABLE2       DC   Al1(00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00)    X'00'-X'0F'
             DC   Al1(00,00,00,00,00,00,00,00,00,00)00,00,00,00,00,00)    X'10'... 
             DC   Al1(00,00,00,00,00,00,00,00,00,00)00,00,00,00,00,00) 
             DC   Al1(00,00,00,00,00,00,00,00,00,00)00,00,00,00,00,00) 
             DC   Al1(00,00,00,00,00,00,00,00,00,00)00,00,00,00,00,00) 
             DC   Al1(00,00,00,00,00,00,00,00,00,00)00,00,00,00,00,00) 
             DC   Al1(00,00,00,00,00,00,00,00,00,00)00,00,00,00,00,00) 
             DC   Al1(00,00,00,00,00,00,00,00,00,00)00,00,00,00,00,00) 
             DC   Al1(00,00,00,00,00,00,00,00,00,00)00,00,00,00,00,00) 
             DC   Al1(00,00,00,00,00,00,00,00,00,00)00,00,00,00,00,00) 
             DC   Al1(00,00,00,00,00,00,00,00,00,00)00,00,00,00,00,00) 
             DC   Al1(00,00,00,00,00,00,00,00,00,00)00,00,00,00,00,00) 
             DC   Al1(00,02,00,00,08,00,00,00,00,00,00)00,00,06,00,00)
*                  x'C0' - X'CF' (02 is at offset X'c1')
             DC   Al1(00,00,00,04,00,00,00,00,00,00)00,00,00,00,00,00)    x'D0' - X'DF' 
             DC   Al1(00,00,00,00,00,00,00,00,00,00)00,00,00,00,00,00) 
             DC   Al1(00,00,00,00,00,00,00,00,00,00)00,00,00,00,00,00)
* An alternative approach here is to have the two-byte branch offsets within TABLE2 
* (it then also uses one less instruction and eliminates the need for TABLE1 but this
* may require twice the size of TABLE2 (depending upon the need for validation, and also on
* the range of the input character).

另一种定义 TABLE2 的方法,让汇编程序自动放置索引字节,如下所示(为简洁起见,只显示了“A”和“D”的示例)。

TABLE2       DC    256AL1(0)                   define 256 bytes of nulls
             ORG   TABLE2+C'A'                 repeat these two lines for each
*                                              valid input character
             DC    AL1(02)                     (The 'ORG' Assembler statement above
*                                              resets to correct position)
             ORG   TABLE2+C'D'                          
             DC    AL1(08)
             ORG                               At end, reset to earlier position after
*                                              end of 256 byte table

使用 4 字节绝对地址的示例

[编辑 | 编辑源代码]

汇编程序可以构建一个绝对地址表。这只需要一个额外的指令,但将分支范围扩展到 2 GB(即 31 位处理器的整个地址空间)。

             SR    R15,R15             Clear index register to zero  (32 bits)
             IC    R15,INPUT           Insert input byte into low order bits of R15 
*                                      (bits 24-31 - forming X'000000C1' for EBCDIC "A")
             IC    R15,TABLE2(R15)     Use R15 as Index to extract a 0,4,8,12 or 16
*                                      from the 2nd Table
             ICM   R15,15,TABLE1(R15)  extract absolute address into all 32 bits of R15 from the 2nd Table             
* The previous ICM instruction above could also be accomplished with
*            L     R15,TABLE1(R15)
             BR    R15                 Branch using the address in R15
TABLE1       DS    0H                ---Start of Offset table--- (each is 2 bytes long) 
             DC    A(ERROR)                        00 = Invalid input value         
             DC    A(ADD)                          04 = Input value was "A"
             DC    A(SUBTRACT)                     08 = Input value was "S"
             DC    A(MULTIPLY)                     12 = Input value was "M"
             DC    A(DIVIDE)                       16 = Input value was "D"
*                                   ---End of Branch table
ERROR        EQU   *                               Label for Errors - could be in a 
*                                                  different CSECT (R15=Entry point address)
*
* print or display error message or similar
ADD          EQU   *                               Label for 'Add'  - could be in a
*                                                  different CSECT through either 
*                                                  an EXTRN ADD statement, or changing 
*                                                  the A(ADD) to V(ADD) (or whatever name)
*
* perform addition and continue with rest of program
             B    NEXT
SUBTRACT     EQU   *                               Label for 'Subtract' - could be in different
*                                                  CSECT etc. 
INPUT        DS   C                    The input character is in this byte.
TABLE2       DC   Al1(00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00)    X'00'-X'0F'
             DC   Al1(00,00,00,00,00,00,00,00,00,00)00,00,00,00,00,00)    X'10'... 
             DC   Al1(00,00,00,00,00,00,00,00,00,00)00,00,00,00,00,00) 
             DC   Al1(00,00,00,00,00,00,00,00,00,00)00,00,00,00,00,00) 
             DC   Al1(00,00,00,00,00,00,00,00,00,00)00,00,00,00,00,00) 
             DC   Al1(00,00,00,00,00,00,00,00,00,00)00,00,00,00,00,00) 
             DC   Al1(00,00,00,00,00,00,00,00,00,00)00,00,00,00,00,00) 
             DC   Al1(00,00,00,00,00,00,00,00,00,00)00,00,00,00,00,00) 
             DC   Al1(00,00,00,00,00,00,00,00,00,00)00,00,00,00,00,00) 
             DC   Al1(00,00,00,00,00,00,00,00,00,00)00,00,00,00,00,00) 
             DC   Al1(00,00,00,00,00,00,00,00,00,00)00,00,00,00,00,00) 
             DC   Al1(00,00,00,00,00,00,00,00,00,00)00,00,00,00,00,00) 
             DC   Al1(00,04,00,00,16,00,00,00,00,00,00)00,00,12,00,00)
*                      x'C0' - X'CF' (04 is at offset X'c1')
             DC   Al1(00,00,00,08,00,00,00,00,00,00)00,00,00,00,00,00)    x'D0' - X'DF' 
             DC   Al1(00,00,00,00,00,00,00,00,00,00)00,00,00,00,00,00) 
             DC   Al1(00,00,00,00,00,00,00,00,00,00)00,00,00,00,00,00)

370 和 zSystem 指令

[编辑 | 编辑源代码]

以下分支指令在 370 和 zSeries 机器中可用——待补充--

360 汇编指令
分支数据传输控制流算术逻辑移位和旋转其他

另请参见

[编辑 | 编辑源代码]
  • [1] 维基百科索引 (信息技术)
[编辑 | 编辑源代码]
  • [2] System/360 指令计时信息


360 汇编语言
360 系列 介绍 · 基本常见问题解答 · 360 系列 · 360 架构
360 指令集 360 指令 · 分支指令 · 数据传输指令 · 控制流指令 · 算术指令 · 逻辑指令 · 移位和旋转指令 · 特权指令 · 其他指令
语法和汇编器 360 汇编器· 伪指令
指令扩展 浮点数 · 高级语言
华夏公益教科书