This is a collection of hints, tips, and code samples that may be
useful to people who are thinking of developing programs in assembler.
The usual disclaimers apply to all code samples (including the MACROs').
Some of the techniques used here are somewhat dated and therefore you may
wonder why they are here. Well the simple answer is that they are still
useful/'memory' efficient/fast!.
There is a full XMI library with all of the listed macros in it that is
available from here.
| Diagnostics Made Easy(er) | |
| label EX R15,label> |
You can use this little trick to debug your assembler programs.
This code will cause a S0C3 Abend. There are two main reasons for wanting to do this; firstly the registers are left unaltered by the Abend, and secondly this is the only way to get an S0C3 so you can rule out any other statements. We have included a link to our CRASH macro that will issue this abend. |
|
|
|
| Swapping Register Contents | |
|
CR Rx,Ry BE *+10 XR Rx,Ry XR Ry,Rx XR Rx,Ry |
This little trick can be used to swap the contents of two registers. It is
neat in that it uses no additional storage and because of this it is useful
when the size of the program is becoming an issue. In fact this method only
uses 12 bytes, but only 6 if you exclude the compare.
The initial compare will prevent the register Rx from being made zero if the contents of both registers are equal. We have included a link to our SWAPREG macro that will swap two registers here. |
|
|
|
| Perform Once Mechanism | |
|
SWITCH1 NOP DEST . . execute once code . goes in here . OI SWITCH1+1,X'F0' switch DEST DS 0H continue from here |
Sometimes it is necessary to execute a sequence of instructions only once even if the code is called several times. Although good programming practice is usually to steer well clear of self modifying code, here is a piece of code that alters the branch in the NOP from 'never' branch to 'always' branch. In this example the NOP at SWITCH1 is flipped from a branch '00' (never branch) to a branch 'F0' (always branch) so that after the first iteration subsequent runs through the code will branch round to DEST and not execute the code between the SWITCH1 and DEST. |
|
|
|
| Hexprint Macro | |
|
L Rx,value LA Ry,WTO+8(8) HEXPRINT Rx,Ry WTO WTO 'RxRxRxRx = Contents' |
This is a HEXPRINT macro. Basically the contents of the first register
specified (Rx) are converted to
printable characters and placed at the location whose address is loaded
into the second register (Ry).
It can be used several times within the same program. Click the link below
to download the macro. All that we ask is that you leave the Copyright
information in it please. We frequently use this macro for diagnosis and
tracing.
|
|
|
|
| How to make hex code printable (part 2) | |
|
LA R0,8
Set loop counter LA R1,your_out_area Point to target area LOOP_it LA R2,X'0F' Prime R2 with 0F SLDL R2,4 Shift first nibble from R3 CH R2,=X'00FA' Is it F0 to F9? BL SKIP ...No, skip subtract SH R2,=X'0039' Subtract 39 to get Hex letter SKIP STC R2,0(R1) Store the character into R1 LA R1,1(R1) Skip up output field BCT R0,LOOP_it Loop until done |
This piece of code is pretty useful for making the hexadecimal value in R3
printable, however it does require that contents of registers 0-2 get
'destroyed', therefore we urge you to save the contents of those registers
before using this code if the contents of them are important to you.
This code is best used in it's own little subroutine where the registers get
saved on entry and restored on exit. The other advantage of using this code
is that it does not require any other assembler macros, so it is usable 'out
of the box'.
|
|
|
|
| Write to Programmer Macro | |
|
Label1 WTP 'Test message' |
This simple macro is used in the exact same way as the IBM supplied WTO
macro, the only difference is that the WTP macro will set the
routing and descriptor codes so that the message should not appear on the
console.
You may need to check with your site system programmer to make sure that they haven't changed the IBM standards for routing and descriptor codes. |
|
|
|
| Folding to Uppercase | |
|
Label1 OC FIELD,=256C' ' Fold to Uppercase
|
This code will fold the contents of FIELD into all upper case characters.
If you really don't want to use XL256 then you can simply replace 256 with
the length of FIELD.
We have included a link to our UPPER macro which will generate this code. |
|
|
|
| Random Number Generator Macro | |
|
Label1 RANDOM 1,100 Generate random number * Between 1 and 100 |
This simple macro will generate a random number (based of the IBM TIME macro)
between the two numbers specified on the macro call. The number is returned
in binary form in general register 0. To convert the number into printable
format you can use our HEXPRINT macro (detailed above).
(Note that the contents of both registers 0 and 1 will be trashed by this macro as it uses the TIME macro) |
|
|
|
| Checking for a DDNAME | |
|
Label1 DEVTYPE =CL8'yourdd ',DEVAREA Look for yourdd DD LTR 15,15 Did we have one? BNZ Not_Found No - Go and do something . . DEVAREA DS D For DEVTYPE call |
This sample shows how to check to see if a JCL stream contains a particular
DD Card (yourdd).
Obviously 'yourdd' should be replaced with something useful (like SYSIN). If you want to check for a generic DD statement then you can always say: |
|
|
|
Abbydale Systems LLC Lic. 802696149. All rights reserved.