Using inline assembly for z/OS XL C/C++ compiler Two ways to use high-level languages in low-level programming Ivy Lam ([email protected]) Software Developer IBM 16 October 2015 There are two ways to build a zOS® XLC/C++ application that contains embedded assembly instructions. Explore the major differences and the operations that can be performed using these two methods. See samples of compiling, linking, and running a program including inline assembly with these two methods. Also included are examples of how to search for user defined and system macros using the ASMLIB compiler option. This article is written for software developers who have a basic understanding of zOS and assembler instructions. Since z/OS V1R9 XL C, METAL C provided C language extensions to allow embedding HighLevel Assembler (HLASM) instructions directly into the C programs. Starting with z/OS XL C/ C++ V2.1.1, you can embed HLASM instructions in C/C++ programs. METAL C (referred to as METAL in this article) allows users to exploit MVS™ system services directly through system provided assembly macros. The latest inline assembly support (referred to as ASM in this article) allows embedding hardware instructions directly within the standard C and C++ programs with full language environment and run time library support. This article highlights the characteristics and the differences between ASM and METAL. It also shows how to use the ASMLIB option and data definition name (DDname) in conjunction with ASM to search for the assembler macros included in the source code. ASM characteristics • • • • • • • ASM is supported for both C and C++ compilers. ASM is easier for a user to generate the object code. ASM supports all compiler supported linkages including XPLINK and NOXPLINK. ASM supports all optimization levels including OPT(2), OPT(3), IPA, and HOT. ASM supports all addressing modes including ILP32 and LP64. The debug side file can be generated by the compiler if requested by the user. Full language environment runtime is available in ASM. © Copyright IBM Corporation 2015 Using inline assembly for z/OS XL C/C++ compiler Trademarks Page 1 of 11 developerWorks® ibm.com/developerWorks/ METAL characteristics • • • • • • • METAL is supported for C only. METAL is used for system programming development. METAL uses MVS linkage convention. METAL supports all optimization levels including OPT(2), OPT(3), IPA, and HOT. METAL supports all addressing modes including ILP32 and LP64. There is no dependency on Language Environment (LE). METAL supports user specified function prolog and epilog. ASM and METAL comparison The major differences between ASM and METAL support are shown below: Table 1. ASM and METAL comparison Characteristics ASM METAL Supporting compiler C and C++ C Controlling compiler options MVS: ASM USS: -qasm MVS: METAL USS: -qmetal -S Available release z/OS V2R1M1 z/OS V1R9 Hardware architecture All architecture levels ARCH(5) minimum HLASM compiler requirement V2R1 HLASM plus APAR P121235 or V2R2 HLASM V1R9 HLASM Output from the C/C++ compiler object file HLASM source code User requires invoking HLASM to compile the source code No Yes Linkage support All supported linkages by C and C++ MVS OS linkage only Runtime library support z/OS C/C++ runtime library z/OS METAL C runtime library Language environment support Yes No METAL C generates code that is independent of LE User customized prolog/epilog support No Yes Modifiable assembly code generated by the compiler No Yes AR-mode support No Yes AMODE switching support No Yes Processing differences The following examples use a simple program (example.c) to demonstrate how to use the ASM and alternatively, the METAL option to create the application. The return code from the execution of the application is 55. Using inline assembly for z/OS XL C/C++ compiler Page 2 of 11 ibm.com/developerWorks/ developerWorks® example.c int main (void) { int a=10, b=45 ; __asm (" AR %0,%1 " :"+r"(a) :"r"(b)); return a; } Example 1. Building an application with ASM under z/OS UNIX System Services 1. Compile: xlc –c –qasm example.c 2. Link: xlc example.o 3. Run: a.out Note: You can combine steps 1 and 2 into one step: 1. Compile and link: xlc –qasm example.c 2. Run: a.out Example 2. Building an application with METAL under z/OS UNIX System Services 1. Compile: xlc -qmetal -S example.c 2. Assemble: as example.s 3. Link: ld –e main example.o 4. Run: a.out Example 3. Building an application with ASM under z/OS batch When the application is compiled with the ASM option, you can use the standard cataloged procedures for each step, or the combined cataloged procedures to build the application. • Use EDCC to compile and CEEWL to link the program (see Listing 1). • Use EDCCB to compile and link the program (see Listing 2). • Use EDCCBG to compile, bind, and run the program (see Listing 3). Listing 1. JCL that uses cataloged procedures EDCC and CEEWL to build the ASM application //jobcard information… //PROC JCLLIB ORDER=(CBC.SCCNPRC, CEE.SCEEPROC) //*------------------------------------------------------------------//* Compile step //*------------------------------------------------------------------//COMP EXEC EDCC, // OUTFILE='HLQ.OBJECT(EXAMPLE),DISP=SHR', // CPARM='ASM' //STEPLIB DD DSN=CBC.SCCNCMP,DISP=SHR // DD DSN=CEE.SCEERUN,DISP=SHR // DD DSN=CEE.SCEERUN2,DISP=SHR // DD DSN=ASM.SASMMOD1,DISP=SHR //COMPILE.SYSIN DD DATA,DLM='/>' int main(void) { int a=10, b=45 ; __asm(" AR %0,%1 " :"+r"(a) :"r"(b)); return a; Using inline assembly for z/OS XL C/C++ compiler Page 3 of 11 developerWorks® ibm.com/developerWorks/ } /> //*------------------------------------------------------------------//* Link step //*------------------------------------------------------------------//LINK EXEC CEEWL, // PARM= AMODE=31,CASE=MIXED //SYSLMOD DD DSN=HLQ.LOAD(EXAMPLE),DISP=SHR //OBJECT DD DSN=HLQ.OBJECT,DISP=SHR //SYSLIN DD * INCLUDE OBJECT(EXAMPLE) /* //SYSPRINT DD SYSOUT=* //*------------------------------------------------------------------//* Run step //*------------------------------------------------------------------//GO EXEC PGM=EXAMPLE //STEPLIB DD DSN=HLQ.LOAD,DISP=SHR Listing 2. JCL that uses cataloged procedure EDCCB to build the ASM application //jobcard information… //PROC JCLLIB ORDER=(CBC.SCCNPRC) //*------------------------------------------------------------------//* Compile and bind step //*------------------------------------------------------------------//COMP EXEC EDCCB, // OUTFILE='HLQ.LOAD(EXAMPLE),DISP=SHR', // CPARM='ASM' //STEPLIB DD DSN=CBC.SCCNCMP,DISP=SHR // DD DSN=CEE.SCEERUN,DISP=SHR // DD DSN=CEE.SCEERUN2,DISP=SHR // DD DSN=ASM.SASMMOD1,DISP=SHR //COMPILE.SYSIN DD DATA,DLM='/>' int main(void) { int a=10, b=45 ; __asm(" AR %0,%1 " :"+r"(a) :"r"(b)); return a; } /> //*------------------------------------------------------------------//* Run step //*------------------------------------------------------------------//GO EXEC PGM=EXAMPLE //STEPLIB DD DSN=HLQ.LOAD,DISP=SHR Using inline assembly for z/OS XL C/C++ compiler Page 4 of 11 ibm.com/developerWorks/ developerWorks® Listing 3. JCL that uses cataloged procedure EDCCBG to build and run the ASM application //jobcard information… //PROC JCLLIB ORDER=(CBC.SCCNPRC) //*------------------------------------------------------------------//* Compile, bind and run //*------------------------------------------------------------------//CBG EXEC EDCCBG, // CPARM='ASM' //STEPLIB DD DSN=CBC.SCCNCMP,DISP=SHR // DD DSN=CEE.SCEERUN,DISP=SHR // DD DSN=CEE.SCEERUN2,DISP=SHR // DD DSN=ASM.SASMMOD1,DISP=SHR //COMPILE.SYSIN DD DATA,DLM='/>' int main(void) { int a=10, b=45 ; __asm(" AR %0,%1 " :"+r"(a) :"r"(b)); return a; } /> Example 4. Building an application with METAL under z/OS batch When the application is complied with the METAL option, you cannot use the combined standard cataloged procedures to compile and bind the program. That is because the output from the compiler is HLASM source code that needs to be assembled by HLASM before the link step. Listing 4. JCL that uses cataloged procedure EDCC and ASMAC to compile and assemble the METAL application //jobcard information... //PROC JCLLIB ORDER=(CBC.SCCNPRC) //*------------------------------------------------------//* Compile step //*------------------------------------------------------//COMP EXEC EDCC, // OUTFILE='HLQ.ASMSRC(EXAMPLE),DISP=SHR', // CPARM='METAL' //COMPILE.SYSIN DD DATA,DLM='/>' int main(void) { int a=10, b=45 ; __asm (" AR %0,%1 " :"+r"(a) :"r"(b)); return a; } /> //*------------------------------------------------------//* Assembly step //*------------------------------------------------------//ASMC EXEC ASMAC //SYSIN DD DSN=HLQ.ASMSRC(EXAMPLE),DISP=SHR //SYSLIN DD DSN=HLQ.OBJECT(EXAMPLE),DISP=SHR //*------------------------------------------------------//* Link step //*------------------------------------------------------//LINK EXEC PGM=IEWL, // PARM= AMODE=31,CASE=MIXED //SYSLMOD DD DSN=HLQ.LOAD(EXAMPLE),DISP=SHR //OBJECT DD DSN=HLQ.OBJECT,DISP=SHR //SYSLIN DD DATA,DLM='/>' INCLUDE OBJECT(EXAMPLE) ENTRY main Using inline assembly for z/OS XL C/C++ compiler Page 5 of 11 developerWorks® ibm.com/developerWorks/ /> //SYSPRINT DD SYSOUT=* //*------------------------------------------------------//* Run step //*------------------------------------------------------//GO EXEC PGM=EXAMPLE //STEPLIB DD DSN=HLQ.LOAD,DISP=SHR Other differences There are some compiler options that can be used together with ASM or METAL during the compilation to enhance the inline assembly support. Table 2 shows which option can be used in conjunction with ASM or METAL Table 2. Compatible compiler option Compiler option ASM METAL ARMODE No Yes ASMDATASIZE No Yes ASMLIB Yes No DSAUSER No Yes EPILOG No Yes GENASM No Yes KEYWORD(asm) Yes No – before V2R1M1 Yes – V2R1M1 and later PROLOG No Yes RESERVED_REG No Yes SYSSTATE No Yes There are other differences in terms of keyword, predefined macros, and pragma support between ASM and METAL. Table 3 highlights the differences. Table 3. Other technical differences ASM METAL 1 keywords asm, __asm, __asm__ __asm, __asm__ compiler predefined macros __IBM_ASM_SUPPORT = 1 __IBM_METAL__ = 1 __IBM_FAR_IS SUPPORTED__ = 1 #pragma insert_asm Not supported Supported _Pragma("insert_asm") Not supported Supported 1 If you want to use the keyword or token ASM in the embedded assembly statements, the token ASM can be accepted by doing one of the following: • In the source code, add one of the following statements: • #define asm __asm • #define asm __asm__ Using inline assembly for z/OS XL C/C++ compiler Page 6 of 11 ibm.com/developerWorks/ developerWorks® • Specify compiler option KEYWORD(asm) ASMLIB There are three ways to instruct the compiler where to locate the macros that are included in the ASM statements: 1. ASMLIB compiler option 2. ASMLIB DDname statement 3. Both of the above, where compiler option takes precedence Compiler option This option gives the compiler the search paths for macro libraries. The specified macro library can be a Partitioned Data Set (PDS), a Partitioned Data Set Extended (PDSE), or a UNIX System Service (USS) directory, or a combination of all 3. • NOASMLIB • NOASMLIB is the default option; it means no allocation for the ASMLIB DD • Does not accept suboptions • Clears all macro libraries specified in any previous ASMLIB options • Does not deallocate ASMLIB DDname if it is allocated • ASMLIB(lib1,lib2,..) • Suboptions only accept fully qualified PDS names, PDSE names, and USS directories. • All data set names must start with //. For example, ASMLIB( //'SYS1.MACLIB'). • Multiple ASMLIB specifications result in the concatenation of the libraries in the order they are specified. Examples Table 4 shows how to search user defined and system macros through the ASMLIB compiler option. Table 4. ASMLIB option usage examples Variations Option specification PDS/PDSE MVS: CPARM=' ASMLIB(//'SYS1.MACLIB')' USS: -qasmlib="//'SYS1.MACLIB'" Results: data set 'SYS1.MACLIB' is searched USS directory MVS: CPARM='ASMLIB(/hlq/mymacrolib)' USS: -qasmlib=/hlq/mymacrolib Results: directory /hlq/mymacrolib is searched Multiple options and mixed types MVS: CPARM='ASMLIB(/hlq/mymacrolib) , ASMLIB(//'HLQ.MYMACLIB')' USS: -qasmlib=/hlq/mymacrolib –qasmlib= "//'HLQ.MYMACLIB'" Results: /hlq/mymacrolib and 'HLQ.MYMACLIB' are searched Multiple suboptions and mixed types MVS: CPARM='ASMLIB(//'HLQ.MYMACLIB', /hlq/ mymacrolib, //'SYS1.MACLIB')' Using inline assembly for z/OS XL C/C++ compiler Page 7 of 11 developerWorks® ibm.com/developerWorks/ USS: -qasmlib=“//’HLQ.MYMACLIB’”: /hlq/ mymacrolib:’’//’SYS1.MACLIB’” Results: 'HLQ.MYMACLIB', /hlq/mymacrolib , and 'SYS1.MACLIB' are searched NOASMLIB MVS: CPARM='ASMLIB(/hlq/mymacrolib), NOASMLIB, ASMLIB(//'HLQ.MYMACLIB')' USS: -qasmlib=/hlq/mymacrolib -qnoasmlib qasmlib=“//’HLQ.MYMACLIB’” Results: only 'HLQ.MYMACLIB' is searched DDname • Multiple DD statements that contain data sets and USS directories are allowed (see Listing 5). • When the ASMLIB compiler option and ASMLIB DD statement are specified in the JCL at the same time, the libraries are concatenated as a search list. The compiler option takes precedence over the DDname (see Listing 6). Listing 5. ASMLIB DDname examples //ASMLIB // // // // // DD DSN=SYS1.MACLIB,DISP=SHR DD DSN=HLQ.MYMACLIB,DISP=SHR DD PATH='/hlq/mymacrolib', PATHOPTS=(ORDONLY,ONONBLOCK), PATHMODE=(SIRUSR,SIXUSR), FILEDATA=TEXT Result: the compiler uses the following search sequence: 1. Data set SYS1.MACLIB 2. Data set HLQ.MYMACLIB 3. Directory /hlq/mymacrolib Listing 6. Example of ASMLIB compiler options and DDname //COMP EXEC EDCC, // CPARM='ASM OPTFILE(DD:XOPTS)' //XOPTS DD DATA,DLM='/>' ASMLIB(//'HLQ.MYMLIB1',/hlq/mymacrolib1) NOASMLIB ASMLIB(//'HLQ.MYMLIB2',/hlq/mymacrolib2) /> //ASMLIB DD DSN=SYS1.MACLIB,DISP=SHR // DD DSN=HLQ.MYMACLIB,DISP=SHR // DD PATH='/hlq/mymacrolib', // PATHOPTS=(ORDONLY,ONONBLOCK), // PATHMODE=(SIRUSR,SIXUSR), // FILEDATA=TEXT Result: the compiler uses the following search sequence: 1. Data set HLQ.MYMLIB2 2. Directory /hlq/mymacrolib2 3. Data set SYS1.MACLIB 4. Data set HLQ.MYMACLIB Using inline assembly for z/OS XL C/C++ compiler Page 8 of 11 ibm.com/developerWorks/ developerWorks® 5. Directory /hlq/mymacrolib Note: HLQ.MYMLIB1 and /hlq/mymacrolib1 were cleared out by NOASMLIB. Conclusion The different inline assembly supports provided by the zOS XLC/C++ compiler are designed for different purposes. METAL C is meant for system programming development. ASM allows users to exploit the assembler macro libraries and hardware instructions in the standard Language Environment. Acknowledgements I would like to thank Rajan Bhakta, Visda Vokhshoori and Milos Lalovic for their help and advice with this article. Using inline assembly for z/OS XL C/C++ compiler Page 9 of 11 developerWorks® ibm.com/developerWorks/ Resources • z/OS XL C/C++ V2R1 User's guide (SC14-7307-01) • z/OS V2R1 Metal C Programming Guide and Reference (SC14-7313-01) Using inline assembly for z/OS XL C/C++ compiler Page 10 of 11 ibm.com/developerWorks/ developerWorks® About the author Ivy Lam Ivy Lam is a software developer. She has worked for IBM in the IBM Canada Laboratory for more than 30 years. Her experience includes application development in IBM midrange computer systems, compiler development in OS/2 and IBM mainframe systems, and system verification for VisualAge C++ and zOS C/C++ compiler. © Copyright IBM Corporation 2015 (www.ibm.com/legal/copytrade.shtml) Trademarks (www.ibm.com/developerworks/ibm/trademarks/) Using inline assembly for z/OS XL C/C++ compiler Page 11 of 11