In-Depth
Callable Service: Manipulating Binary Data at the Bit Level
In the February 2000 issue ("Codename: Callable"), I demonstrated how you can use IBM’s Language Environment Callable Services in a COBOL program to perform some tasks that are otherwise outside the scope of the language.
In this article, I would like to continue this theme by showing you how to use Callable Service to accomplish a task which is otherwise impossible in COBOL: Manipulating binary data at the bit level.
I will illustrate four bit-manipulation services:
1. Determine the setting of a bit.
2. Set a bit to 0.
3. Set a bit to 1.
4. Shift bits left or right.
You can invoke these services from a batch or CICS program compiled using the IBM COBOL for MVS & VM, or COBOL for OS/390 & VM compilers. The program must execute on a system in which the Language Environment runtime system is installed.
You can find IBM’s documentation for Language Environment in the following manuals:
SC28-1939 – Language Environment Programming Guide; and SC28-1940 – Language Environment Programming Reference.You can also view this documentation on the IBM Web site at www1.s390.ibm.com/le/.
Determine the Setting of a Bit
Call program 'CEESITST' to determine the setting of a bit. Include a binary fullword containing the number whose bit value you want to test, a fullword containing a value of 00 through 31 pointing to the bit you want to test (where 00 is the low-order, or rightmost, bit and 31 is the high-order, or leftmost, bit) and a fullword which 'CEESITST' will set to 0 or 1, reflecting the value of the bit.
The action of 'CEESITST' is similar to that of the BAL 'TM' instruction:
WORKING-STORAGE SECTION.
01 FEEDBACK-CODE.
05 FC-SEVERITY PIC S9(4) BINARY.
05 FC-MESSAGE PIC S9(4) BINARY.
05 FILLER PIC X(08).
01 WORK-FIELDS.
05 INPUT-FIELD PIC S9(9) BINARY.
05 BIT-POINTER PIC S9(9) BINARY.
05 BIT-VALUE PIC S9(9) BINARY.
PROCEDURE DIVISION.
*------------------------------------------------------------------*
AFTER CALLING 'CEESITST', 'BIT-VALUE' WILL CONTAIN '0' OR '1', REFLECTING THE VALUE OF BIT 24 FROM
‘INPUT-FIELD’. *------------------------------------------------------------------*
MOVE +24 TO BIT-POINTER.
MOVE +0 TO BIT-VALUE.
CALL 'CEESITST' USING INPUT-FIELD,
BIT-POINTER,
FEEDBACK-CODE,
BIT-VALUE.
IF FC-SEVERITY = +0 AND
FC-MESSAGE = +0
DISPLAY
‘VALUE OF BIT 24 IN INPUT-FIELD IS ‘ BIT-VALUE ELSE
PERFORM ERROR-RTN.
Set a Bit to 0
Call program 'CEESICLR' to set a bit to 0. Include a binary fullword containing the number whose bit value you want to set to 0, a fullword containing a value of 00 through 31 pointing to the bit to set to 0 (where 00 is the low-order, or rightmost, bit and 31 is the high-order, or leftmost, bit), and a fullword into which 'CEESICLR' will copy the input number with the specified bit set to 0.
The action of 'CEESICLR' is similar to that of the BAL 'NI' instruction:
WORKING-STORAGE SECTION.
01 FEEDBACK-CODE.
05 FC-SEVERITY PIC S9(4) BINARY.
05 FC-MESSAGE PIC S9(4) BINARY.
05 FILLER PIC X(08).
01 WORK-FIELDS.
05 INPUT-FIELD PIC S9(9) BINARY.
05 BIT-POINTER PIC S9(9) BINARY.
05 OUTPUT-FIELD PIC S9(9) BINARY.
PROCEDURE DIVISION.
*----------------------------------------*
AFTER CALLING 'CEESICLR',
‘OUTPUT-FIELD’ WILL BE A COPY OF ‘INPUT-FIELD’ WITH BIT 31 SET TO 0. *----------------------------------------*
MOVE +31 TO BIT-POINTER.
MOVE +0 TO OUTPUT-FIELD.
CALL 'CEESICLR' USING INPUT-FIELD,
BIT-POINTER,
FEEDBACK-CODE,
OUTPUT-FIELD.
IF FC-SEVERITY = +0 AND
FC-MESSAGE = +0
DISPLAY 'VALUE OF INPUT-FIELD WITH BIT 31 SET TO 0 IS 'OUTPUT-FIELD
ELSE
PERFORM ERROR-RTN.
Set a Bit to 1
Call program 'CEESISET' to set a bit to 1. Include a binary fullword containing the number whose bit value you want to set to 1, a fullword containing a value of 00 through 31 pointing to the bit to set to 1 (where 00 is the low-order, or rightmost, bit and 31 is the high-order, or leftmost, bit), and a fullword into which 'CEESISET' will copy the input field with the specified bit set to 1.
The action of 'CEESISET' is similar to that of the BAL 'OI' instruction:
WORKING-STORAGE SECTION.
01 FEEDBACK-CODE.
05 FC-SEVERITY
PIC S9(4) BINARY.
05 FC-MESSAGE
PIC S9(4) BINARY.
05 FILLER
PIC X(08).
01 WORK-FIELDS.
05 INPUT-FIELD
PIC S9(9) BINARY.
05 BIT-POINTER
PIC S9(9) BINARY.
05 OUTPUT-FIELD
PIC S9(9) BINARY.
PROCEDURE DIVISION.
*----------------------------------------*
AFTER CALLING 'CEEISET', 'OUTPUT-FIELD
’ WILL BE A COPY OF ‘INPUT- FIELD’ WITH BIT 31 SET TO 1.*----------------------------------------*
MOVE +31 TO BIT-POINTER.
MOVE +0 TO OUTPUT-FIELD.
CALL 'CEESISET' USING INPUT-FIELD,
BIT-POINTER,
FEEDBACK-CODE,
OUTPUT-FIELD.
IF FC-SEVERITY = +0 AND
FC-MESSAGE = +0
DISPLAY 'VALUE OF INPUT-FIELD
WITH BIT 31 SET TO 1 IS 'OUTPUT-FIELD
ELSE
PERFORM ERROR-RTN.
Shift Bits Left or Right
Call program 'CEESISHF' to shift bits left or right. Include a binary fullword containing the number whose bits you want to shift, a fullword containing a value of –32 through +32 indicating the number of bit positions to shift right or left, and a fullword into which 'CEESISHF' will copy the input field with the bits shifted the number of positions specified by the second parm. Any bit positions vacated in the shift are filled with 0.
A positive number in 'POSITIONS-TO-SHIFT' moves bits to the left and is equivalent to multiplying the number by powers of 2. For example, +1 in 'POSITIONS-TO-SHIFT' multiplies the number by 2, +2 multiplies the number by 4, etc. A shift to the left is similar to the action of the BAL 'SLA' instruction.
A negative number in 'POSITIONS-TO-SHIFT' shifts bits to the right and is equivalent to dividing the number by powers of 2. For example, -1 in 'POSITIONS-TO-SHIFT' divides the number by 2, -2 divides the number by 4, etc. A shift to the right is similar to the action of the BAL 'SRA' instruction.
WORKING-STORAGE SECTION.
01 FEEDBACK-CODE.
05 FC-SEVERITY
PIC S9(4) BINARY.
05FC-MESSAGE
PIC S9(4) BINARY.
05 FILLER
PIC X(08).
01 WORK-FIELDS.
05 INPUT-FIELD
PIC S9(9) BINARY.
05 POSITIONS-TO-SHIFT
PIC S9(9) BINARY.
05 OUTPUT-FIELD
PIC S9(9) BINARY.
PROCEDURE DIVISION.
*----------------------------------------*
AFTER CALLING 'CEESISHF',
‘OUTPUT-FIELD’ WILL BE A COPY OF ‘INPUT-FIELD’ WITH THE BITS SHIFTED 2 POSITIONS TO THE LEFT. THIS IS EQUIVALENT TO MULTIPLYING THE VALUE IN 'INPUT-FIELD' BY 4. *----------------------------------------*
MOVE +2 TO POSITIONS-TO-SHIFT.
MOVE +0 TO OUTPUT-FIELD.
CALL 'CEESISHF' USING INPUT-FIELD,
POSITIONS-TO-SHIFT,
FEEDBACK-CODE,
OUTPUT-FIELD.
IF FC-SEVERITY = +0 AND
FC-MESSAGE = +0
DISPLAY 'VALUE OF INPUT FIELD WITH BITS SHIFTED IS' OUTPUT FIELD
ELSE
PERFORM ERROR-RTN.
About the Author: Steven M. Polacek is a Senior Software Engineer at Uniprise Technologies, a United HealthGroup Company (Somerset, N.J.).