您的位置:首页 > 大数据 > 人工智能

大型机汇编(mainframe assembler/HLASM)之显示内存实际数据

2013-08-20 08:40 417 查看
 

 本篇重在介绍,怎么把内存的实际数据显示出来,首先看下汇编怎么实现的,接下来是用COBOL实现的

000000                00000 00100     1 MAIN     CSECT                   

                 R:C  00000           2          USING *,12              

000000 90EC D00C            0000C     3          STM   14,12,12(13)      

000004 0DC0                           4          BASR  12,0              

000006 50D0 C02C            0002C     5          ST    13,SAVE+4         

00000A 41D0 C028            00028     6          LA    13,SAVE           

                      0000E           7 START    EQU   *                 

00000E F384 C075 C070 00075 00070     8          UNPK  OUTPUT(9),INPUT(5)

000014 DC07 C075 C000 00075 00000     9          TR    OUTPUT,HEXTAB     

                      0001A          10 EXIT     EQU   *                 

00001A 58D0 C02C            0002C    11          L     13,SAVE+4         

00001E 98EC D00C            0000C    12          LM    14,12,12(13)      

000022 41F0 0000            00000    13          LA    15,0              

000026 07FE                          14          BR    14                

000028                               15 SAVE     DS    18F              

000070 A0B1C2D312                    16 INPUT    DC    X'A0B1C2D3',X'12'

000075 4040404040404040              17 OUTPUT   DC    CL8' ',C' '            

00007E                0007E 000F0    18          ORG   MAIN+C'0'         

0000F0                000F0 000F0    19          ORG   ,                 

                      00000          20 HEXTAB   EQU   *-C'0'            

0000F0 F0F1F2F3F4F5F6F7              21          DC    C'0123456789ABCDEF'

000000                               22          END   MAIN                      

 

上面的代码是把内存十六进制的数据变成可显示的数据,比如输入X'A0B1C2D3',结果输出的数据就是可显示的A0B1C2D3

这里需要明确几点:

1.OUTPUT   DC    CL8' ',C' '和OUTPUT   DC    CL9' '的唯一区别是,前者OUTPUT的长度是8后者是9.

  同理INPUT    DC    X'A0B1C2D3',X'12'和INPUT    DC    X'A0B1C2D312'的区别前者长度是4后者长度是5,这也正是为什么在UNPK指令里要注明(9)的原因

  其实在这个程序里,真正的输入数据就是存放在INPUT的前四个字节里,最后一个是什么无所谓,而真正的输出也是存放在OUTPUT的前八个字节里

 

2.计算机里专门有个location counter来标识每个指令或字段的地址,而base register,比如本程序的R12只能标识location connter中的一小部分,它们并不是一回事

  本程序中USING *,12写在了第一行,如果往下写几行,就会发现它们的数据并不相同,location counter肯定是从本程序的第一行开始算起,而base register理论上放在程序的任何地方都可以

       
000014 DC07 C075 C000 00075 00000     9          TR    OUTPUT,HEXTAB

  这一句中我们发现HEXTAB的地址被计算机解析为C000,这不就是程序的开始地址吗?而HEXTAB是在程序的开始地址处吗?不是,因其本身没有地址,它用的是EQU,这个可以从listing里看出来,但它却代表程序的开始地址。

                              00000          20 HEXTAB   EQU   *-C'0'             

        0000F0 F0F1F2F3F4F5F6F7              21          DC    C'0123456789ABCDEF'            

  它们是孤零零的两行,它们之间在计算机看来没任何关系,如果第一行是HEXTAB   EQU  *这只是说明HEXTAB所指向的地址正好是下一行的地址,现在这种情况HEXTAB代表的就是当前地址往前推240个字节,即指向程序开始处的地址。

 

3.TR指令是怎么转换数据的呢?

  通过UNPK指令,OUTPUT变成X'FAF0FBF1FCF2FDF3',X'21',我们拿第一个字节举例,TR就应该找到HEXTAB+X'FA'处的数据,使之替换它,所以就是

  *-C'0'+X'FA' =当前地址-X'F0'+X'FA' = 当前地址+X'0A',对应表中就是字符A

  那可能有人会问X'21'怎么转换呢?其实你根本没必要担心,因为OUTPUT的长度是8,TR转换8次之后就停止了,压根就没处理X'21'这个数据

  其实说到底INPUT和OUTPUT最后多定义那一个字节,纯粹是指令的需要,至于写什么根本不重要,但就是因为有了它,程序确实优美了许多

  

4.

         00007E                0007E 000F0    18          ORG   MAIN+C'0'         

         0000F0                000F0 000F0    19          ORG   , 

   这两行代码完全是为了HEXTAB   EQU   *-C'0'的需要,本程序很短,万一*所代表的当前地址没有C'0'大, 那岂不是要报错!?

  上面第一行是说把location counter强制改成000F0(而它之前所设置的最大为0007E),后一行是说再把location counter再设置为之前所碰到的最大值,这样一来这两行就可以保证location counter最小也要是000F0

   还有一点要说的是HEXTAB   EQU   *-C'0' 这里的*代表当前地址,可当前地址程序是怎么表示的呢?你可以理解为是location counter的数值,当然也可以用base register R12+偏移量来表示,因为它们是一致的,程序中用的就是CXXX),本程序中由于base register设置是在第四行,即location
counter为6处,所以location counter的数值应该始终比以base register的偏移量少6

 

 5.              
R:C 00000 2 USING *,12

 本程序第一行如上所示,它是说在编译过程中,R12里存放的数值就是location counter为0000的数值,R12要从此处开始计算偏移量

 如果把这行放在第四行,其会变成

                  R:C 00006 2 USING *,12

它的意思是说R12的数值是0006,即偏移量是从R12为0006处开始算起的,即往后每个指令或者字段的表示中,相对于R12算出来的偏移量都比去自身的location counter小6,等到了装载的时候R12的里的数据就会比入口地址大0006

解释到这里,你会不会觉得本程序把USING放在第一行有点问题?

,不明白没关系,下一篇大型机汇编(mainframe
assembler/HLASM之基址寄存器的设定帮你解惑

 

 ***************************************************************************************************************

用COBOL同样可以实现同样的功能:

       IDENTIFICATION DIVISION.

       PROGRAM-ID. HELLO.      

       ENVIRONMENT DIVISION.   

       DATA DIVISION.           

       WORKING-STORAGE SECTION.                                

       01  AAA  PIC 9(7) COMP-3.                               

       01  BBB  REDEFINES AAA.                                 

           05  BBB1  PIC X(3).                                 

           05  BBB2  PIC X(1).                                 

       01  CCC  PIC 9(7).                                      

       01  DDD  REDEFINES CCC.                                 

           05  DDD1  PIC X(6).                                 

           05  DDD2  PIC X.                                    

       PROCEDURE DIVISION.                                     

           MOVE X'1A3E5B' TO BBB1.                             

           MOVE AAA TO CCC.                                    

           INSPECT DDD1 REPLACING ALL X'FA' BY 'A',            

             ALL X'FB' BY 'B',ALL X'FC' BY 'C',ALL X'FD' BY 'D'

             ALL X'FE' BY 'E',ALL X'FF' BY 'F'                  

           STOP RUN.

         

 有异议请联系QQ349106216

 

 

 

 


内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: