This topic shows how to write a simple MI program that receives two packed-decimal parameters and returns the larger value through a third parameter.
This MI program demonstrates how to do the following tasks:
First the program, MI01 in this example, needs an ENTRY directive statement to designate its external entry point. The following directive declares an unnamed (the *) external (the EXT) entry point, which is called with a parameter list corresponding to PARM_LIST (defined later in the source code):
ENTRY * (PARM_LIST) EXT;
i5/OS™ programs typically pass parameters by reference as part of the high-level language (HLL) calling convention. Because i5/OS programs pass by reference (that is, address and not value), the program also needs to define three space pointers (how storage is referenced) to represent the three parameters being passed. This is accomplished by the following directives:
DCL SPCPTR ARG1@ PARM; DCL SPCPTR ARG2@ PARM; DCL SPCPTR RESULT@ PARM;
To associate these three space pointers with the parameters being passed to the program, the following operand list (OL) is declared:
DCL OL PARM_LIST /* Name of OL is PARM_LIST */ (ARG1@, /* The first parameter */ ARG2@, /* The second parameter */ RESULT@) /* The third parameter */ PARM EXT; /* External parameter list */
The names ARG1@, ARG2@, RESULT@, and PARM_LIST are chosen by you and are not mandated by the system. You can choose any valid name for any object data element. For a definition of what constitutes a valid name, see "Name" in the Program syntax topic of the Create Program (QPRCRTPG) API.
Now that the program has established addressability (the space pointers) to the three parameters, the program needs to declare how to map (or view) the storage addressed. The following declarations define the storage addressed (the BAS argument) by the three space pointer parameters as being packed-decimal (PKD) scalar data objects (DD) with 15 digits, 5 digits being to the right of the decimal point:
DCL DD ARG1 PKD(15,5) BAS(ARG1@); DCL DD ARG2 PKD(15,5) BAS(ARG2@); DCL DD RESULT PKD(15,5) BAS(RESULT@);
The names ARG1, ARG2, and RESULT are chosen arbitrarily, but, for ease of reading, are similar to the basing space pointers ARG1@, ARG2@, and RESULT@. The declarations of packed 15,5 are used for consistency with CL. The declared type and size could be of any other valid type and size. The true requirement is that the calling program and the MI program agree on the type and size.
With all the needed declarations now done, the instruction stream definition, where the program will compare the numeric values (CMPNV instruction) of parameters one and two, is started:
CMPNV(B) ARG1,ARG2 / LO(ITS2);
The program then branches (the (B) extender to CMPNV) to label ITS2 if ARG1 is less than ARG2 (the /LO branch target).
If ARG1 is not low (LO) when compared to ARG2, the next MI instruction in the source stream is run. When the next MI instruction is run, it copies the numeric value (CPYNV instruction) of ARG1 to RESULT and, following that, branches to label RETURN:
CPYNV RESULT,ARG1; B RETURN;
If ARG2 was greater than ARG1, the CPYNV instruction at label ITS2 is run, setting RESULT to the value of ARG2:
ITS2: CPYNV RESULT,ARG2;
The program has now finished processing and ends:
RETURN: RTX *; PEND;
The previous return external (RTX) instruction is not needed because it is implied by the PEND directive. The RTX instruction is included to add clarity to the program flow.
Put all together, the program looks like this:
/********************************************************************/ /********************************************************************/ /* */ /* Program Name: MI01 */ /* */ /* Programming Language: MI */ /* */ /* Description: Return the larger of two packed arguments. */ /* */ /* */ /* Header Files Included: None */ /* */ /* */ /********************************************************************/ ENTRY * (PARM_LIST) EXT; DCL SPCPTR ARG1@ PARM; DCL SPCPTR ARG2@ PARM; DCL SPCPTR RESULT@ PARM; DCL OL PARM_LIST (ARG1@, ARG2@, RESULT@) PARM EXT; DCL DD ARG1 PKD(15,5) BAS(ARG1@); DCL DD ARG2 PKD(15,5) BAS(ARG2@); DCL DD RESULT PKD(15,5) BAS(RESULT@); CMPNV(B) ARG1,ARG2 / LO(ITS2); CPYNV RESULT,ARG1; B RETURN; ITS2: CPYNV RESULT,ARG2; RETURN: RTX *; PEND;