gtpa2m37 | Application Programming |
There are special requirements for coding library functions in assembler. The first of these is knowing which registers are available and which are reserved for the TPF system. The second is understanding the prolog and epilog macros.
There are two kinds of assembler programs: those that call additional TPF services and those that do not. Programs that call additional services require prologs and epilogs. Programs that do not call additional services do not require prologs or epilogs.
For functions requiring prologs and epilogs, when the assembler program begins to run, the first statement is a BEGIN statement, coded with TPFISOC=YES. A frame is not automatically added to the call stack when an assembler program is run but if the assembler program calls other programs, the environment must be saved first, to retain the information needed to return to the original C function. The prolog macro, TMSPC, saves the C environment. The application base needed for assembler applications, CE1SVP, must be loaded before calling the entry point. Before a return statement (BACKC or EXITC macros), the epilog, a TMSEC macro, must be coded to restore the C environment.
TPF has its own set of register conventions, which have been adapted for use by the IBM C compiler. Some registers are reserved for TPF system use while others are used by the compiler for specific purposes. The register conventions for ISO-C and TARGET(TPF) are somewhat different. Most registers are available for application use and are saved and restored across function calls. Some registers are used by the compiler. These are not saved or restored across calls.
The following are summaries. See the TPF Program
Development Support Reference for more information about register
conventions.
Registers | ISO-C Convention |
---|---|
R0 | Available for application program use |
R1 | Available for application program use Used by the compiler for parameter list pointer. |
R2 | Available for application program use. |
R3 | Available for application program use. Used by the compiler as the code base. |
R4 - R11 | Available for application program use. |
R12 | Address of the TCA. |
R13 | Address of the DSA. |
R14 | Available for application program use. Used by the compiler as the link register. |
R15 | Available for application program use. Used by the compiler as the called function address and as the return register. |
Register | TARGET(TPF) Convention |
---|---|
R0 - R5 | Available for application program use. |
R6 | Parameter list pointer/function return value. |
R7 | Reserved, pointer to current stack frame. |
R8 | Reserved, program base. |
R9 | Reserved, ECB base register |
R10 | Available for application use but not saved across function calls. |
R11 | Reserved, always contains X'1000' |
R12 | Available for application use but contains X'2000' across external function calls and returns. |
R13 | Available for application use but contains TPF system stack pointer across function calls. |
R14 | Available for application program use, on function calls is used as the return address register. |
R15 | Available for application program use, used in external and library function linkage. |
Library functions written in assembler, as well as external functions linked to DLMs written in assembler, that need to acquire a stack frame, must begin with a TMSPC macro call when called from ISO-C functions or with an ICPLOG macro call when called from TARGET(TPF) functions. The TMSPC or ICPLOG macros must be the first instruction coded after the BEGIN macro. The code generated by these macros helps manage the programming environment of the C caller.
Earlier we talked about the need for stack blocks and stack frames. C functions use a stack for storage of local variables and parameter lists. The first time a C function is called, a stack block is attached to the ECB. In addition to saving registers, the TMSPC and ICPLOG macros are used to allocate additional space in the stack frame. Refer to TPF C/C++ Language Support User's Guide for details on TMSPC and ICPLOG.
The TMSEC and ICELOG macros are required for C library functions written in
assembler and for entry points written in assembler that need to acquire a
stack frame, like C written entry points. The TMSEC macro is for ISO-C
functions and the ICELOG macro is for TARGET(TPF) functions. Each one
deallocates the stack frame, restores the registers specified (or defaulted)
by the prolog macro, and returns control to the calling function. There
are two ways values can be returned, depending on their types: one way
is to put the value in a return register, the other way is to put a pointer to
the value in the parameter list.
Data Type to be Returned | ISO-C | TARGET(TPF) |
---|---|---|
Integer, Character, Pointer | RC=Rx | R6 |
float, double | 1st fullword of C parameter list | 1st fullword of C parameter list |
The epilog macros can be coded anywhere in the program and any number of times. However, it makes good sense to code it once, immediately before the exit point of a function or program.
All the functions in a library use secondary linkage if any one library function uses writable static or the library has active user exits. This results in performance losses for any function in the library. To keep these losses at a minimum, isolate the functions requiring writable static in less frequently used libraries rather than in libraries with frequently used functions and activate user exits only for libraries that require them.
Because library functions are not activated by way of the standard TPF ENTRC mechanism, there are certain considerations that must be kept in mind when coding a library function.
Figure 37 shows the same library function written in assembler. The function calls the TIMEC macro to generate an 8-byte EBCDIC time stamp. The function returns the address of the time stamp to the calling C function.
Figure 37. Comparison of Sample Library Functions Written in Assembler
* ISO-C version TARGET(TPF) version * | PRINT NOGEN | PRINT NOGEN BEGIN NAME=C001,VERSION=41, | BEGIN NAME=C001,VERSION=31 TPFISOC=YES | * | TMSPC FRAMESIZE=NO,LWS=R6 | ICPLOG HIGHREG=R5,FRAMESIZE=NO | L R5,CE1TCA | SL R5,=A(CSTKTCA-ICS0TK) L R5,ILWSUEXP | L R5,CSTKUEXP-ICS0TK(,R5) ST R8,ILWSLBAS | ST R8,CSTKLBAS L R8,CE1SVP | L R8,CE1SVP TIMEC , | TIMEC , L R8,ILWSLBAS | L R8,CSTKLBAS | LR R6,R5 TMSEC RC=R5 | ICELOG , * | LTORG | LTORG FINIS | FINIS END | END
The blank areas in the ISO-C version of the sample program are just for spacing in this example and are not present in an actual program.
The BEGIN macro in the ISO-C versions uses the TPFISOC parameter because the default (that is, TPFISOC=NO) C language is TARGET(TPF).
The prolog macros, TMSPC and ICPLOG, are called to save the environment of the calling program. The TIMEC macro requires the use of R5 in this example. Saving the environment is automatic with ISO-C support. In TARGET(TPF) we must instruct ICPLOG to save registers R14-R5 using the HIGHREG parameter.
When the prolog macros finish, the assembly language program has addressability to a stack frame. For ISO-C the stack frame is addressed through the IDSDSA DSECT in R13. In TARGET(TPF) it is addressed through the ISC0TK DSECT in R7.
In either ISO-C or TARGET(TPF) if FRAMESIZE=NO, the stack frame addressed is that created for the program call. If FRAMESIZE is a number, the stack frame addressed is the newly created one. Such an additional stack frame is necessary to preserve the environment if the assembly language program calls another program or requires temporary storage. Library functions typically would specify FRAMESIZE=NO because they perform some simple service and return to their caller. Specifying FRAMESIZE=NO minimizes the amount of stack required and enhances performance slightly by avoiding unnecessary frame generation.
The ISO-C LWS parameter provides a simple means for accessing non-volatile work space. The LWS parameter provides a DSECT (IDSLWS) for accessing the structures in the work space. The address of the work space is returned, as specified in the example, in R6.
In ISO-C, if the CENV user exit is active, the user expansion area can be added to the initial stack and accessed through the ILWSUEXP data area. In the ISO-C example the address of the user expansion area is moved to R5 to begin setting up the call to TIMEC.
In TARGET(TPF), if the CSK user exit is active, addressability to the user expansion area can be set up in R5 through the TCA of the current stack and the CSTKUEXP. Storage in this area has been allocated by the C language support user exit (see Customizing C/C++ Language Support) and in this example is used to contain the time stamp returned by TIMEC.
Because TIMEC is a fast-link macro, R8 must contain the base of the calling application program when the macro is called. The library base address must be saved before the call to TIMEC. The ISO-C example uses ILWSLBAS for this because addressability to it is provided by the LWS parameter of TMSPC. If TMSPC had been called without the LWS parameter, the ISO-C example would have used CSTKLBAS with FRAMESIZE=0 to save the library base, just as the TARGET(TPF) example does.
On return from the TIMEC macro, the library function restores its program base from CSTKLBAS or ILWSLBAS, as appropriate.
When the TIMEC macro returns, in this example the address of the time stamp is in R5. In the ISO-C example, the TMSEC macro places the contents of R5 in R15 before the return. Therefore, when the assembly language program returns, the return value is a pointer to the time stamp.
Similarly, in the TARGET(TPF) example, the address of the time stamp is copied to R6, the register designated to contain function return values. A TARGET(TPF) ICELOG macro is called to return control to the calling C function in the application program segment.