MOM Pt. 004: Writing simple COBOL on MVS3.8 tk4-

Hello again!

Wow, I have to say… I feel good! Do you feel good? I really hope you do.

Today I have planned to write my own very first piece of COBOL code. That means I’ll write my own JCL to compile the COBOL and execute it. Let’s keep it simple today. To be honest, that’s an easy way to hide the fact that I don’t fully know what I’m doing, haha. The next step will be writing COBOL code that reads a data set? But before I do that, I want to make some blogposts on Zowe first, as Master the Mainframe 2019 is approaching!

Is this blog a tutorial? Hmm, it might be. I just write about what I’m doing in a tutorial-like way. Why? Because I like to document stuff, weird, I know. I want to explain the COBOL and the JCL I am writing. I hope to do a good job as I don’t want to blunder, after all, you never know who reads this. Hi FBI!

Today’s assignment

Hello world! KIDDING! That would be too much of a Kevin thing to do. Let’s make a FizzBuzz. This will learn me how to code a fizz buzz and it might help you during a coding interview. There’s tons of FizzBuzzes out there, probably also in COBOL, but this one will be explained, coded inside a mainframe, executed by JCL and made with tons of love.

So what is a FizzBuzz?

A FizzBuzz is a very easy programming task that’s used in most software developer interviews. It was invented by Imran Ghory.

Write a program that prints the numbers from 1 to 100. But for multiples of three print “Fizz” instead of the number and for the multiples of five print “Buzz”. For numbers which are multiples of both three and five print “FizzBuzz”.

So let’s do this in COBOL, compile it using JCL and see if I can get it to work. For this blog’s purpose, I’ll code the simple version of FizzBuzz.

Pre-Workout: the JCL

We’ll copy the JCL from TESTCOB that we’ve reviewed last time. Don’t worry, copying code is not a crime as long as you know what the code actually does.

So I went to RFE (1), UTILITIES (3), DSLIST (4), entered data set name prefix SYS2.JCLLIB, edited SYS2.JCLLIB and I made a new member using the primary command s.

After this the new empty member was created.

Into the new member FIZZBUZZ I want to COPY TESTCOB. This can be done with ease using, you’ve guessed it, COPY TESTCOB.

Done, all copied! So what’s next? First we’ll take note of Marco’s comment and rename the job to our user profile name. In my case it’s HERC01.

I have changed TESTCOB to HERC01. I also have made some other small changes. There might be some issues running the job as we’re using our username as the jobname, we already have a job running with our name the moment we login. So that’s the reason it will ask for a jobname.

Workout: the COBOL

Defining variables in COBOL

So there was already a constant defined called HELLO-CONST. This variable was defined in the WORKING-STORAGE section. I have done the same, I have defined three new variables called WS-FIZZWS-BUZZ and WS-FIZZBUZZ. I prefix them with WS to let others know that this is a variable in the WORKING-STORAGE section. This is a common practice.

Every variable except for indexes are defined with a level number. In this case the level number for WS-FIZZ is 77, not cool, but ok. Most companies don’t like using level number 77 as it wastes space, some even have a policy against using it. For more details about this visit

Looping in COBOL

In addition to the above mentioned text working storage variables I have defined 3 numeric variables that can each be up to 3 (numeric) characters long. I have initialized WS-I variable with 1, as we don’t want to check 0 for fizzbuzz. The other variables I have initialized with 0. WS-I is short for working storage indice and WS-R is short for working storage remainder.

PERFORM CALCUL UNTIL WS-I > 99. This line of code performs the “function” named CALCUL until the WS-I variable is larger than 99. After that it will stop the execution. I know, CALCUL is not an ideal name, but say it out loud. Sounds cool right?

Biggest COBOL amateur at work

Believe me, this is so embarassing. I had so much troubles with the COBOL section, it is unreal. The END-IF should begin A-MARGIN. But I couldn’t start my IF in the A-margin? Also COBOL expected a condition for the else? But when I provided a condition it didn’t work?

Well then, I guess I’ll have to work around the fact that I can’t use ELSE.

Lo and behold the production of me learning COBOL for 2 hours on a friday night. Because I can’t use the ELSE for some reason, I just checked if WS-R was bigger than 0 and then called the next “function” in line.


The line of code above equals to WS-QUOTIENT = WS-I / 3 and the remainder value will be stored in WS-R. The result of this statement will be stored in WS-QUOTIENT. If you’re not familiar with this, you’re probably thinking: “But 45/3 is not 0? So it can’t be FizzBuzz with this code?”.

It works like this:

  • 45 divided by 15 equals 3. The remainder is 0, so it’s FizzBuzz.
  • 48 divided by 15 equals 3.2. So the remainder is 0.2, not FizzBuzz.
  • 48 divided by 3 equals 16. So the remainder is 0, so it’s Fizz.

I really don’t like putting this ugly code out here, but I just kind of felt like it. If any of you would like to help me out, or yell at me, feel free! 🙂 I can do better sir, just not right now, heheh. (sweating)

Does it FizzBuzz?

Let me check! SUBMIT, check the output via RFE > 3.8select the job and see.

I really did it! I have to say, I never expected to get this far with the little COBOL learning I did. To conclude, I really should study and practice before I just start doing things.

Up next: Zowe?


Not too long ago Zowe has announced that it’s now available on IBM Z Trial! It’s only a 3 day trial though. So this means I’ll have to request the trial on a friday so I can solve the introduction and blog about it in one weekend.

Zowe will also be used in the new Master the Mainframe 2019 challenges, so this will be a very nice warm up to prepare us for that big moment in september!

Share this:

MOM Pt. 003: Getting to know COBOL – Compiling

Today I’m going to get to know COBOL. I’ve already used COBOL in IBM’s Master the Mainframe 2018 contest, but this time I’m working in MVS 3.8!

What am I planning to do here? Well, before I start learning COBOL I want to know how I can edit, compile and run it on my own mainframe. MVS3.8 provides a small piece of test code in SYS2.JCLLIB called TESTCOB.

So I go to RFE. Then I need to navigate in the DSLIST utility, so that means I enter 3.4 to quickly get there. The data set name prefix is SYS2.JCLLIB. When editing, I am able to scroll down and edit TESTCOB.

So this is TESTCOB. Normally any piece of COBOL production code has four divisions.

    • Here we identify the COBOL program, the name of the program itself. Typically, the program documentation goes here.
    • Here we link the program with external data sets.
    • Here we define the local variables, exclusive to this program only.
    • Here we code all our logic.

As you can see on the image below, TESTCOB indeed has the four divisions.

Now what have I highlighted in pink? Those are sections. Sections can be omitted but they have chosen not to in this case. At line 000027 you can see 000-DISPLAY, that is a routine. The next two lines are statements/sentences inside a paragraph. These state that the machine needs to DISPLAY the HELLO-CONST in CNSL. The HELLO-CONST is defined at line 000025 in the data division. CNSL is an alias for CONSOLE defined in the CONFIGURATION section. The code pretty much speaks for itself right? Display HELLO, WORLD in the console and then STOP running.

Now what is HELLO-CONST PIC X(12) VALUE ‘HELLO, WORLD’? This means that HELLO-CONST can carry 12 bytes. 1 byte equals to 1 character in an EBCDIC mainframe. You can see as a template, in theory HELLO-CONST is XXXXXXXXXXXX. We fill those X’s with ‘HELLO, WORLD’, X means the repetition factor meaning X is repeated 12 times.

SPOILER ALERT: change MSGCLASS=A to MSGCLASS=H on line 000004!

When you’re finished checking this file, enter the primary command save to save your changes. To execute your program, enter the primary command submit.


To check our output we need to go back to the root RFE and navigate to the OUTLIST (3.8). Select the correct job by using the line command s.

Kevin’s Coding Blog is experiencing technical difficulties

It’s not here? Where is it? The COBOL job isn’t outputting to the OUTLIST?

Please allow me to add some Google tags for those with the same issue: cobol mainframe MVS 3.8 tk4 no job output help sysprint please google.

I forgot to change the MSGCLASS to H. This means you want the output from the compiler to be held. Now let’s submit it again and check the output.


Yes I know, 25… I’ve been struggling. Again the job output was empty, but after entering the primary command ST * I can see all the jobs.

TESTCOB is there! Now I’ll select with s and see what it did.

There it is! HELLO, WORLD. We have done it!

Next up: our own custom mix of JCL and COBOL!

Are you experiencing any technical difficulties?

Tell me all about it!

Share this: