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)
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
I think this concludes the series of articles regarding base register(s). Unless, of course, I get further comments.
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
Ingen kommentarer:
Send en kommentar