360ASM/instructions
360 instruction set arranged by op-code, to make the pattern easy to see.
You need to view / print this using a fixed font, so the columns line up.
Down past these tables are some comments about programming. When teaching
programming, there are 15 things that should all be taught first.
After you write and run a couple programs, things will start to make sense.
These are the classical 360 instructions, arranged by op-code. If you look at
them by op-code, you see ?9=compare ?a=add ?b=subtract ?c=multiply, ?d=divide.
?0=store ?8=load On the left is the first hex digit of the op-code, and at the
top of each column is the 2nd hex digit. Eg 05 is BALR, and 98 is LM.
There are 5 copies, with fewer instructions each time. The last one contains
all the instructions you're likely to use for quite a while.
0 1 2 3 4 5 6 7 8 9 A B C D E F
0 SPM BALR BCTR BCR SSK ISK SVC BSM BASSM BASR MVCL CLCL
1 LPR LNR LTR LCR NR CLR OR XR LR CR AR SR MR DR ALR SLR
4 STH LA STC IC EX BAL BCT BC LH CH AH SH MH BAS CVD CVB
5 ST LAE N CL O X L C A S M D AL SL
8 SSM LPSW DIAG BRXH BRXLE BXH BXLE SRL SLL SRA SLA SRDL SLDL SRDA SLDA
9 STM TM MVI TS NI CLI OI XI LM TRACE LAM STAM SIO TIO HIO TCH
D MVN MVC MVZ NC CLC OC XC MVCK MVCP MVCS TR TRT ED EDMK
F SRP MVO PACK UNPK ZAP CP AP SP MP DP
This is the same table, with the I/O instructions, and system instructions
removed because you'll never use them.
0 1 2 3 4 5 6 7 8 9 A B C D E F
0 BALR BCTR BCR SVC BSM BASSM BASR MVCL CLCL
1 LPR LNR LTR LCR NR CLR OR XR LR CR AR SR MR DR ALR SLR
4 STH LA STC IC EX BAL BCT BC LH CH AH SH MH BAS CVD CVB
5 ST N CL O X L C A S M D AL SL
8 BRXH BRXLE BXH BXLE SRL SLL SRA SLA SRDL SLDL SRDA SLDA
9 STM TM MVI TS NI CLI OI XI LM
D MVN MVC MVZ NC CLC OC XC MVCK MVCP MVCS TR TRT ED EDMK
F SRP MVO PACK UNPK ZAP CP AP SP MP DP
This is the same table again, with even more instructions removed, because I
never used them.
0 1 2 3 4 5 6 7 8 9 A B C D E F
0 BALR BCTR BCR SVC BSM BASSM BASR MVCL CLCL
1 LTR NR OR XR LR CR AR SR MR DR
4 STH LA STC IC EX BAL BCT BC LH CH AH SH MH BAS CVD CVB
5 ST N O X L C A S M D
8 BXH BXLE
9 STM TM MVI NI CLI OI XI LM
D MVC NC CLC OC XC TR TRT ED EDMK
F PACK UNPK ZAP CP AP SP MP DP
Same, with more removed, because it'll be some years before you use them, if ever.
0 1 2 3 4 5 6 7 8 9 A B C D E F
0 BALR BCTR BCR SVC BSM BASSM MVCL CLCL
1 LTR NR OR XR LR CR AR SR
4 STH LA STC IC EX BAL BCT BC LH CH AH SH MH CVD CVB
5 ST N O X L C A S M D
8 BXH BXLE
9 STM TM MVI NI CLI OI XI LM
D MVC NC CLC OC XC TR TRT
F PACK UNPK ZAP CP AP SP MP DP
Same, with even more removed. At first you're unlikely to use more than these,
and you're unlikely to use all of these. You might. But probably not.
0 1 2 3 4 5 6 7 8 9 A B C D E F
0 BALR BCR MVCL CLCL
1 LTR LR CR
4 STH LA STC IC EX BAL LH CH AH SH MH CVD CVB
5 ST L C A S
8
9 STM TM MVI CLI LM
D MVC CLC
F PACK UNPK ZAP CP AP SP
A few notes:
90% of all your programming will consist of a dozen or so instructions.
The maschoistic joy of assembler programming is that you do 2 things at once.
- Keep track of the object of what you're doing.
- Keep track of the instructions that you need to do the current task.
- If you're good, have a master plan indicating what you'll need later,
and save it as you're working.
There is no reason to use assembler today, other than if what needs to be done cannot be
done in a higher level language. More time and money is spent on program maintenance than
original coding, so the easier you make it for whoever comes along behind you, the better
you're serving whoever is paying to have the program written. (That said, it is fun.)
L loads a register. LA calculates a number, most often not an address.
EX executes another instruction, ORing the specified reg with the 2nd byte of the executed inst.
eg, if used with a decimal instruction, you can hard code one length and supply the 2nd length.
EX of an EX instruction creates a 0C3 abend w/o changing registers. IBM uses it all the time.
Registers: ALWAYS use regs 14, 15, 0, 1 when possible. 2-12 are to valuable to waste.
TRT instruction changes reg-2. It's the only instruction to do that. Never use 2 as base.
BCT / BCTR -- load the count reg with the number of times to go through the loop.
When you want to multiple a register, if you can, MH (multiply halfword) because it's easier
to remember, uses fewer registers, and doesn't have the even-odd register restriction.
There are application / utility programmers, and system programmers. They are equally good.
Some programs start, read, manipulate, and write data, and exit.
Other programs live in memory and are used over and over, generally as subroutines of other code.
If your program is used over and over, it has to be "re-entrant". That means that it cannot
change any work areas that is uses. If it needs a work area, it must "getmain" some memory,
and use that as work area, freeing it when it's done.
Programs that start, run, and exit, can do whatever they want with their memory.
There is no reason to make such a program re-entrant.
In general, these are utility or application programs. That's what I've always done.
You'll have seen the traditional BALR start of a program. I use reg-13 as save area & base.
This does NOT work for a re-entrant program.
I personally assign base registers 12-on down, and data regs 2-up
When I was coding, a base-reg was good for 4k. Today you can be 64k. You only need one.
If you need more, you're probably making a mistake. But you'll have to ask someone else
how to do that. I never did learn.
You'll note when writing a program, that there are instructions that get executed,
and there are instructions to the assembler about how to create the instructions to run.
START tells the assembler that you're going to create a program.
USING tells the assembler that, in this case, reg-13, will contain this address.
DC and DS tell the assembler to reserve memory, and, with DC, what to put there.
STM is a real instruction that gets translated to x'90' and gets executed.
NAME START 0
USING *,13
B AAAA-NAME(15)
DC 17F'0'
DC C'NAME VER 01.01 ASM &SYSDATE AT &SYSTIME'
AAAA STM 14,12,12(13)
ST 15,8(13)
ST 13,4(15)
LR 13,15
Using z390, I like my programs to align on a 4k boundary. It does waste memory.
But it makes instruction offsets and locations easier to map. This is the code I use.
ENDDOC DC X'00'
@@PAD#1 EQU ((*-NAME)/4096+1)*4096 <== adjust this # to multiple of 4k.
@@PAD#2 EQU @@PAD#1-(*-NAME)
ORG *+@@PAD#2
END NAME
This is a very simple program to copy a file.
GENER START 0 I'M GOING TO WRITE A PROGRAM
SAVE (14,12) SAVE CALLER'S REGISTERS
BALR 12,0 SET MY BASE REGISTER
USING *,12 TELL THE ASSEMBLER ABOUT MY BASE
LA 2,SAVEAREA POINT TO MY SAVE AREA
ST 13,4(2) SAVE A(CALLER'S SAVE AREA) FOR LATER
ST 2,8(13) SAVE A(MY SAVE AREA) IN CALLER'S AREA
LR 13,2 PUT MY S/A ADDR IN REG-13
*
OPEN (INFILE,INPUT,OUTFILE,OUTPUT) OPEN FILES
READ GET INFILE READ A RECORD
LR 0,1 PUT IT'S ADDRESS INTO REG-0
PUT OUTFILE,(0) WRITE THAT RECORD
B READ AND LOOP TO READ
*
ENDFILE CLOSE (INFILE,OUTFILE) ALL DONE, CLOSE FILES
L 13,4(13) LOAD ADDR OF CALLER'S SAVEAREA
LM 14,12,12(13) LOAD CALLER'S REGS
OI 19(13),X'01' (INDICATE THAT WE HAVE RETURNED)
SR 15,15 SET RETURN CODE=0 (GOOD COPY)
BR 14 RETURN TO CALLER (OPERATING SYSTEM)
*
SAVEAREA DC 18F'0'
INFILE DCB DDNAME=IN,DSORG=PS,MACRF=GL,EOD=ENDFILE
OUTFILE DCB DDNAME=OUT,DSORG=PS,MACRF=PM
END
In the real world, files have records, and those records are
combined in blocks. Data files will have record lengths
and block lengths. Maybe a record length might be 80,
and a block length might be 1600.
A DATA CONTROL BLOCK or DCB to use this data might be
DCB LRECL=80,BLKSIZE=1600
If you're reading a file, that information will exist in the
file definition, so you don't worry about it. You MIGHT
have to specify it for a file that you are writing.
OR, you might copy that information from the file you're reading. EG
* ---------------------------------------------------
DC A(EXITLST+X'85000000')
USING *,15
EXITLST CLI OUTFILE+36,0 Q. RECFM ALREADY THERE?
BNER R14 YES, SKIP THIS
MVC OUTFILE+36(1),INFILE+36 RECFM NO, COPY
MVC OUTFILE+52(2),INFILE+52 BLKSIZE FROM THE
MVC OUTFILE+82(2),INFILE+82 LRECL INPUT FILE.
BR 14
OUTFILE DCB DDNAME=OUT,MACRF=PM,DSORG=PS,EXLST=EXITLST-4
INFILE DCB DDNAME=IN,MACRF=GL,DSORG=PS,EODAD=END
* ---------------------------------------------------