My Assembler program is running out of Base register Addressibilty . I need to insert few lines of code comprising 30 bytes of Instruction size . I dont have any option to increase the base registers . Can something be done as a quick turnaround .
Joined: 14 Jan 2008 Posts: 2501 Location: Atlanta, Georgia, USA
Many times, Assembler programs contain constants (defined to the Main CSECT and addressed off a CSECT base-register), which could be defined to an External CSECT (table) and brought into the program via an MVS LOAD Macro (Batch only) and addressed via their own base-register and DSECT?
Do you have a situation like this where constants like these could be removed and externalized?
Is there any way/method to convert the existing program baseless
baseless programming is not a workaround to overcome current program issues/limitations
is rather a long term approach,
You will have to review the programming habits
You will have to learn and be proficient with a completely new set of machine instructions
it will introduce quite a few macro incompatibilities
( the instruction sequence might become baseless, You will need anyway the base registers to address data )
add as many more concerns as You like
Its a few years since I did assembler, but remember running into the same problems and was able to find a few bytes here and there with things like using smaller constants or different instructions to do the same thing. For example (and my memory of lengths and instructions may be a bit off here):
L R6,=F'2' -> LA R6,2(0,0) : 8 bytes -> 2 bytes
L R3,=F'523' -> LH R3,=H'523' : 8 bytes -> 6 bytes
S 2,=F'1' -> BCTR 2,0 : 8 -> 2
Basically this stuff is similar to what Bill mentioned about reducing the footprint of literals.
There are also immediate instructions (CLI, etc) that take up less space than instructions that reference storage.
Sometimes there are eye-catcher constants you can reduce the size of.
You might be able to reorganize literals or constants so that wasted space due to alignment is reclaimed. Be careful with that because there are some instructions and macros that still require alignment (not many though).
Some instructions set condition codes and perform similar functions as others that don't. This can let you remove condition code test instructions.
Finally (and this should have been first) sometimes there is an algorithm done inefficiently that can simply be rewritten in less code. There are some old tricks that save space for some tasks (using UNPK for conversion to hex, using TRT for reversing strings, etc) that might be smaller than code in the existing program (note any such change obviously requires extensive testing).
Of course, the best thing to do is create a new CSECT or two to isolate some of the function as external subroutines if that is possible.
Joined: 27 Oct 2009 Posts: 2481 Location: Netherlands, Amstelveen
Following are 2 macro's I used for entering/exiting programs,
and also an example how to use them
Code:
PROGRMX INITSCC
ENDSCC
routines
working storage
LTORG
dsects
MACRO
00010013
&NAME INITSCC &EQUREG=YES,&BASE=(11,12) 00020013
.* 00030013
.* THIS MACRO IS USED IN COMBINATION WITH THE MACRO 'ENDSCC' 00040013
.* 00050013
.* IT GENERATES CODING FOR LINKAGE CONVENTIONS, RETURN TO OS 00060013
.* 00070013
.* WITH THE KEYWORD 'EQUREG' IT IS POSSIBLE TO EQUATE ALL REGISTERS 00080013
.* 00090013
.* THIS MACRO WILL ALSO OBTAIN 4086 BYTES OF STORAGE, THE FIRST 72 00100013
.* BYTES AREA IS THE SAVE AREA, THE REST OF STORAGE IS USED FOR SAVING 00110013
.* RETURN ADDRESSES, THE RETURN ADDRESSES ARE STORED BY MACRO ROUTIN 00120013
.* AND RETRIEVED BY MACRO ROUTUT 00130013
.* 00140013
.* MACRO ENDSCC WILL FREE THE GETMAINED STORAGE OF 4096 BYTES 00150013
.* 00160013
.* 00170013
.* SAMPLES : 00180013
.* NAME INITSCC DEFAULT : EQUATE REGISTERS 00190013
.* NAME INITSCC EQUREG=NO NO REGISTER EQUATION 00200013
.* NAME INITSCC EQUREG=NO,BASE=11 00210013
.* 00220013
.* NAME IS REQUIRED 00230013
.* 00240013
.* 00290013
GBLC &$R 00300013
GBLA &$STOR 00310013
GBLA &K 00320013
GBLA &N 00330013
&$R SETC '' 00340013
&$STOR SETA 4096 00350013
&NAME CSECT 00360013
.* 00370013
AIF ('&EQUREG' EQ 'NO').NOEQU 00380013
&$R SETC 'R' 00390013
* 00400013
*EQUATES 00410013
* 00420013
R0 EQU 0 00430013
R1 EQU 1 00440013
R2 EQU 2 00450013
R3 EQU 3 00460013
R4 EQU 4 00470013
R5 EQU 5 00480013
R6 EQU 6 00490013
R7 EQU 7 00500013
R8 EQU 8 00510013
R9 EQU 9 00520013
R10 EQU 10 00530013
R11 EQU 11 00540013
R12 EQU 12 00550013
R13 EQU 13 00560013
R14 EQU 14 00570013
R15 EQU 15 00580013
* 00590013
.NOEQU ANOP 00600013
AIF (T'&NAME NE 'O').LAB 00610013
MNOTE 16,'NAME OPERAND REQIURED' 00620013
MEXIT 00630013
.LAB ANOP 00640013
SAVE (14,12),,&NAME._&SYSDATE._&SYSTIME 00650014
LR &$R&BASE(1),&$R.15 LOAD ENTRY POINT ADDRESS 00660013
USING &NAME,&$R&BASE(1) SET UP ADDRESSABLITY 00670013
AIF (N'&BASE EQ 1).LAB1 00680013
&N SETA 2 00690013
&K SETA 0 00700013
.LAB0 ANOP 00710013
&K SETA &K+4096 00720013
USING &NAME+&K,&$R&BASE(&N) SET UP ADDRESSABILITY 00730013
LA &$R&BASE(&N),4095(&$R&BASE(&N-1)) INIT BASE 00740013
LA &$R&BASE(&N),1(&$R&BASE(&N)) WITH DISPLACEMENT 00750013
&N SETA &N+1 00760013
AIF (&N LE N'&BASE).LAB0 00770013
.LAB1 ANOP 00780013
LR &$R.8,&$R.1 SAVE PARAMETERS PTR 00790013
GETMAIN R,LV=&$STOR GET SAVE AREA STORAGE 00800013
ST &$R.13,4(&$R.1) STORE CALLERS SA IN MY SA 00810013
ST &$R.1,8(&$R.13) SAVE SAVE AREA PTR 00820013
LR &$R.13,&$R.1 LOAD R13 WITH SA ADDRESS 00830013
LR &$R.1,&$R.8 RESTORE PARAMETER PTR 00840013
MEND 00850013
MACRO 00010000
&NAME ENDSCC &RC 00020000
.* 00030000
.* THIS MACRO IS USED IN COMBINATION WITH INITSCC 00040000
.* AND GENERATES CODING TO RETURN TO OS 00050000
.* 00060000
.* THIS MACRO CAN BE SUPPLIED WITH A PARAMETER WHICH WILL BE 00070000
.* USED FOR THE RETURN CODE IN R15 00080000
.* 00090000
.* SAMPLES : 00100000
.* ENDSCC DEFAULT RETURN CODE = 0 00110000
.* ENDSCC 16 RETURN CODE = 16 00120000
.* ENDSCC (Rx) RETURN CODE IS IN Rx 00130000
.* 00140000
.* 00190000
GBLC &$R 00200000
GBLA &$STOR 00201009
&NAME LR &$R.1,&$R.13 GET ADDRESS OF SAVE AREA 00210006
L &$R.13,4(&$R.13) RESTORE CALLERS SAVE AREA 00220000
FREEMAIN R,LV=&$STOR.,A=(1) FREEMAIN SAVE AREA 00230009
AIF (T'&RC EQ 'O').DFLT 00240000
AIF ('&RC'(1,1) EQ '(').REG 00250000
AIF (T'&RC EQ 'N').NUM 00260000
MNOTE 16,'PARAMETER INVALID' 00270000
MEXIT 00280000
.DFLT ANOP 00290000
&$RC SETC '0' 00300000
RETURN (14,12),RC=&$RC 00310000
MEXIT 00320000
.NUM ANOP 00330000
RETURN (14,12),RC=&RC 00340000
MEXIT 00350000
.REG ANOP 00360000
LR &$R.15,&RC 00370000
RETURN (14,12),RC=(15) 00380000
MEND 00390000