by Jeff Robinson

Prerequisites: Completion of Parts 1 & 2 in previous issues (including the exercises).

Environment: This course addresses the use of "C" in the ISO-C TPF environment.

In our last installment, we discussed how "C" defines and handles data and structures -- the basic "C" building block for data. In this issue, we'll conclude this course by taking a look at "C" control statements and functions that "C" provides which serve as equivalents to some familiar Assembler instructions.


Sometimes its convenient to change the sequential flow of instructions in a program in order to do conditional and/or repetitive tasks. In Assembler, we accomplished this by means of compare and branch statements. The following is an example of how this is done in Assembler:

                        CLI         MI0ACC,C'A'

                        BE          LABEL0001

                        MVC     EBW000,MI0ACC

                        B            LABEL0002

LABEL0001    EQU     *

Like Assembler, "C" also provides a means to compare data elements and then execute or skip certain instructions based upon the results of the comparison. This is accomplished by means of the "if" statement whose format is:

if (expression)




The square brackets in the preceding format indicates that the "else" clause is optional. The "expression" clause refers to a logical expression in "C" which evaluates to either a "1" (TRUE) or "0" (FALSE). When "expression" evaluates to "1", the statement following the "if" clause will be executed. When "expression" evaluates to "0", the statement following the "if" clause will NOT be executed; instead, the "statement" following the "else" will be executed should the "else" clause be present.

In the format above and in later ones, the "statement" clauses can represent one or more actual "C" language statements -- including another control statement. When it represents multiple statements that need to be executed, these statements must be preceded and followed by a left and right curly brace as shown:

if (expression)
} ]

Logical Operators
It's important now to take a brief detour from our look at control statements in "C" and to take a look at symbols in "C" know as logical operators. Logical operators are important because the "C" language provides them so that they can be used in expressions within control statements. A logical operator is used to do comparison between two items of data. Listed below are the logical operators supported in "C" and examples of using them in an "if" statement.

Operator Meaning Example
! Logical NOT if (!TRUE)
> Greater than if (value1 > value2)
< Less than if (value1 < value2)
== Equality test if (value1 == value2)
>= Greater than OR equal to if (value1 >= value2)
<= Less than OR equal to if (value1 <= value2)
!= Not equal to if (value1 != value2)
&& Logical AND if (value1==1) && (value2==1)
|| Logical OR if (value1==1) || (value2==1)

As can be seen in the last two examples in the preceding table, you can combine multiple tests in an expression. However, if this is done, it means that the entire expression must evaluate to a "1" before the statement(s) following the "if" clause will be executed.

Now using the information in the preceding paragraphs, we can rewrite the aforementioned Assembler code statements to look like the following "C" statements:

if (mi0acc[0] = = 'A')         /*Read: If mi0acc[0= is a character 'A', */

ebw000 = mi0acc[0];         /* Then, Save it to the ebw000 work area.*/


In Assembler, when you want to execute a series of instructions more than once, you either made use of some kind of unconditional branch instruction or a branch-and-count instruction. Here are two such examples:

Example #1

LABEL0001       EQU *

                            CLI         0(R2),C'A'

                            BE          LABEL0001

                            LA         R2,1(,R2)

                            B             LABEL0001

LABEL0002       EQU *

Example #2

                                        LABEL0001        EQU *

                                                                    AR       R2,R3

                                                                    BCT     R5, LABEL0001

                                        LABEL0002        EQU *

The preceding statements are commonly referred to as "looping" instructions. "C" offers the "while" and "do" control statements to provide the same kind of functionality seen in the first Assembler looping example. Like in Assembler, these instructions can repetitively execute a group of statements as long as the values in their control statement expressions remain true (i.e., non-zero). The format for these statements are:

while (expression)            do

statement                            statement

while (expression)

The difference between the two control statements is that "while" will only execute the first time if "expression" is true. However, the "do-while" combination always executes at least once and evaluates "expression" at the end of each execution of "statement". As with the "if" control statement format, the "statement" clauses can represent one or multiple actual "C" statements; again -- they must be enclosed between left and right curly braces if more than one statement is present.

An example of using both statement follows:

while (value1 < value2)         /*If value1 is less than value two,*/

        value1++;                          /*execute this statement. */

do                                              /*Decrement value1 at least once and */

        value1--                            /*continue to do so if its still */

while (value1 > value2);         /*greater than value2. */


The last "C" control statement we'll look at is the "for" statement. It provides functionality similar to the BCT statement loop in the preceding example #2. However, the "for" statement's counter value appears as the first statement in the sequence of instructions rather than at the end. A "for" loop has the following format:


As you can see, this statement can have up to three different expressions within its clause. The "initial-expression" clause is used to establish the beginning value that will be used to control the "for" loop. The "conditional-expression" clause is used to determine when the "for" loop should stop executing its statements and will do so if "conditional expression" evaluates to "0" (or False). The "loop-expression" is where the counter value is modified so that "conditional-expression" eventually evaluates to "0" (or False).

Like BCT or BCTR, the "for" statement is used to execute the statement(s) in its body a specific number of times. The following is an example of a "for" statement. It accumulates "value1" into "result" until "value1" is no longer less than "value2".

for (value1=1;value1 < value2; value1++)
result=result + value1;


As may you realize by now, most of the instructions and macros you used in Assembler are not needed in "C". However, there are a few functions in "C" that work similar to instructions in Assembler which would be a good idea to learn about. Below, I've listed a table of functions in "C" (with their Assembler equivalents) which you might find useful and familiar later.

"C" Function Assembler Equivalent(s) Meaning
Sizeof L'(Some Fieldname) Returns the number bytes used by a field
Memcpy MVC; MVCL; MVI Copy data from one location to another
Memcmp CLC; CLCL; CLI Compares data at two locations; returns 0 or 1
Sprintf PACK; UNPK; ED Formats data into displayable form
Sscanf CVB; CVD; etc. Converts data from one form to another
Memset ZAP; XC; X; XI Sets a data area to all zeroes
Getcc GETCC Allocation of core blocks
Crusa CRUSA Releasing core blocks
Levtest LEVTA Testing levels for core blocks

The following examples show the use of three of these functions. For each

example assume the following declaration has been made:

char string1[10],string2[10];
short len=10;

Example 1: Demonstrates usage of the memcpy function.

        memcpy(string1,string2,len) /*Copy string2 to string1 for number of bytes specified in len */

Example 2: Demonstrates usage of "memcmp" function. This function compares two variables for the length defined in the third parameter. The "memcmp" returns 0 if the two variables are equal.

if (memcmp(string1,string2,len) == 0)
value1 = value2;
value2 = value1;

Example 3: Demonstrates the usage of "memset" function. This function is used to initialize a variable to the character in the second parameter for number of bytes specified in the third parameter(len).

memset(string1,'\0',len);     /*set string1 to binary zeroes*/
memset(string2,'A',len);     /*set string2 to character A's*/


For details on using these "C" functions, refer to your IBM C Programmers Guide manual (or another "C" instruction manual). Also, don't forget that a lot of the TPF macros have "C" equivalents described in the IBM TPF C/C++ Language Support manual. Please refer to those manuals or other similar documentation for details on using the above macros and others.

This concludes our "fast-track" exposure course for moving from TPF Assembler to ISO-C. For more information on learning ISO-C in the TPF environment, contact your local IBM sales representative or surf the web at

QUIZ - Part 3

  1. The controlling clause in an "if" control statement is called a logical expression. True or False?
  2. Expressions must ultimately evaluate to a True or False condition. True or False?
  3. The "while" control statement will only execute if its expression initially evaluates to "1" or True condition. True or False.
  4. The _________ loop always executes at least once. Fill in the blank.
  5. Expressions use _______ operators in order to determine their results. Fill in the blank.
  6. The left and right _______ _______ must be used to group multiple statements used in the body of an "if" clause.
  7. Use _________to compare data which resides in two different locations.
  8. The loop-expression in a "for" loop determines if the "for" loop should stop executing. True or False.
  9. Which operator is used as an equality test in logical expressions?
  10. Control statements cannot have other control statements within their body.  True or False?


1. Convert the following Assembler programs to "C" functions.

Note 1: You'll have to research the format of the equivalent "C" crusa function on your own.

Note 2: When using ECB-related fields in "C", precede all variable names with "ecbptr()->"  (i.e.,  ecbptr()->ebw000).      

Note 3: Use the sizeof() function to determine the size of a field name for memcpy. (i.e., memcpy(fieldname1,fieldname2,sizeof(fieldname1));)

                                        BEGIN NAME=XYZ1,VERSION=A0
*JUST EXIT AND RETURN.                                                                                                               *

                                        MI0MI REG=R1
                                        PN0NR REG=R3
                                        CRUSA         S0=4                 RELEASE LEVEL 4 BLOCK IF ANY

                                        L                     R1,CE1CR0     BASE THE INPUT BLOCK
                                        L                     R3,CE1CR2     BASE THE PASSENGER NAME BLOCK
                                        XR                  R4,R4               ZERO OUT THIS REGISTER
                                        AH                 R4,MI0CCT    GET THE NUMBER OF BYTES PASSED
                                        LTR                R4,R4               IS R4 ZERO?
                                        BE                  SETERROR     YES, THEN GO EXIT
                                        CLI                 MI0ACC,C'Y'   ZERO OUT THE CURRENT PASSENGER NAME ?
                                        BE                  ZAPNAME      IF 'Y', THEN GO TO ZAP NAME
                                        ENTRC          ABCD              INVOKE ABCD TO DO THE COPY
                                        B                     EXITHERE      GO TO EXIT
        ZAPNAME            DS                  0H
                                        XC                 PN0NM(L'256),PN0NM    ZERO OUT THE CURRENT NAME RECORD
                                        B                    EXITHERE
        SETERROR             DS                 0H
                                        MVI              EBSW01,C'E'           INDICATE AN ERROR OCCURRED
        EXITHERE             DS                 0H
                                        BACKC ,
                                        LTORG ,
                                        FINIS XYZ1
                                        END ,

                                        BEGIN NAME=ABCD,VERSION=A0
                                        MI0MI REG=R1
                                        PN0NR REG=R3
                                        MVC             PN0LST,EBW000             COPY IN LAST NAME (20 Bytes)
                                        MVC             PN0FST,EBW020             COPY FIRST NAME (15 Bytes)
                                        MVC             PN0PHN,EBW035            COPY PHONE NUMBER (12 Bytes)
                                        MVC             PN0FLT,EBW047             COPY FLIGHT NUMBER (4 Bytes)
*           Now, clear out the EBW work area.                   *
                                        XC                 EBW000(L'PN0LST),EBW000
                                        XC                 EBW020(L'PN0FST),EBW020
                                        XC                 EBW035(L'PN0PHN),EBW035
                                        XC                 EBW047(L'PN0FLT),EBW047
                                        BACKC ,
                                        FINIS ABCD