mandag den 2. november 2015

Base register in assembler (3)

The modern approach to write big programs
Some commented on the previous article that it was not relevant any longer to discuss base register because some new instructions have come that deal with branching to a label more than 4K away. That is right and I have studied them and I will try to present my view of this new approach. It is worth mentioning that not only is it solved for branch instruction but for all instruction that use base register. You basically do not need base registers for instructions anymore but for constants in your program, nothing is changed.

Relative instructions

All new instructions are called “relative” instructions. That is because the branch instruction addresses the target relative to where you are now. If you are on Location Counter X’00000C’ and you wish to to branch to LC X’0010A8’ the assembler calculates the difference to  X’109C’. It could put that into the instruction but in order to address a longer range the relative address is in half words so we have to divide by two to X’84E’. The machine instruction will then be
X’A7F4 084E’  <==  BRC   X'F',WTO
The X’A7’ is a common instruction code for all relative branches. To distinguish between the different branch instruction types the low order four bits of second byte give the subinstruction: (‘4’ in the above instruction)
4. BRANCH RELATIVE ON CONDITION
5. BRANCH RELATIVE AND SAVE
6. BRANCH RELATIVE ON COUNT (31 bit)
7. BRANCH RELATIVE ON COUNT (64 bit)
You will find several other “relative” instructions but they basically work the same.

Just Jump

You probably do not code ‘BC’ instructions anymore. You use the extended branch mnemonics like “B” for the unconditional branch. Likewise is there a “J” for the relative unconditional branch. So “BE” can be substituted by “JE” and so on. The instruction above will be
J     WTO ⇒ BRC   X'F',WTO
000000                00000 01140     1 PGM5     CSECT                            
                                     2 PGM5     RMODE ANY                        
                                     3          ENTRY PGM5                       
000000 90EC D00C            0000C     4          STM   14,12,12(13)               
000004 0DB0                           5          BASR  11,0                       
000006                                6 START    DS    0H                         
                R:B  00006           7          USING START,11                   
000006 D245 B05A B012 00060 00018     8          MVC   WTOTEXT,=CL70'HELLO WORLD'
                                     9 *        B     WTO                        
00000C A7F4 084E            010A8    10          BRC   X'F',WTO                   
000010 A7F4 084C            010A8    11          J     WTO                        
000018                               12          LTORG                            
000018 C8C5D3D3D640E6D6              13                =CL70'HELLO WORLD'         
00005E 0046                          14 WTOTEXT_LGD DC Y(L'WTOTEXT)               
000060                               15 WTOTEXT  DS    CL70                       
0000A6 4040404040404040              16          DC    4096C' '                   
0010A6 00                            17          DC    X'00'                      
0010A8                               18 WTO      DS    0H                         
                                    19          WTO   TEXT=WTOTEXT_LGD,ROUTCDE=11
Example of BRC and J.
Try to explain why there are a displacement difference in the two similar instructions:
00000C A7F4 084E            010A8    10          BRC   X'F',WTO                   
000010 A7F4 084C            010A8    11          J     WTO


If you can explain the values and the difference you now understand relative instructions.

Negative offset

What if we are jumping upwards in the code? I have made small change to the program to show what happens. Look at the Jump at LC 0010A8. The offset is X’F7B4’ = -2124. The assembler calculates it like this

(LC X’10’ - LC X’10A8’ ) / 2 = X’EF68’ / 2 = X’F7B4’
00000C A7F4 084E            010A8     9          BRC   X'F',GOTOWTO                
000010                               10 JUMPTOWTO DS   0H                          
000010 A7F4 084E            010AC    11          J     WTO                         
000018                               12          LTORG                             
000018 C8C5D3D3D640E6D6              13                =CL70'HELLO WORLD'          
00005E 0046                          14 WTOTEXT_LGD DC Y(L'WTOTEXT)                
000060                               15 WTOTEXT  DS    CL70                        
0000A6 4040404040404040              16          DC    4096C' '                    
0010A6 00                            17          DC    X'00'                       
0010A8                               18 GOTOWTO  DS    0H                          
0010A8 A7F4 F7B4            00010    19          J     JUMPTOWTO                   
0010AC                               20 WTO      DS    0H                          
                                    21          WTO   TEXT=WTOTEXT_LGD,ROUTCDE=11
Negative offset
Location Counter shows 0010A8 shows a negative jump. The high order bit is set to 1.

LOAD ADDRESS RELATIVE LONG (LARL)

If you really fancy not using base register at all you can even do away with base register to constants as well by loading the address into a register and then move it.
MVC FLD,=CL10'PAUL'
You could have
LARL R15,PAULTEXT
MVC FLD,0(R15)

PAULTEXT DC CL10'PAUL'

One extra instruction and you are free of base register (Thanks to Paul Stuyvesant for the example).

Additional “relative” instructions

If you really want to write a total base register free program you might also need these relative instruction:

  • LOAD ADDRESS RELATIVE LONG
  • LOAD HALFWORD RELATIVE LONG
  • LOAD LOGICAL HALFWORD RELATIVE LONG
  • LOAD LOGICAL RELATIVE LONG
  • LOAD RELATIVE LONG
  • COMPARE AND BRANCH RELATIVE
  • COMPARE HALFWORD RELATIVE LONG
  • COMPARE IMMEDIATE AND BRANCH RELATIVE
  • COMPARE LOGICAL AND BRANCH RELATIVE
  • COMPARE LOGICAL IMMEDIATE AND BRANCH RELATIVE
  • COMPARE LOGICAL RELATIVE LONG
  • COMPARE RELATIVE LONG
  • EXECUTE RELATIVE LONG

Halfword boundary

Take a look at the second last instruction. I entered the ‘DC’ in order to confuse the assembler. Because we use number of halfwords to address the target instruction it must be on halfword boundary.  I chanced the code to
0010A6 00                            17          DC    X'00'                      
                     010A7          18 WTO      EQU   *                          
                                    19          WTO   TEXT=WTOTEXT_LGD,ROUTCDE=11
0010A7 00                                                                         
0010A8                               21+         CNOP  0,4                        
WTO label is not on halfword boundary
That produced this error during assembling:
000010 0000 0000            00000    11          J     WTO
** ASMA058E Invalid relative address - WTO
Boundary error

That is why it is always a good idea to use
LABEL     DS    0H
instead of
LABEL     EQU   *

because the first always aligns on half word as opposed to the latter
I think this concludes the series of articles regarding base register(s). Unless, of course, I get further comments.

Ingen kommentarer:

Send en kommentar