fredag den 13. november 2015

Addressing modes in assembler (2)

How to get above the bar

2GB storage and 31-bit addressing mode seemed not to be enough. So yet another addressing mode was introduced to end all addressing mode problems, - 64-bit addresses. That is a mind blowing amount of storage to address. 16 exabytes!! (An exabyte is slightly more than one billion gigabytes.). However, before your head explodes, bear in mind that the virtual storage must be backed up by real storage so you don’t run into paging problems.


The border between 31-bit storage and 64-bit storage is called “The bar” as opposed to the border between 24-bit and 31-bit storage which is called “The line”.


You may remember that the PSW contained a bit to tell the addressing mode, - either 24 or 31. Another bit is introduced to tell the addressing mode is 64. It is the low order bit of the first fullword of the PSW:


AMODE64 PSW: 078D0001   80007E14


The AMODE31 bit is on and the bit left to it is also on, which tells us we are in AMODE64.


The storage above the bar is not intended for programs although you can specify RMODE 64. The program will only be loaded into 31-bit storage but AMODE will automatically be 64.


You can not obtain storage above the bar by the Getmain or Storage macroes. You must use another macro called IARV64. I will show you a program that obtains a bit of storage, called an object, above the bar, move a text to it, and then moves it back again and writes it using a WTO. You can see the whole program at the bottom of this article.


IBM has introduced some new instructions to take account for the 64-bit addressing mode. Along with these new instructions the old can also work with storage above the bar. We operate with two types of instructions in this regard, - modal instruction that changes their characteristics in different addressing modes and non-modal that works exactly the same whatever addressing mode they are in. One could say that modal instructions adapt to the environment so the still work logically the same but not physically. The new 64-bit instructions work the same in any addressing mode so the can also be used in other addressing modes.


LG is a new instruction, a load in 64-bit addressing mode. The “G” is used throughout the instruction set to tell that it is a 64-bit instruction. MVCL is a modal instruction that logically works as always but physically works different in 64-bit where it uses all 64 bits of the registres as address.


Let us go through the special 64-bit instructions in my program:
  1. PGM7     AMODE 64
    We start to set the addressing mode. It is quite the same as for the other addressing modes
  2. IARV64 REQUEST=GETSTOR,SEGMENTS=SEGMENTS,ORIGIN=STORAGE_ADR
    Getmain some storage above the bar.
    1. REQUETS=GETSTOR = GETMAIN
    2. SEGMENTS=SEGMENTS. Further down I define a doubleword with the value of one. I only need one segment of storage. One segment is 1MB of storage.
    3. ORIGIN=STORAGE_ADR puts the 64-bit address of the storage into a doubleword of storage in my program.
  3. LG    STORAGE_REG,STORAGE_ADR
    I load the whole 64-bit address into the baseregister of the DSECT.
  4. SEGMENTS DC    FD'1'
    Only one segment will be obtained (1MB)
  5. STORAGE_ADR DS FD.
    The target for the obtained 64-bit storage address


Right before the MVCL to the 64-bit location my registers look like this
R2:  48_00000000 (2048 bytes of storage addressable)  
R3:     00000046 (1978 bytes of storage addressable)  
R4:     1F700FB4 (Module PGM7 CSECT PGM7 + X'1BC')    
R5:     00000046 (1978 bytes of storage addressable)  
Move Long registers


The load module is binded in AMODE 64 which you can see in the LOADLIB.
Name     Prompt        Alias-of     Size      TTR     AC   AM   RM
PGM7                               00000208   00070F   00    64  ANY


Dynamic addressing mode

You can also swap between addressing modes like I showed in the previous article. However, it has become “too easy”. IBM has introduced three instructions to swap addressing modes, - The three Set Addressing Mode instructions:
  • SAM24
  • SAM31
  • SAM64
If you are in AMODE 31 and you wish to swap to AMODE 64 just issue SAM64. When you wish to go back enter SAM31. Too good to be true!
        SAM64                      
        LA    R2,TEXT64            
        L     R3,=F'70'            
        LA    R4,=CL70'HELLO WORLD'
        LR    R5,R3                
        MVCL  R2,R4                
Just enter SAM64 to swap into AMODE 64         


It was too good to be true! I received an ABEND/0C4:
SYSTEM COMPLETION CODE=0C4  REASON CODE=0000003B
The reason code 3B tells you that something is wrong in an page translation table, the third actually. When I moved the SAM64 instruction up as the first in the program, the program run perfectly.
It turned up that the BASR was the culprit. In AMODE 31 it sets the high order bit in the “return address” to indicate AMODE 31.
B: 00000000_9F700DFE


But when the program enters AMODE 64 the AMODE-bit becomes a part of the address. I reset the bit and then I was running.
        BASR  11,0                               
    USING *,11                               
    N     11,=X'7FFFFFFF'                    
    IARV64 REQUEST=GETSTOR,SEGMENTS=SEGMENTS,
          ORIGIN=STORAGE_ADR                 
    LG    STORAGE_REG,STORAGE_ADR            
    USING WS64,STORAGE_REG                   
    SAM64
    LA    R2,TEXT64                          
    L     R3,=F'70'                          
    LA    R4,=CL70'HELLO WORLD'              
    LR    R5,R3                              
    MVCL  R2,R4                              
Resetting the AMODE bit in the baseregister made the program run

A more clever way to reset an address from 31-bit to 64-bit is LLGTR

        BASR   11,0  
        USING *,11  

        LLGTR 11,11 

or you could just load the base register by using LARL

         LARL   11,BASEADR
         USING BASEADR,11

BASEADR    DS    0H
Thanks to: Jeffrey Celander and Binyamin Dissen for advise to load baseregisters

Please remember to go back to your original AMODE before you return to the caller. Otherwise you will get an ABEND/0C4


Source of the example program


R2       EQU   2
R3       EQU   3
R4       EQU   4
R5       EQU   5
STORAGE_REG EQU 12
WS64     DSECT
TEXT64   DS CL(L'WTOTEXT)
WS64_LEN EQU   *-WS64                                         
PGM7     CSECT                                                
PGM7     RMODE 31                                             
PGM7     AMODE 64                                             
        ENTRY PGM7                                           
        STM   14,12,12(13)                                   
        BASR  11,0                                           
        USING *,11                                           
        IARV64 REQUEST=GETSTOR,SEGMENTS=SEGMENTS,     *
              ORIGIN=STORAGE_ADR                             
        LG    STORAGE_REG,STORAGE_ADR                                  USING WS64,STORAGE_REG
        LA    R2,TEXT64            
        L     R3,=F'70'            
        LA    R4,=CL70'HELLO WORLD'
        LR    R5,R3                
        MVCL  R2,R4
*********                                 
        LA    R2,TEXT64                  
        L     R3,=F'70'                  
        LA    R4,WTOTEXT                 
        LR    R5,R3                      
        MVCL  R4,R2                      
        WTO   TEXT=WTOTEXT_LGD,ROUTCDE=11
        B     RETURN                     
SEGMENTS DC    FD'1'                      
STORAGE_ADR DS FD                         
WTOTEXT_LGD DC Y(L'WTOTEXT)               
WTOTEXT  DS    CL70                       
RETURN   DS    0H                         
        LM    14,12,12(13)
        RETURN RC=0
        LTORG
        END
Static AMODE64 program


That concludes the two articles about addressing modes in System z assembler. I could have written an article about data spaces but I postpone that. You can read much more in this manual: MVS Programming:Extended Addressability Guide

Ingen kommentarer:

Send en kommentar