C_CXX_Cafe_Metal

advertisement
Using the METAL option in the XL C compiler
Power tool
Assembly language is powerful. It is close to the underlying hardware architecture; it allows you
to access low-level system features, interacting closely with the operating system; and it has no
runtime dependency. In short, it allows you to do almost anything you want.
But assembly language forces you to spell out all the minor details in the code. You need to focus
on the leaves and trees, not the forest and the landscape. You need to spend time on the lowlevel details and not the high level logic. You need to hand hold the underlying machine every
step of the way. It is tedious. An assembly program can take time to write and debug. The
resulting code can be difficult to maintain.
Wouldn’t it be nice if you could use a high level language to do low-level programming ?
The METAL option of the XL C compiler is designed with this in mind. The concept of metal is
such that the code generated can inter-operate with code written in assembler and therefore is
close to the hardware – the metal. With the METAL option you can now use C language features
to express low-level programming logic, for example writing user exits. You are freed from the
tedious tasks such as managing the registers and developing the correct instruction sequences.
Let us take a few moments to look at what the METAL option can do.
Close to the metal
The XL C compiler generated code requires the Language Environment to establish an overall
execution context. The C library functions also require the Language Environment in order to
provide their services; most noticeably the functions to manage the heap storage and dynamic
storage area, to do file input-output, and to handle exception conditions. If your C program needs
to get close to the metal, it needs the means to acquire these services directly from the operating
system. Since you can only acquire these using assembler macros, the compiler needs to
incorporate your assembler statements in the C program. The compiler also needs to make the C
program to follow conventions expected in the operating system environment.
As a first step to achieving the above, the METAL option generates code in assembly source
program format. You can then feed the assembly source through the High Level Assembler, like
any other assembly programs. The resulting code is independent of the Language Environment.
You can write a statement like if (x + y * z > 0) x = -x, and the XL C compiler will
turn it into assembly instructions. You work on the high level logic, and the compiler generates
assembly code. The code is close to the metal.
Keep things local
One reason why a normal C program requires support from the Language Environment is the
requirement of a stack, on which local variables reside. Normal C code relies on the runtime to
manage this stack. When doing low-level programming, this could be a roadblock as you might
have your own storage management scheme.
METAL C gives you control of stack allocation by letting you customize the function prolog and
epilog code. This is code generated by the compiler at the beginning and end of a function to
acquire sufficient storage for local variables. METAL C provides a default code sequence; but you
can override it by providing you own. You can allocate the stack according to your own scheme.
Protect your investment
But what about the existing library of high level assembly code? These are often the result of
years of cumulative work, encapsulating the knowledge and experience of many skilled
programmers. You don’t have to throw them away. METAL C allows you to tap into these
treasures.
Function calls and argument passing in METAL C follow the MVS linkage convention. For
example, when you call a function from C, the compiler will set up the arguments so that register
1 points to the parameter list, like you would when calling an assembly routine. When coding the
C call statement, you just treat the assembly routine like any other C functions -- the C programs
and your assembly programs are interoperable. You are now poised to enhance your collection of
assembly programs with new additions written in C.
The pearls
Well, you might say, all these are fine, but it is not just assembly routines which we need to worry
about. It is assembler macros that contain the pearls of low-level services. There is a large body
of system services which are available only as assembler macros; and you may have a few of
your own. These are good stuff, and can be accessed only through assembly code. We need a
way to open the clamshell and get the pearl.
No problem; METAL C has a clamshell opener -- you can embed a short sequence of assembly
instructions inside a C function, in between other C statements. Further more, you can reference
the values in C variables from these assembly instructions. For example, within a C function, you
can set up the parameter values for the STORAGE macro, call the STORAGE macro, and then
return the obtained storage address in a C variable. All these can be done within a C function.
You can even develop a C library to get at the system services, and design a high level
application interface tailoring for your purpose.
The key is in the register
Sometimes an application written in assembly code may put aside a certain register for a special
purpose throughout the application, using it to hold the address of a key data block, for example.
This is done for efficiency. Of course, you can use embedded assembly instructions as described
above to access the data block. But METAL C provides an even easier way – you can tie a
register to a pointer variable. The address value in the C pointer is the address stored in the
register. You can declare a C structure representing the layout of the data block, and then access
the data through a pointer variable in C expressions. No assembly code is needed.
And reaching far …
Speaking of pointers and data blocks, what if you need to manipulate a very large table of data
and you are not ready for AMODE 64? An application written in assembly code may use data
spaces to do it. METAL C allows you to access data spaces through far pointers. These are C
pointer variables but wider – the lower half is an address within the data space; the upper half is
the ALET. You can use a far pointer like a normal pointer; you can deference it,
increment/decrement it, compare it with other far pointers to the same data space, etc. You can
write a sort routine in C, for example, to sort the data, and then call this C routine from existing
assembly code. You can now exploit the advantage of data spaces using a high-level language.
But what about printf() ?
Well, printf() needs the Language Environment, as do other C library functions. Since we want the
code to be independent of the Language Environment, we don’t have the full C library. But all is
not lost; we still provide a useful subset of these functions in the METAL C library. Please refer to
the companion article for more details. We cannot provide normal input-output functionality, but
we can still provide functions like sprintf(). Not printf(), but sprintf(), which is equally useful. You
can still enjoy the convenience of %-substitution in the format string; and you can emit the
resulting string in a buffer. You can print this buffer using, for example, WTO.
Putting it all together
The above represents some significant additions to the XL C compiler, and they are available in
the z/OS V1R9 release. You can use these features in a number of ways. As indicated in the
above, METAL C does not require you to rewrite your existing assembly code. METAL C code is
meant to inter-operate with existing assembly routines, and work without the Language
Environment. You can use it when adding new features to your existing application written in
assembly language. Your investment in existing code is protected, and you can leverage them
using a programming tool that can better express the high-level logic. You can rewrite selected
routines in C, if you like. You might want to do this for the code that requires frequent
maintenance. And, of course, you can write user exists in C. You have a power tool to work close
to the iron. To top off all these, you can enjoy the capabilities exist in the XL C compiler to
optimize your programs tailored to the latest hardware you have.
For further information on the METAL compiler option and related features, see z/OS V1R9.0 Metal
C Programming Guide and Reference (SA23-2225-00) and z/OS XL C/C++ User's Guide (SC094767-06).
Download