Communication with Assembler Programs |
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 (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.
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]](../common/images/cautend.gif)
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.
Keep in mind the following concerning the CRAB:
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).
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 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.
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').
Copyright © 2001
by SAS Institute Inc., Cary, NC, USA. All rights reserved.