MVS TOOLS AND TRICKS OF THE TRADE MAY 2005 Sam Golob MVS Systems Programmer P.O. Box 906 Tallman, New York 10982 Sam Golob is a Senior Systems Programmer. He also participates in library tours and book signings with his wife, author Courtney Taylor. Sam can be contacted at sbgolob@cbttape.org. Information about the CBT MVS Tapes can be found on the web, at http://www.cbttape.org. ACCUMULATING KNOWLEDGE IN ASSEMBLER Only the old-timers in MVS systems programming remember when this job actually involved an extensive amount of programming in Assembler language. That era ended around 1980 or so. After that time, our job requirement became mainly the setting up of the MVS operating system when necessary, and the installation of fixes. We may also debug day-to-day problems, or more often, we merely report them to the various vendors' support lines. And we generally keep our firm and alert fingers on the general health of the system. This leaves very little requirement for us to do any writing of code in Assembler. So many of us do not get any Assembler practice as part of the job. There actually exist a lot of "systems programmers" who never do any programming. And after the "Assembler Coding Era" for MVS systems programmers ended, the tendency, both from IBM and from the vendors, was (perhaps unintentionally) to tacitly discourage the use and knowledge of the Assembler language among MVS support people. Intentionally or not, the tendency was there. OCO (Object Code Only - no source) distribution of the operating system and vendor code, was becoming the rule, even more so among the vendors than with IBM, and as a result, MVS systems programmers were getting less and less of a chance to learn about what really makes their system tick. Another blow that took away systems programmers' Assembler programming practice, was the general replacement of user modifications to the system, by system exits. This was practical. Installations who modified the operating system would later have to re-fit their modifications to later operating system versions. This discouraged the installation of new system releases, and it presented a problem to all the vendors. As a remedy, IBM and the vendors added exit points to their code in places where the users frequently wanted to make their installation-dependent changes. So instead of having the users modify the main code, they would merely code a (hopefully release-independent) user exit and hook it in to the vendor's product at a strategic, vendor-determined point. But that practice, as necessary as it was, also tended to reduce the amount of Assembler coding required in this job. Now the question remains: Why should we all have to know Assembler language? The answer is that even though much of the system is coded in PL/X by IBM, it all boils down to Assembler code eventually. We can safely say that for all practical purposes, most of the MVS system is written in Assembler language. So if you understand Assembler language and you know about the system interfaces to the various components of MVS, you have an excellent chance of learning a lot about how the MVS system components work. If on the contrary, you don't know Assembler language, you have very little chance of acquiring any in-depth knowledge about MVS at all. And in this business, that is an enormous handicap. FIGHTING THE GENERAL TENDENCY Starting in the mid-80s, many of us have tried to "buck the tendency" of excluding Assembler programming practice from the the MVS system programmer's job. A person whose everyday work is in this field, and who is straining himself with the everyday tasks, might wonder when you can get an opportunity to write Assembler code as part of the job. The answer, I think, is in the writing of utilities. IBM has left us a lot of leeway in the "optional utilities department" of MVS, especially in writing utilities that work under TSO. TSO has most of the power of MVS itself, and while IBM itself has given us some completed tools and TSO commands in SYS1.CMDLIB, they have not come anywhere near supplying us with the capability of "doing things" under TSO which TSO is really capable of. But IBM has been nice to us in another way. IBM has supplied us with a wealth of system macros that provide access to a great many of the MVS internal facilities, and they have given us documentation about how to use them. With these macros, you can write utility programs to extend your powers under MVS in astonishing ways. But you have to know Assembler language to take advantage of this opportunity. And to learn the language you have to practice coding it. In the old days, the companies would send us to Assembler school. I think those days are pretty much over. Nowadays, I think the best way to learn Assembler is to look at other people's code. And it helps if you can crystallize your knowledge, a bit at a time, by making yourself a project to write one utility in Assembler and getting it to work. Then you can add to that, and write another utility, and then some more. That's the way to get going. There are a few Assembler language books, most of them pretty old, but for our purposes, one of them stands out. That one is: Advanced Assembler Language and MVS Interfaces: For IBM Systems and Application Programmers, by Carmine A. Cannatello and published by John Wiley, ISBN number 0-471-36176-3. Last I checked on Amazon, it was very hard to get. I myself learned the basics of Assembler from Kevin McQuillen's book, published by Mike Murach, which is still in print. All the coding examples from Carmine Cannatello's book are available for free, on the CBT Tape, in File 069. Do a www.google.com search on "CBT Tape" to get to this enormous free collection of MVS goodies. I'll give you one example about what I was able to write, just to show you the kind of power you can create by writing in Assembler. (This is not to disparage REXX and other languages--it's just that Assembler can go much deeper into the system.) The example is my set of programs to administer the SYS1.BRODCAST dataset, and TSO Broadcast data in general, which is on File 247 of the CBT Tape collection. Most of my programs can write directly to the SYS1.BRODCAST dataset without being APF authorized. (You just need RACF Update authority to SYS1.BRODCAST.) SYS1.BRODCAST is a DSORG=DA keyed dataset which needs special methods to access it. I can duplicate IBM's way of doing that, in Assembler language, and I can also duplicate IBM's enqueues to make sure that IBM's SEND and LISTBC commands will not update SYS1.BRODCAST at the same time I am doing any updating. I challenge you to do something similar in REXX or in another language. It's highly unlikely. If you want to see my code, just download File 247 from the CBT Tape, and you can learn all the stuff necessary to do this yourself, if you need that kind of information, or if you're just curious. I don't expect any of you to try and do what I've done. But my stuff is available for you to get information from. So is a lot of other people's code, in the over 700 files that are on the CBT Tape collection itself, and in the almost 300 files on the CBT Overflow Tape. At www.xephon.com there are a lot of coding examples too, in the free code that is more than two years old, which they give out. The beauty of Assembler coding your own utilities is that you can do your own work, in areas of MVS that will help you yourself, and your own shop. You should create, and have fun doing it! Now let's get to the real point of this article. Practically speaking, it takes time and effort to accumulate Assembler programming knowledge, to the point where you will accomplish what you want to do. I'm going to show you a few hints about how I've progressed over time, and I hope that I can help you achieve fantastic satisfaction and very tangible results. ACCUMULATING ASSEMBLER KNOWLEDGE I don't have space to talk about too many specifics here. It's ATTITUDE that I'm trying to give over. The right attitude is the tried and true way of accumulating Assembler knowledge. The first thing you have to know in Assembler language, is how the instructions work. While you're learning that, ONE INSTRUCTION AT A TIME, you have to also learn to use the special commands which tell the Assembler compiler (known as "the Assembler") what to do. You have to learn the general concepts of how a program keeps track of where it is, by means of "base registers". And you have to learn how these base registers are loaded with the proper data, so they work the way you want them to. The Assembler's USING instructions are the means of keeping track of where the program thinks its locations are. Anyone can refer you to IBM's "Principles of Operation" manual, and tell you to start there. But the "PrinOp" is a very forbidding place to start for a beginner, and it's my job, for the rest of this article, to try and make your progress easier, more enjoyable, and doable. One nice thing about MVS is that the old stuff that was written years ago, will continue to work on new systems, unless some internals have changed significantly. And the old ways of entering a program, saving the registers, and returning back to the caller or the system, still work just fine. In fact, I much prefer to use the old ways of entering and leaving a program, to the new BAKR and PR method, because my programs will work on older MVS systems as well as on the new ones. The main idea in (eventually) getting expertise in Assembler programming is to learn ONE THING AT A TIME. This idea is so important that it should be your watchword. "One thing at a time." For example, once you learn about the LOAD and STORE instructions, and get that idea into your head once and for all, you'll never again confuse the LOAD instruction with the LOAD ADDRESS instruction. Confusing those two instructions is the source of a large percentage of Assembler programming errors with beginners, and even with some more advanced people. It goes like this. The LOAD instruction will take four bytes of storage, starting at a beginning location, and dump those four bytes, unchanged, into a register. The STORE instruction does exactly the opposite. STORE takes the entire (4-byte) contents of a register and dumps it, unchanged, into a 4-byte chunk of storage starting at a given location. LOAD and STORE just move data between a register and storage. But LOAD ADDRESS does arithmetic. LOAD ADDRESS adds numbers together. LOAD and STORE don't. They just move data. So when you get that straight, you won't ever confuse LOAD and LOAD ADDRESS again. The process of "Learning Assembler" consists of learning new things like this, many times over. And there's so much to learn, that people tend to get discouraged and don't bother learning more. Looking at what you don't know, is not the way to go. Using what you DO KNOW, and adding to it, one thing at a time, IS THE WAY TO GO. That principle is so important, that if you just learn it, without any other specifics, from this article, then I've already done my job. Condition codes are an important thing to learn about. Some of the assembler instructions change the condition code, and some of them don't. An instruction that sets the condition code (which is one nibble of bits 8, 4, 2, and 1) can be followed by another instruction which reads the current condition code (like a BRANCH instruction) and acts according to what it sees. It's another thing that you have to learn, but if you do it "one particular thing at a time" and you're patient, I guarantee that you will eventually succeed. When people went to Assembler school (in former times) they would sometimes do "cutesy things" like writing an instruction that sets the condition code, and then writing a whole page of other instructions carefully, which don't change the condition code, and then afterwards code an instruction which reads the condition code that was set, 65 instructions back, and acts on it. I don't recommend such programming practices at all. I like to make my programs straightforward and readable, and I try to comment each line. Assembler is a hard enough language to learn in the first place. (Remember--one thing at a time.) Making it harder by confused coding, is downright cruel to the next guy. It's sort of like trying to follow ALTER instructions in a big COBOL program. Once you've gotten some expertise in Assembler coding, after having followed these principles, you'll be able to test yourself by trying to find 10 different ways of zeroing a register, and to know which of these set the condition code and which of them do not. This is the kind of question we used to get at job interviews 25 years ago. That's all very nice, and a way to measure your progress, but the main idea is to write simple, solid code THAT WORKS. Even if you don't know very much Assembler, if you can do that, you can pat yourself on the back and start enjoying what you can do. THEN ADD TO YOUR KNOWLEDGE, and do some more. The key is to do it gradually. And don't worry that there's so much more to learn. Just concentrate on what you know already, and try to add a little bit more to that. USE what you know already, and then add, and then USE THAT! SUMMARY Assembler knowledge is a very powerful thing to have, if you work with MVS. It's a lost art nowadays, but you can't learn about how the MVS system works, without it. Therefore, despite the fact that our working environment usually does not afford us the time or occasion to learn Assembler, we should all embark on it. We should all BEGIN, and then CONTINUE. The key idea in learning Assembler language is to do one thing at a time, and concentrate on what you already know, rather than on what you don't know. USE WHAT YOU KNOW, THEN ADD A LITTLE MORE TO IT, THEN USE THAT. In this way, you will succeed. It is the tried and true formula. I hope that old hands in this field, as well as new people, will gain from reviewing these ideas. They are very important in our job, even if Assembler programming is not encouraged, and nobody mentions it at work. If you push yourself in this direction, you will profit, and so will your work place. All the best of everything to all of you! I am looking forward to seeing you here again, next month.