IBM 汇编程序中的位移位

Bit shifting in IBM assembler

在 IBM OS/390 程序集中,我正在尝试执行以下操作:

我有一组全部以 2 个零结尾的位:

00xxxxxx 00yyyyyy 00zzzzzz

我想将它们压缩成以下格式:

xxxxxxyy yyyyzzzz zz...

我想订单应该是这样的

ICM  R7,B'1111',FIRSTBUF       LOAD 4 BYTES FROM FIRSTBUF INTO REGISTER 7
SLL  R7,2                      SHIFT ALL BITS LEFT BY 2
STCM R7,B'1000',FINALBUF       PASTE THE LEFTMOST BYTE ONLY
SLL  R7,2                      SHIFT ALL BITS LEFT BY 2
(somehow overwrite only the rightmost 2 bits of the leftmost byte)
STCM R7,B'0100',FINALBUF       PASTE SECOND LEFTMOST BYTE
SLL  R7,2                      SHIFT ALL BITS LEFT BY 2
(somehow overwrite only the right 4 bits of the second byte)
STCM R7,B'0010',FINALBUF       PASTE SECOND RIGHTMOST BYTE
SLL  R7,2                      SHIFT ALL BITS LEFT BY 2
....

我走的路对吗?


ICM  R7,B'1111',FIRSTBUF       LOAD 4 BYTES FROM FIRSTBUF INTO REGISTER 7

SLL  R7,2       ; Shift away zeros
LR   R8,R7       ; Move to a work register
AND  R8, 0x3F   ; Clear out extra bits.
; First Character complete.

SLL  R7,8       ; Remove 1 character and lower 2 bit 0s by shifting away.
LR   R9,R7       ; Move to another work register
AND  R9, 0x3F    ; Clear out extra bits.
SLL  R9, 6       ; Shift up to proper location
O    R8, R9      ; Drop it in
; Second Character complete.

SLL  R7,8       ; Remove 1 character and lower 2 bit 0s by shifting away.
LR   R9,R7       ; Move to register
AND  R9, 0x3F    ; Clear out extra bits.
SLL  R9, 14      ; Shift up to proper location
O    R8, R9      ; Drop it in
; Third Character complete.

SLL  R7,8        ; Remove 1 character and lower 2 bit 0s by shifting away.
LR   R9,R7       ; Move to register
AND  R9, 0x3F    ; Clear out extra bits.
SLL  R9, 22      ; Shift up to proper location
O    R8, R9      ; Drop it in

; And so on until you want to store the result, or your holder register is full.

我以前没有用这个汇编器编写过代码,但是一个汇编器很像另一个,上面应该展示了按位 and/or 与移位相结合的位操作思想。它还通过不不断地将数据写入内存来缓冲 I/O,而是使用寄存器来加快速度。

祝你好运!

我想你已经在这方面绕过了房子。

BUF01    DS    CL4                First data location
...
BUF02    DS    CL4                Second data location
...
BUF03    DS    CL4                Third data location
...
FINBUF   DS    0CL9               Final location
FINB01   DS    CL3                First final part
FINB02   DS    CL3                Second final part
FINB03   DS    CL3                Third final part

         L     R7,BUF01          Load first data to available gp register    
         STCM  R7,B'0111',FINB01 Store low-order three where needed

         L     R7,BUF02          Load second data to available gp register    
         STCM  R7,B'0111',FINB02 Store low-order three where needed

         L     R7,BUF03          Load third data to available gp register    
         STCM  R7,B'0111',FINB03 Store low-order three where needed
         ETVOILA                 Required data arrives at this point in FINBUF

如果您的数据(或其中的任何数据)碰巧已经在寄存器中,放弃加载并将 R7 更改为适当的寄存器。

您在问题中使用的 ICMB'1111' 的优点是它设置了条件代码,而 LOAD 则没有。如果你不需要CC,那么ICM比LOAD慢,所以你不会用它。

这里,盲目加载四个字节到一个寄存器,然后存储低位三个是没有问题的。可能有很多变化,但除了简单之外没有理由保留它。

整个四个字节被加载到寄存器中。由于掩码为 B'0111',因此只有寄存器的三个低位字节存储在内存中。寄存器中与掩码中的 1 相对应的任何字节都将从第二个操作数的地址开始连续存储。您只需不存储第一个字节即可获得连续的九个字节。无需移位再组合。

这里是 Store Characters Under Mask (STCM) 指令的解释摘录,来自 第 7 章的第 313 页。一般指令 当前(来自链接到文档的 z/OS 2.1 元素和功能 页面)z/Architecture 操作原理 ,这是您的 Mainframe Assembler 参考指南。

Bytes selected from general register R(1) under control of a mask are placed at contiguous byte locations beginning at the second-operand address.

The contents of the M(3) field are used as a mask. These four bits, left to right, correspond one for one with four bytes, left to right, of general register R(1). For STORE CHARACTERS UNDER MASK (STCM, STCMY), the four bytes to which the mask bits correspond > are in bit positions 32-63 of general register R(1)... The bytes corresponding to ones in the mask are placed in the same order at successive and contiguous storage locations beginning at the second-operand address. When the mask is not zero, the length of the second operand is equal to the number of ones in the mask. The contents of the general register remain unchanged.

请注意,您的CPU可能不是最新的,但您问题中所有说明的描述和使用都是相同的。询问您的技术支持,您应该使用哪种 POP(操作原理)来匹配您的实际 CPU.

作为一个顽固的汇编爱好者,我打算对上面的例子做一点改动...

首先,如果您有可用的寄存器并且可以安排原始值在内存中相邻,一个简单的 LOAD MULTIPLE (LM Rx,Ry,data) 和三个 STORE CHARACTERS UNDER MASK (STCM) 就可以解决问题.总共四个指令。

但后来我想到有一种更好的方法可以通过使用 TRANSLATE (TR) 的一条指令来完成此操作:

IN1    DC  A(0)                      <- Input fields...they must be contiguous   
IN2    DC  A(0)
IN3    DC  A(0)
     . . .
TARGET DC  XL9'010203050607090A0B'   <- Note the pattern
     . . .
       TR  TARGET,IN1                <- Magic!

TRANSLATE 指令使用第二个操作数作为查找替换目标中的值 table。虽然这最常用于将 ASCII 转换为 EBCDIC 之类的事情,但它也可以用于 "rearrange" 数据,就像原始发布者想要的那样。 TR 获取第一个字节 (X'01'),按此数量索引到第二个操作数,并用它找到的任何内容替换输入中的值。当指令完成时,TARGET 字段包含所请求的内容——并且这种方法只使用一条 CPU 指令。

我很少展示我对大型机汇编程序的了解,所以感谢您给我机会!

* ASSUME R1 -> TWO ENTRY PARM LIST
* PARM ONE -> 4 BYTES WITH BITS = 00XXXXXX 00YYYYYY 00ZZZZZZ ...
* PARM TWO -> 4 BYTES TO RECEIVE BITS = XXXXXXYY YYYYZZZZ ZZ000000 ...
U3856804 CSECT
         SAVE (14,12) "STM 14,12,12(13)"
         USING U3856804,15
         LM 14,15,0(1) R14 -> PARM ONE, R15 -> PARM TWO
         IC 0,0(14)    R0 LOW-ORDER BYTE = 00XXXXXX
         IC 1,1(14)    R1 LOW-ORDER BYTE = 00YYYYYY
         SLL 1,26      R1 HIGH-ORDER BYTE = YYYYYY00
         SLDL 0,6      R0 LOW-ORDER HALFWORD = 0000XXXX XXYYYYYY
         IC 1,2(14)    R1 LOW-ORDER BYTE = 00ZZZZZZ
         SLL 1,26      R1 HIGH-ORDER BYTE = ZZZZZZ00
         SLDL 0,20     R0 = XXXXXXYY YYYYZZZZ ZZZZ.... ........
         ST 0,0(,15)   STORE RESULT
         RETURN (14,12) "LM 14,12,12(13)" "BR 14"
         END

我知道您问的是 OS/390 架构。但是,如果您 运行 在 z10 或更高版本的机器上,旋转和插入选定位 (RISBG) 可能会有所帮助。