Calling C code from Assembler — C example

This section shows samples of how to C code from assembler. There are three parts to this example.

The first code example (CCNGCA4) shown in Figure 1 is a trivial C routine that establishes the C runtime environment.

Figure 1. Establishing the C runtime environment
/* this example demonstrates C/Assembler ILC */
/* part 1 of 3 (other files are CCNGCA2, CCNGCA5) */
/* in this example, the code in CCNGCA4 invokes CCNGCA2, */
/* which in turn invokes CCNGCA5 */
/* you can use EDCCBG to do the compile and bind, but */
/* you must include the objects from CCNGCA2 and CCNGCA5 */

#pragma linkage(CALLPRTF, OS)

int main(void) {
   CALLPRTF();

   return(0);
}

The second part, shown in Figure 2, is the assembler routine (CNGCA2). It calls an intermediate C function that invokes a runtime library function.

Figure 2. Calling an intermediate C function from Assembler OS linkage
* this example demonstrates ILC with Assembler-part 2 of 3
CALLPRTF CSECT
         EDCPRLG
         LA    1,ADDR_BLK              parameter address block in r1
         L     15,=V(@PRINTF4)         address of routine
         BALR  14,15                   call @PRINTF4
         EDCEPIL
ADDR_BLK DC   A(FMTSTR)                parameter address block with..
         DC   A(X'80000000'+INTVAL)    ..high bit on the last address
FMTSTR   DC   C'Sample formatting string'
         DC   C' which includes an int -- %d --'
         DC   AL1(NEWLINE,NEWLINE)
         DC   C'and two newline characters'
         DC   AL1(NULL)
*
INTVAL   DC   F'222'            The integer value displayed
*
NULL     EQU  X'00'             C NULL character
NEWLINE  EQU  X'15'             C \n character
         END

Finally in this example (CCNGCA5), the intermediate C routine calls a runtime library function, as shown in Figure 3.

Figure 3. Intermediate C routine calling a runtime library function
/* this example demonstrates C/Assembler ILC */
/* part 3 of 3 (other files are CCNGCA2, CCNGCA4) */
/*******************************************************\
 * This routine is an interface between assembler code  *
 * and the C/C++ library function printf().             *
 * OS linkage will not tolerate C-style variable length *
 * parameter lists, so this routine is specific to a    *
 * formatting string and a single 4-byte substitution   *
 * parameter.  It's specified as an int here.           *
 * This object wil be named @PRINTF4.                   *
/*******************************************************/

#pragma linkage(_printf4,OS) /*function will be called from assembler*/

#include <stdio.h>

#pragma map(_printf4,“@PRINTF4”)

int _printf4(char *str,int i) {

   return printf(str,i);       /* call runtime library function */

}