跳转到内容

360 汇编/360 指令/USING

来自 Wikibooks,开放世界中的开放书籍

USING 伪指令 用于告知汇编器各种寄存器的内容,这些寄存器将用于基址-偏移寻址。它不生成任何可执行指令,而是向汇编器提供信息。

USING 伪指令的格式为

USING 地址,寄存器1[,寄存器2[,...]]

寄存器1 可以是通用寄存器 1 到 15 中的任何一个。它告诉汇编器,该寄存器已加载了作为第一个参数指定的地址。因为许多指令(包括分支指令)将寄存器 0 视为无操作或包含实际值 0,所以不应将寄存器 0 用于此目的。第二个(或后续)寄存器(由参数 寄存器2 指示)可选地提供第二个基址寄存器,并假定它包含第一个参数的地址加上 4096。如果指定了每个后续寄存器,则汇编器假定它包含前一个寄存器中指定的地址以上 4096 个字节的地址。

示例

PROG      START 0
          BALR  12,0
          USING *,12,11
          LA    11,4095(12)
          LA    11,1(11)

在上面的示例中,USING 伪指令告诉汇编器,寄存器 12 被设置为该模块前 4096 个字节的基址寄存器,寄存器 11 被设置为后 4096 个字节的基址寄存器。在通过 BALR 指令将寄存器 12 加载了当前地址后,寄存器 11 将加载程序中 4096 字节之后的地址。请注意,这使用了旧的 LA 指令,该指令不能将超过 4095 的值添加到寄存器中包含的值,因此必须使用两个 LA 指令。虽然这种指令组合可以在所有型号的 IBM 硬件以及竞争对手的设备上运行,但 IBM 硬件的后续版本(如 z/Series)为此目的提供了更高效的指令。

如果多个寄存器都访问同一个特定位置,汇编器可能会感到困惑并发出 MNOTE 级别 4(警告),因为它不确定使用哪个寄存器,在这种情况下,它将使用指向目标地址的编号最高的寄存器。但是,如果两个或多个寄存器的 USING 地址重叠,则汇编器将选择产生最低偏移地址的寄存器。以下示例将演示这一点。此示例来自汇编列表。

000000                                       1 ************
000000                                       2 * Determine which register the assembler uses  
000000                                       3 * Author - Paul Robinson    
000000                                       4 * Date   - 11/28/20
000000                                       5 *****************
000000                                       6          TITLE 'Using test'
000000                                       7          PRINT NOGEN
000000                                       8 *
000000                                       9 MAIN     CSECT 
000000                                      10          USING MAIN,8
000000 90ECD00C                             11          STM   14,12,12(13)
000004 188F                                 12          LR    8,15          Reg 8 now contiains start address
000006 45F0806C                00006C       13          BAL   15,START 
00000C 0000000000000000                     14          DC    18F'0'
000054 D4C1C9D540404040                     15          DC    CL8'MAIN'          Create a marker visible during coredumps
00005C F1F161F2F861F2F0                     16          DC    CL8'11/28/20'     Date compiled 
000064 F0F14BF0F3404040                     17          DC    CL8'01.03'       Version number of program
00006C 50FD0008                             18 START    ST    15,8(13)          Link savearea to preious savearea
000070 50DF0004                             19          ST    13,4(15)
000074 18DF                                 20          LR    13,15             R13 now points to new savearea
000076                                      21          USING MAIN+8,13
000076                                      22          WTO   'Program Started'
000090                                      28 *
000090 4150D4C0                0004C8       29          LA    5,ITEM
000094                                      30 *
000094 4120D0D8                0000E0       31          LA    2,BLANKS
000098 4130D4C0                0004C8       32          LA    3,ITEM
00009C 4140D0D4                0000DC       33          LA    4,X
0000A0                                      34 *
0000A0                                      35          USING X,4
0000A0                                      36          USING ITEM,3
0000A0                                      37          USING BLANKS,2
0000A0                                      38 *
0000A0 41202000                0000E0       39          LA    2,BLANKS
0000A4 41303000                0004C8       40          LA    3,ITEM
0000A8 41404000                0000DC       41          LA    4,X
0000AC                                      42 *
0000AC 41503000                0004C8       43          LA    5,ITEM
0000B0                                      44 *
0000B0                                      45          WTO   'Program ended.'
0000C8 58D0D004                             51          L     13,4(,13) Restore old savearea
0000CC 41F00000                             52          LA    15,0
0000D0 58E0D00C                             53          L     14,12(,13)
0000D4 982CD01C                             54          LM    2,12,28(13)
0000D8 07FE                                 55          BR    14            And leave
0000DA                                      56 *
0000DC 00000000                             57 X        DC    A(MAIN)
0000E0 4040404040404040                     58 BLANKS   DC    1000C' '
0004C8 00000000                             59 ITEM     DC    A(0)
0004CC                                      60          END

以下是程序的汇编方式。

  • 在第 13 行,分支跳转到程序中的十六进制地址 8C(标签 START),在指令中,它被汇编为 45F0806C,其中 45BAL 指令的十六进制操作码,F 表示寄存器 15,第一个 0 表示未使用索引寄存器,806C 是十六进制地址 08C 加上寄存器 8 中地址的基址-偏移地址,由于第 10 行的 USING 伪指令,因此使用了寄存器 8。
  • 在第 29 行,指令被汇编为 4150D4C0,其中 41LA 指令,5 表示寄存器 5 是要加载的目标寄存器,第一个 0 再次表示未使用索引寄存器,并且 {{mono|D4C0|| 用于指示该地址是十六进制地址 4C0 字节加上寄存器 13 中的地址。这是正确的,因为 ITEM 位于程序中的十六进制地址 4dc8。汇编器使用寄存器 13,因为第 21 行的 USING 语句将偏移量放在寄存器 13 中,与寄存器 8 相比,它离 ITEM 只有 8 个字节。
  • 类似地,对于第 31-33 行的指令,寄存器 13 中的地址“更接近”(偏移量小于)寄存器 8,因此使用寄存器 13。
  • 第 35-37 行的指令告诉汇编器,寄存器 2-4 指向这些位置。
  • 在第 39-41 行,由于汇编器已被告知这些寄存器中的每一个都指向它们被告知要加载地址的项,因此在每种情况下,该寄存器与目标地址的偏移量为 0,因此使用该寄存器(偏移量为 0)。
  • 在第 43 行,汇编器被告知寄存器 3 与 ITEM 的地址相同,因此汇编器使用寄存器 3 且偏移量为 0。将其与第 29 行的相同指令进行比较,在第 29 行中,寄存器 13 中的地址产生最小的偏移量,因此它被使用而不是寄存器 8。

这是一个内联子程序的示例,该子程序为子程序设置一个临时基址寄存器。出于本示例的目的,假设 R14 等于 14,R15 等于 15 等,以提供交叉引用 - 请参阅 EQU 汇编器伪指令)

* some typical assembler instructions showing comments to the right
        L     R15,=A(MOVE)                    Load sub-routine address into R15                   
        BALR  R14,R15                         Go to the sub-routine ===>
*                                             ....return here with return code in R15
*
*****************************************
*  Move the input to output             *
*****************************************
MOVE    EQU   *                               Start of a sub-routine called "Move"
        USING *,R15                           Tell the assembler reg. 15 points to
*                                             this address 
        MVC   OUTPUT,INPUT                    Move the input to the output area 
        SR    R15,R15                         Clear register contents (set Return code = 0)
        BR    R14                             return to caller
        DROP  R15                             Tell assembler we are no longer using
*                                             register 15 and resume using previous register
*
TABLE   DC    C'ABCDEFGHIJKLMNOPQRSTUVWXYZ'   Table of letters of the alphabet
INPUT   DS    Cl80                            Input area
OUTPUT  DS    Cl80                            Output area

如上例所示,USING 伪指令告诉汇编器特定寄存器包含指定的地址,而 DROP 伪指令告诉汇编器该寄存器不能再使用,直到在另一个 USING 伪指令中指定它。

按照惯例

  • 操作系统通常在 SVC 中使用寄存器 0 和 1,并期望使用一个或两个寄存器提供值或值列表的地址;它们也经常用于(有时与寄存器 15 一起)从 SVC 返回结果值。因此,寄存器 1 不应在可执行代码段中用作基址寄存器,但可以接受引用 DSECT 将标签映射到寄存器 1 的偏移量。
  • 某些操作系统和某些指令可能会提供或使用寄存器 2 和/或寄存器 15,因此如果在发出 SVC 或发出 SVC 的宏的汇编语言模块中使用寄存器 2 或 15 作为基址寄存器,则应注意。
  • 390/zSystem 硬件上的 Linux 操作系统使用寄存器 1 到 6 用于参数,因此在 S/390 Linux 上进行 SVC 后,不应认为这些寄存器保持不变或可用。
  • 寄存器 13 通常用作指向 18 字节寄存器保存区域的指针(对于在 24 或 32 位模式下运行的程序),因此它应该只用于此目的。如果程序没有调用任何子程序并在入口处保存寄存器 13 的值,并在退出时恢复它,则寄存器 13 可以用于任何目的。但是,如果寄存器 13 用于其他目的(其中它不指向保存区域),则应在程序中记录这一点,以便将来维护程序的任何人不会对此做法感到困惑。注意,寄存器 13 可以用于其他目的,例如指向可重写区域(例如,对于动态获取内存的重入程序)或任何其他目的,只要它指向的前 18 个字可用作寄存器保存区域。
  • 寄存器 14 通常用作程序返回到调用方(或如果程序不是子程序,则返回到操作系统)的返回地址。如果程序在入口处保存寄存器 14,并在退出时恢复它,则寄存器 14 可以用于任何目的。
  • 寄存器 15 通常作为程序的入口点提供,因此可以作为 USING 寄存器;只有当程序本身必须调用子程序时,它才必须将另一个寄存器设置为其基址寄存器。但是,某些操作系统也使用寄存器 15 以及寄存器 0 和 1 返回值,因此如果例程发出 SVC 或发出 SVC 的宏,最好不要将寄存器 15 用作基址寄存器。

地址可以是 *(表示当前程序计数器),也可以是当前模块中的标签,或者标签加上一个值。这允许汇编器知道对当前模块中的地址的引用使用哪个基址寄存器。它也可以在引用 DSECT 时使用,以将 DSECT 中使用的标签分配给基址/偏移地址。

主程序(即不是由调用方加载基址寄存器的子程序)将使用 BALRBASR 指令加载基址寄存器的内容,然后发出 USING 伪指令以告知汇编器该特定寄存器可用作基址寄存器。

 
360 汇编器 伪指令
地址相关 ADATACNOPDROPEQULOCTRLTORGORGUSING
代码相关 ALIAS • AMODE • CATTR • COM • CSECT • CXD • DSECT • DXD • END • ENTRY • EXTRN • OPSYN • RMODE • RSECT • START • WXTRN • XATTR
数据相关 CCW • CCW0 • CCW1 • DC • DS
条件汇编和宏相关 ACTR • AGO • AIF • AINSERT • ANOP • AREAD • COPY • GBL(GBLA / GBLB / GBLC)• LCL(LCLA / LCLB / LCLC)• MACRO • MEND • MEXIT • MNOTE • SET(SETA / SETB / SETC)
列表、输出和源代码相关 注释 • *PROCESS • ACONTROL • EJECT • END • EXITCTL • ICTL • ISEQ • POP • PRINT • PUNCH • PUSH • REPRO • SPACE • TITLE
 
System/360 汇编语言
System/360 系列 简介 · 基本常见问题 · System/360 系列 · System/360 架构
System/360 指令集 System/360 指令 · 分支指令 · 数据传输指令 · 控制流指令 · 算术指令 · 逻辑指令 · 移位和旋转指令 · 特权指令 · 其他指令
语法和汇编器 System/360 汇编器 · 伪指令
指令扩展 浮点数 · 高级语言
华夏公益教科书