I have been working for a long time in a company where all ASSEMBLER code was using SP macros, and there were no compare instructions and no branches in the code.

To make this possible, it is IMO necessary that you have in addition to the SP macros like IF, THEN, ELSE, EIF, LOOP, BREAK, ELOOP, LEAVE etc. a sort of "lightweight" PCALL, PROC end ENDPROC macro, which allows for inline procedures, so that you are able to call "structure blocks" of code and to build well structured large programs.

The "lightweight" call macros should not do the full featured register save conventions as it is done for external module calls, but they should save some registers (for example regs 10 thru 14), and they should exstablish new base registers for a static data area which follows the code (static local variables). So each function block can have its own local static variables and constants and literal pool (don't forget LTORG). Calls between those function blocks have to be done using address constants, so that there are no restrictions
regarding distance.

We had such macros in the company mentioned above, and I improved them in the last years to allow for "baseless coding" (meaning: the code part of the function blocks is not covered by base registers, all branches are relative branches - the SP macros support this). If you specify this global "baseless" parameter (specified at the startup macro and controlling all SP macros and the lightweight CALL and PROC macros), there is only one base register which covers the area after ENDPROC, allowing for up to 4 k of local static variables (this is the default, of course you can have more, but if your function blocks are small
and you have many of them, your module size if virtually unlimited).

I cannot share these macros, but if you want me to write similar macros for your company,
contact me offline.

to Frank specifically: PERFORM is CALL, and J is GOTO ...
PERFORM is ok (from Dijsktra's point of view), as it leaves the structure of your program intact, but J is not (see: "Goto Statement considered harmful"). The use of the SP macros should lead
to programs that get rid of all branches.

Kind regards

Bernd



Am 17.05.2016 um 19:43 schrieb Swarbrick, Frank:
This is exactly true.  That being said, I don't know how structured programming 
macros can be used for 100% of your code if you want to also use the minimum 
number of instructions possible.  These two things appear to be in conflict.

For example, I did this simple code:

     IF (TM,0(R6),UEPPSB1,O)
         J     PSBFUNC
     ENDIF

Which generated this:
           TM    0(R6),UEPPSB1
           BRC   14,#@LB5
           J     PSBFUNC
+#@LB5    DC    0H

But without using the macros I'd simply do this:
           TM    0(R6),UEPPSB1
           JNO   PSBFUNC

So it seems like there might be implied guidance to not use an IF macro if the 
only conditional code is a branch.  Or is there something I am missing?  I know 
there is DOEXIT, but that doesn't really fit in this case.

I should qualify that I know that I *could* do something like the following:
     IF (TM,0(R6),UEPPSB1,O)
         [lots of code here]
     ELSE
         [lots of code here]
     ENDIF

I choose not to because I have a philosophy, for higher level languages anyway, that if "conditional 
code" is more than a "few" lines it should be taken "out of line" and invoked.  For 
example, in COBOL, instead of

IF SOME-CONDITION
     [50 lines of code goes here]
ELSE
     [30 lines of code goes here]
ENDIF

I would do this:
IF SOME-CONDITION
     PERFORM 50-LINES-OF-CODE
ELSE
     PERFORM 30-LINES-OF-CODE
ENDIF

The compiler, of course, is free to bring the "performed" code inline.  And, of 
course, an assembler will not do that.

I have only been using the SP macros for a total of three days, so if I am 
missing a possibility please let me know!

Frank


Reply via email to