...making Linux just a little more fun!

<-- prev | next -->

From Assembler to COBOL with the Aid of Open Source

By Edgar Howell

Introduction

Recently I had occasion to help convert an Assembler program into COBOL. The Assembler part of it was familiar to me from the old days of IBM Assembler 360/370/390, which was source-compatible with that used by Siemens, Amdahl, and others at one time or another on so-called "big-iron". For other than systems work, Assembler is gradually falling out of favor, not without justification, based on some of what I have seen over the last decade or so. Within this environment, COBOL is still a reasonable and viable alternative.

The Problem

The program in question was well over 6000 lines of code -- 8000 with macro expansions -- and easily would have taken several weeks to convert completely by hand. Only then could compilation and testing start. A nightmare.

Fortunately, for many years one of the participants in the project has been working on tools to improve the quality of Assembler code as well as to convert it to PL/1 or COBOL. But it is in the nature of Assembler that such a tool can never be finished. Many of the Assembler programs I've seen in the past remind me of a demolition derby: getting there is all that counts, it doesn't matter how you do it!

I was given a copy of the Assembler program in which each line had a unique line number, as well as a copy of the COBOL program produced by software which had references to the line number of Assembler code that caused generation of that particular line of COBOL code. And "all" I had to do was review the generated code and adapt it as needed. Hmmmm...

Manual Work

Had it only been necessary to make minor changes here and there, likely the task would have been quickly finished. But there were numerous places where something needed to be adjusted, often the same problem, just a variation on a theme, and another place where another change meant another chance of making a mistake.

To be sure, the vast majority of the software-generated code was in excellent condition - but this isn't horseshoes. Even though the customer will have to make final adjustments based on his operating environment, it just wouldn't do to turn the final product over with too many problems.

As it turned out, the biggest problem was that the software faithfully produced COBOL code that replicated the Assembler code very closely. Where the original code was clean, so was the COBOL.

Assembler vs COBOL

Here is a small example of the problem. The following Assembler code, which defines storage to manipulate the date (century, year, month day) -

    H1CYMD   DS    0CL8
    H1CYM    DS    0CL6
    H1CYY    DS    0CL4
    H1C      DS    CL2
    H1YY     DS    CL2
    H1MM     DS    CL2
    H1DD     DS    CL2

resulted in the following COBOL:

    01  H1CYMD PIC X(8). 
    01  filler6607 REDEFINES H1CYMD. 
            10 H1CYM PIC X(6). 
            10 filler6608 REDEFINES H1CYM. 
                    20 H1CYY PIC X(4). 
                20 filler6609 REDEFINES H1CYY. 
                            30 H1C PIC X(2). 
                            30 H1YY PIC X(2). 
                            30 filler6611-0 REDEFINES H1YY. 
                                35 H1YY-char PIC X(6). 
                            30 filler6611 REDEFINES H1YY. 
                                35 H1YY-2-char PIC X(4). 
                20 H1MM PIC X(2). 
            10 H1DD PIC X(2). 

Aside from the fact that this COBOL is pig-ugly, it isn't even syntactically correct!

However, this is not due to the software but the Assembler code itself: in the symbol table H1YY has a length of 2 because of its explicit declaration with that length, but the REDEFINES H1YY-char has a syntactically invalid length of 6 because that is the explicit length used with it at one point in the Assembler program. That's not syntactically incorrect in Assembler, but it is up to the programmer to know whether that length is reasonable to use. Originally, it was - but not in COBOL.

But there is no way I could have a chance of finding every situation like that by hand. Now what?!

Open Source to the Rescue

The Norns have been very kind to me of late. A while back I had discovered a COBOL complier for Linux but hadn't had the time to investigate it. The problem with it was that since it wasn't part of any distribution I had, I couldn't just grab an RPM and plop it onto one of the machines and expect it to function.

It was now time to make time.

Installing Open COBOL under SuSE 10.0

As usual, nothing ever goes smoothly the first time - and installing this package was no exception. In the following, I have omitted the false starts, other than to demonstrate what to do if that should happen to you. Basically, by not doing my homework up front, I gained a certain level of experience at that. Do pay attention to prerequisites when a package you are interested in is kind enough to let you know in advance.

The documentation that came with Open COBOL listed the following packages as required:

   libgmp      decimal arithmetic
   libtool     dynamic CALL statements

The following were optional:

   libdb       indexed file I/O and SORT/MERGE
   libncurses  SCREEN SECTION

Using YaST, I installed four of the following packages (listed as required for development) that were available but not yet installed:

   autoconf
   automake
   libtool     present
   gettext     present
   bison
   flex

Installation then went as follows (indentation indicates a different GUI window and CTRL-D exits root status):

mkdir /tmp/COBOL
cp /media/usb01/COB/open-cobol-0.32.tar.gz /tmp/COBOL/
cd /tmp/COBOL
tar xzf open-cobol-0.32.tar.gz
cd open-cobol-0.32
./configure

This failed because one of the required packages had not yet been installed. No biggie, I just opened another window and installed GMP.

      mkdir /tmp/GMP
      cp /media/usb01/COB/gmp-4.1.4.tar.gz /tmp/GMP/
      cd /tmp/GMP
      tar xzf gmp-4.1.4.tar.gz
      cd gmp-4.1.4
      ./configure

This also failed since I hadn't anticipated doing any "development" in this partition. So I fired up YaST and installed gcc as well as glib2-devel and glib2-doc (instead of glib-* since glib2 was already installed).

      ./configure
      make  

This took a tremendous amount of time to write endless messages to the screen. Well, that is what you will think if you have never run 'make' before.

      su
      make install

At this point you will need to note for later (export) the messages regarding /usr/local/lib or whatever.

      make clean
      CTRL-D  <end root status>
./configure

The following messages at the end are merely informative ("no" due to absence of optional packages):

            Use gettext for international messages: yes
            Use Berkeley DB for file I/O:           no
            Use fcntl for file locking:             yes
            Use ncurses for screen I/O:             no
make
su
make install
make clean
CTRL-D  <end root status>

Initial Tests

The only thing left to do was to see if it had been worth all the effort.

cd <directory_with_test_programs>
export LD_LIBRARY_PATH=/usr/local/lib
cobc hello.cob
./hello
Hello World!

After that I spent a bit of time playing around with what the compiler can handle. Here you can see a bit of code using decimal arithmetic -- which blew me away! But, then, that is what the GMP package is all about.

That worked so well that I decided to dig out an almost 20-year-old test program from a COBOL package that worked under MS-DOS. Minimal compiler error messages. And after I made comments of a couple of lines of code, the program compiled. And executed! Like access to the date and time in the machine, output to the screen, input from the keyboard. And I didn't have to change anything!

The Acid Test

OK, so it's time to see if this thing can help me with my real-world problem. I fed it the program I had been working on and among the error messages were:

/tmp/temp.cob:2081: size of 'filler6611-0' larger than size of 'H1YY'
/tmp/temp.cob:2083: size of 'filler6611' larger than size of 'H1YY'

I'm a believer!

Conclusion

While I may never have need to do any program development with this COBOL compiler, in a very brief period of time it has made a big impression on me. It seems to produce good code, although divide by zero didn't give the response I expected. Still, the ability to deal with decimal arithmetic is very impressive.

It seems to be very good at discovering syntactic errors in source code. I spent considerable time finding and fixing minor syntax problems that I never ever would have found just by reading the code. Exactly what I had hoped for.

And it ought to be perfect for anyone wanting to learn COBOL at home without the time pressure or expense of a formal class somewhere.

Due to dependencies, installing Open Source programs can turn into a bit of a pain, particularly if the discrepancies between your system and the requirements of the package are too great. But within reason this can be overcome, as you saw above. And in all likelihood, the accompanying documentation will let you know what is needed.

It can certainly be worth your taking the time to try out that package of interest.

Talkback: Discuss this article with The Answer Gang


[BIO] Edgar is a consultant in the Cologne/Bonn area in Germany. His day job involves helping a customer with payroll, maintaining ancient IBM Assembler programs, some occasional COBOL, and otherwise using QMF, PL/1 and DB/2 under MVS.

(Note: mail that does not contain "linuxgazette" in the subject will be rejected.)

Copyright © 2006, Edgar Howell. Released under the Open Publication license unless otherwise noted in the body of the article. Linux Gazette is not produced, sponsored, or endorsed by its prior host, SSC, Inc.

Published in Issue 126 of Linux Gazette, May 2006

<-- prev | next -->
Tux