360 彙編/360 指令/USING
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,其中 45 是 BAL 指令的十六進位制操作碼,F 表示暫存器 15,第一個 0 表示未使用索引暫存器,806C 是十六進位制地址 08C 加上暫存器 8 中地址的基址-偏移地址,由於第 10 行的 USING 偽指令,因此使用了暫存器 8。
- 在第 29 行,指令被彙編為 4150D4C0,其中 41 是 LA 指令,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 中使用的標籤分配給基址/偏移地址。
主程式(即不是由呼叫方載入基址暫存器的子程式)將使用 BALR 或 BASR 指令載入基址暫存器的內容,然後發出 USING 偽指令以告知彙編器該特定暫存器可用作基址暫存器。
| 360 彙編器 偽指令 | |
| 地址相關 | ADATA • CNOP • DROP • EQU • LOCTR • LTORG • ORG • USING |
|---|---|
| 程式碼相關 | 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 彙編器 · 偽指令 |
| 指令擴充套件 | 浮點數 · 高階語言 |