Chapter Contents

Previous

Next
Communication with Assembler Programs

Using Macros, Control Blocks, and DSECTs

A number of assembler macros provided on the SAS/C installation tape are useful when communicating with assembler. These macros, and the control blocks they describe, are discussed in this section.


The C Run-Time Anchor Block

The C Run-Time Anchor Block (CRAB) is the primary control block for the C library. Compiled code depends upon general register 12 addressing the CRAB. Among other things, the CRAB contains the following:

Some of the fields in the CRAB can be conveniently used in an assembler routine. Note especially the fields in Useful CRAB Fields.

Useful CRAB Fields
Label
CRABZERO
CRABDBL1
CRAB2P31
CRABUNMO
CRABDWK
CRABINTI
CRABNEGI
CRABEOST
CRAB16M
CRABTAUT
CRABUSR1
CRABUSR2
CRABUSR3
CRABTUSR

Note:    The distributed CRAB macro defines only those library fields associated with the systems programming environment (SPE). Some of these fields are used for other purposes when the full SAS/C Library is used.  [cautionend]

The uses of the CRAB constant fields such as CRABINT1 are obvious. An explanation of the use of the double to int (and int to double ) conversion fields is beyond the scope of this discussion, but an examination of the generated code for such conversions (via an OMD listing) shows how the conversions are performed. Similarly, the generated code for a built-in strlen function call shows the use of the translation table addressed by CRABEOST. The work area at label CRABTAUT is used by the compiler for functions with small automatic storage requirements and can be used by any C function.

Cautions

Keep in mind the following concerning the CRAB:


The CENTRY and CEXIT Assembler Macros

It is possible for assembler functions to be coded to use run-time facilities such as stack allocation and inclusion in abend tracebacks. Functions that make use of the C stack can be made reentrant more easily, and their display in an abend traceback (which prints the function name and the offset in the function) makes debugging abends easier. To make use of these facilities in the same way as compiled code, each function must begin with a CENTRY macro and return via the CEXIT macro.

In a program that runs with the =optimize or =minimal run-time linkage option, assembler routines must use the CENTRY and CEXIT macros if they call C functions.

When you use CENTRY and CEXIT, you must supply a CSECT statement before the first entry point; conventionally, the CSECT name should be the name of the first entry point, followed by the @ operator. (You can use some other name without adverse consequences if the name is not the same as another external name in the load module.) Programs that use CENTRY and CEXIT should also issue the CREGS macro to define symbolic registers and should copy the members CRAB and DSA to obtain mappings of these C run-time control blocks. Assembler functions that use CENTRY and CEXIT should ensure that general register 12 addresses the CRAB when entering and exiting the function (unless the CENTRY INDEP=YES parameter is used).

These macros and members are included in the assembler LCUSER MACLIB (under CMS) or SASC.MACLIBA (under OS/390).

The CENTRY macro

This is the form of a call to the CENTRY macro:

label    CENTRY DSA=dsa-size,
                  BASE=base-reg,
                  FNM=function-name,
                  STATIC=NO/YES,
                  INDEP=NO/YES,
                  LASTREG=last-reg

All the keyword parameters are optional. The label of the CENTRY macro is the name of the entry point. It is defined as an external symbol unless STATIC=YES is specified. The keyword parameters are described below:

DSA =dsa-size
specifies the size of the routine's Dynamic Save Area (DSA); if DSA is omitted, a minimum DSA (120 bytes) is allocated. In addition to providing the save area for called functions, the DSA can be used as a storage area for auto variables. Specify DSA=0 to avoid allocation of a DSA. DSA=0 can be used only for routines that

BASE=base-reg
specifies a base register for the routine. If BASE is omitted, R9 is assumed.

FNM=function-name
specifies a function name for the assembler routine. This is the name that appears in an error traceback to identify the function. If no FNM keyword appears on the macro call, the value of label is assumed.

STATIC=NO|YES
determines whether the function is to be externally defined. The default is STATIC=NO.

INDEP=NO|YES
determines whether the indep form of function linkage is required. INDEP=NO is the default. INDEP=YES is required if the assembler routine can be called from a routine that does not preserve the C execution framework pointer normally contained in register 12. The INDEP=YES linkage is less efficient than the INDEP=NO linkage and requires that L$UPREP be linked with the routine that uses the CENTRY macro. Refer to Using the indep Option for Interlanguage Communication for more information.

LASTREG=last-reg
specifies the last register to be saved for this routine. You can specify any register between R6 and R11. If no register is specified, R11 is assumed. All registers between R14 and the LASTREG value are saved when CENTRY is executed and restored when CEXIT is executed. If any unsaved registers are modified, the effects are unpredictable. If INDEP=YES is specified, the value of LASTREG is ignored, and registers R14 through R12 are always saved.

When the CENTRY macro is expanded, a USING CRAB,R12 statement should be in effect. You can use the USING positional operand of the CREGS macro to generate such a USING statement automatically.

The CEXIT macro

The CEXIT macro returns control from a routine that begins with a call to CENTRY. The form of a CEXIT call is as follows:

label     CEXIT RC=return-info/(reg),
                   DSA=YES/0,
                   INDEP=NO/YES,
                   LASTREG=last-reg

The keyword parameters are described below:

RC=return-info|(reg)
specifies an integer constant to be returned as the value of the returning function. In this case, the value is returned in R15.

You can specify any general purpose register except for register 1 (R1). R1 is used by the CEXIT macro. Specifying R1 as the value for RC will prevent the return code from being stored correctly.

Alternately, RC=(reg) specifies a register containing the return value. If RC is omitted, no value is returned unless the assembler routine is declared as returning double . In this case, do not use the RC keyword; instead load the return value into floating-point register 0 before issuing the call to CEXIT.

DSA=YES|0
must equal 0 for CEXIT if the corresponding CENTRY macro specifies DSA=0. Otherwise, DSA can be omitted.

INDEP=YES
should be specified if the corresponding CENTRY macro also specifies INDEP=YES.

INDEP=NO
should be specified (or the INDEP option omitted entirely) if the corresponding CENTRY macro does not specify INDEP=YES.

LASTREG=last-reg
specifies the last register to be restored on return from this routine. This specification should always match the LASTREG specification on the corresponding CENTRY macro.


The CREGS Macro and the CRAB and DSA DSECTs

Another group of facilities useful for the assembler programmer is the CREGS macro and the DSECTs CRAB and Dynamic Save Area (DSA), which map C run-time control blocks.

CREGS can be issued in the form CREGS USING to obtain appropriate USING statements for the CRAB and the DSA.

The CRAB DSECT should be copied because it is required for the proper expansion of CENTRY and CEXIT.

The DSA DSECT can be copied to obtain a map of the standard part of the DSA. After the standard part of the DSA, you can define additional DSA fields and then use the EQU operator to compute a total DSA size for use in CENTRY. The additional fields can be used as automatic variables. For an example of defining auto variables in an assembler function, see Defining Auto Variables in the DSA.


Defining Auto Variables in the DSA
function body COPY DSA TEMPVAR DS F auto int variable SHORTX DS H auto short variable STR1 DS CL40 auto array of char DSALEN EQU *-DSA compute total length of DSA END

If your assembler function does not define any automatic variables but does call another function, the size of the minimal DSA needed in this case is defined by the symbolic name DSAMIN.

Note that CENTRY saves a pointer to the parameter list in the DSA at label DSAPARMS (offset 80, X'50').


Chapter Contents

Previous

Next

Top of Page

Copyright © 2001 by SAS Institute Inc., Cary, NC, USA. All rights reserved.