READ THIS BEFORE CONVERTING ASSEMBLER CODE TO COBOL CODE

2

Table of Contents

1. Introduction:
Often, you might have faced many difficulties in converting Assembler code to Cobol code. Through this document, I have tried to ease out ways of converting the code and find a simple approach which would be helpful for the same. The major difficulties while converting assembler to cobol is understanding the use of pointers in cobol. This document helps you to understand pointers as well as some assembler instructions which could be used in an easy way to convert to cobol. This document also helps you to learn the advantages of converting your low-level assembler code to the more flexible, user-friendly COBOL language. We will also understand some of the differences between the languages and some basics about converting your programs. This document introduces you to some of the intricacies of the assembler language and provides general guidance for how to convert assembler code to COBOL.Before going into the intricacies of conversion, first of all we see what is the need to convert code available in assembly language.

3

2. Need for Conversion to COBOL:
Coding in assembler language is not like coding in any other language, because assembler lacks the flexibility and user-friendliness of a high-level language. A low-level language directly addresses memory-resident areas called registers; in any high-level language, the variables handle this function. There are several reasons to convert a low-level assembler program to the higher level COBOL language. The main reasons are: • • • There might be licensing issues with assembler code, and the code might expire. Licensing is often expensive, and you risk losing rights to use the code. Assembler code can be difficult to maintain because of a shortage of experienced professionals. Programming in assembler language is not as flexible or user-friendly as COBOL language.

3. How to Convert?
Before starting with the code conversion, first of all we need to understand the conversion of Assembler data types (DSECT) to COBOL data types (Copy Book).

3.1 DSECT Vs. Copy Book
In Assembler the data types are character type (C), binary type (B, X, H, F, D), packed type (P) and address type (A). While in COBOL, the data types are character type, numeric type and alpha-numeric type. Let’s understand with the help of an example how to convert DSECT to Copy Book. Consider the following DSECT layout: EMPLOYEE EMPNUM EMPNAME EMPDEPT DSECT DS DS DS F CL30 CL10 ------ > Fullword ------ > Char Type ------ > Char Type

4

EMPDESG EMPDOB EMPDOJ EMPSAL

DS DS DS DS

CL3 XL10 XL10 PL5

------ > Char Type ------ > Hex Type ------ > Hex Type ------ > Pack Type

Above Dsect is having Binary, Char, Pack types of data. So for binary type data, like F(Fullword – 4 Byte), H(Halfword – 2 Byte), D(Doubleword – 8 Byte), we will use S9 (9) BINARY, S9 (4) BINARY and S9 (16) BINARY respectively. We can also use COMP instead of BINARY. For Char type data here we are using X(Alphanumeric type), because it can store character as well as alphanumeric types of data. For the packed type data, PL5 (Packed Type – length 5), S9 (9) COMP-3 would be used.

Hence, in Copy Book, the above code fragment would be written as below: 01 EMPLOYEE. 05 05 05 05 05 05 05 EMPNUM EMPNAME EMPDEPT EMPDESG EMPDOB EMPDOJ EMPSAL PIC S9 (9) BINARY. PIC X(30). PIC X(10). PIC X(03). PIC X(10). PIC X(10). PIC S9 (9) COMP-3.

Let us understand DSECT to Copy Book translation with another example: The following Assembler code, which defines storage to manipulate the date (century, year, month day) H1CYMD H1CYM H1CYY H1C H1YY H1MM H1DD H1CYMD DS DS DS DS DS DS DS ORG DS 0CL8 0CL6 0CL4 CL2 CL2 CL2 CL2 H1C + 1 CL7

5

In the above code, the purpose of ORG directive is to redefine a location. Hence, to convert this type of data into COBOL, we would be using REDEFINES keyword. Also, the first three fields of above Dsect would be used as group level data. The above Dsect resulted in the following COBOL Copy Book: 01 01 H1CYMD filler 10 10 REDEFINES H1CYM filler 20 20 REDEFINES H1CYY filler 30 30 20 10 01 filler 10 10 H1DD REDEFINES filler H1CYMD H1MM H1C H1YY PIC X(8). H1CYMD. PIC X(6). H1CYM. PIC X(4). REDEFINES H1CYY. PIC X(2). PIC X(2). PIC X(2). PIC X(2). H1CYMD. PIC X(1). PIC X(7).

3.2 Code Conversion
Having done with the data tpes, let’s next move on to code conversion. In code conversion, we’ll look into the following types of instructions: a) Conversion Instructions b) Logical Instructions c) Character Manipulation & Subroutine d) Arithmetic Instructions e) Some more Instructions

3.2.1 Conversion Instructions:
In this section, we will discuss how to convert the following Assembler instructions to COBOL:

6

a) Pack b) Unpack c) TR d) TRT e) ED f) EDMK

a) PACK - - - -> Convert from zoned number to pack Suppose we are having a PACK instruction as follows: PACK WorkPL8, Zndata

where variables are defined as WorkPL8 Zndata DS DS PL8 XL3

In COBOL, we can’t directly convert from character to pack, so we need to take one numeric variable. We will first convert Character type to numeric type then numeric to pack. In this example, we are taking numeric variable Wrkfld. WorkPL8 Zndata Wrkfld MOVE Zndata MOVE Wrkfld PIC PIC PIC S9 (15) COMP-3. XL3 999. TO Wrkfld TO WorkPL8

b) UNPACK - - - -> Convert from pack number to zoned number Suppose we are having an UNPACK instruction as follows: UNPACK Zndata, WorkPL8

where variables are defined as WorkPL8 DS PL8

7

Zndata

DS

XL3

In COBOL, for UNPACK instruction we will do reverse operation of PACK instruction WorkPL8 Zndata Wrkfld MOVE WorkPL8 MOVE Wrkfld c) TR ----- > Translate Replace each byte of the source field with a value determine by look table. Let’s take an example of TR instruction TR SOURCE, TABLE PIC PIC PIC S9 (15) COMP-3. XL3 999. TO Wrkfld TO Zndata

where variable is defined as SOURCE TABLE DS DC XL5 X’0200010301’ X’C1C2C3C4C6’

Suppose initial value of SOURCE is X’0200010301’ then after executing TR instruction, value of SOURCE would be X’C3C1C2C4C2’ In COBOL, we will handle this instruction as follows: 01 01 01 01 SOURCE TABLE WS-I WS-2Byte. 05 WS-2Byte-N PIC 9(4) Binary VALUE 0. PIC X(5). PIC X(5) VALUE X’C1C2C3C4C6’. PIC 9(4) Binary.

PERFORM VARYING WS-I FROM 1 BY 1 UNTIL WS-I GREATER THAN LENGTH OF SOURCE MOVE SOURCE(WS-I :1) TO WS-2Byte(2:1)

8

MOVE TABLE(WS-2BYTE-N + 1:1)TO SOURCE(WS-I:1) END-PERFORM d) TRT - Translate & Test Instruction TRT is used to scan a string of characters, searching for the occurrence of any characters which are specified in a translate table. TRT also sets the condition code to indicate the results. Let’s take an example of TRT instruction. To find the first numeric digit or alphabetic character in the field specified by BUFFER variable,

SR B BRTAB B B B In storage: BUFFER SCANTAB2

R2,R2 BRTAB(R2) NONE ALPHA DIGIT

TRT BUFFER(80),SCANTAB2

DS DC DC DC DC DC ORG

CL80 256X'00' If alphabetic, set value in register 2 to 04 9X'04' 9X'04' 8X'04' If numeric, set value in register 2 to 08 10X'08'

ORG SCANTAB2+C'A' ORG SCANTAB2+C'J' ORG SCANTAB2+C'S' ORG SCANTAB2+C'0'

Result:

9

If no alphabetic or numeric character is found, the value in register 2 remains 0 and the branch to NONE is taken. If an alphabetic character is found, the rightmost byte of register 2 is set to 04 and the branch to ALPHA is taken. If a numeric character is found, the rightmost byte of register 2 is set to 08 and the branch to DIGIT is taken. In COBOL, for the above TRT instruction, the following operation would be performed: 01 01 01 BUFFER WS-I WS-2Byte. 05 WS-2Byte-N PIC 9(4) Binary VALUE 0. PIC X(80). PIC 9(4) Binary.

PERFORM VARYING WS-I FROM 1 BY 1 UNTIL WS-I GREATER THAN LENGTH OF BUFFER IF BUFFER(WS-I :1) IS Numeric GO TO DIGIT END-IF IF (BUFFER(WS-I :1) IS Greater than X’C0’ /* Alphabet range start from C1 – C9 AND BUFFER(WS-I :1) IS Less than X’CA’) OR (BUFFER(WS-I :1) IS Greater than X’D0’ AND BUFFER(WS-I :1) IS Less than X’DA’) OR (BUFFER(WS-I :1) IS Greater than X’E1’ AND BUFFER(WS-I :1) IS Less than X’EA’) GO TO ALPHA END-IF END-PERFORM e) ED ------ > EDIT Instruction D1 – D9 E2 – E9 */

10

ED converts the packed decimal number in the second operand, to a displayable form using the hexadecimal pattern in the first operand, which also receives the result. ED TOTAL ..... PTOTAL DC XL9'4020202021204B2020' PTOTAL,TOTAL DC PL4'12347' CONVERT TO VIEWABLE FORM EDIT PATTERN - - - -> OTHER CONSTANTS EDIT PATTERN

The result would be PTOTAL ----- > XL9’404040F1F2F34BF4F7’ - > ‘ 123.47’ In COBOL, we can edit data using edited picture numerical literals. So we define data 01 01 01 TOTAL NUM-DATA PTOTAL PIC S9(7) COMP-3 VALUE 12347. PIC 9(7). PIC BZZZZZ9.99. TO NUM-DATA TO PTOTAL

MOVE TOTAL MOVE NUMDATA

f) EDMK ------ > EDIT & MARK Instruction The EDMK instruction works in exactly the same way as the Ed instruction with a bonus. If the significance detector is on, Register 1 will be loaded with the address of the significant digit. This is useful when wanting to insert a currency symbol ahead of an amount. Example: • Example #1: Insert $ - Significance is started by non-zero digit MONEY1 PATTERN1 LA EDMK BCTR DC DC PL5'1234567' => X'001234567C' X'40202020202021204B2020' POINT TO PAST SS SET BY NON-ZERO DIGIT

R1, PATTERN1+7 PATTERN1, MONEY1 R1, 0

11

MVI * PATTERN1

0(R1),C'$' Result => ‘ $12345.67’ => X'40405BF1F2F3F4F54BF6F7'

• Example #2: Insert $ - Significance is started by significance starter (SS) MONEY2 PATTERN2 LA EDMK BCTR DC DC PL5'123' => X'000000123C' X'40202020202021204B2020' POINT TO PAST SS SET BY SIGNIFICANCE STARTER $1.23 ‘=> X'4040404040405BF14BF2F3‘ $0.23’

R1, PATTERN2+7 PATTERN2, MONEY2 R1, 0

MVI 0(R1), C'$' * PATTERN2 Result => ‘ * If MONEY2 = PL5'23' then result is ‘ COBOL code for the above example: Here value of Money is 1234567 or 123 01 MONEY 01 NUM-DATA 01 PATTERN 01 WS-I MOVE MONEY MOVE NUM-DATA PIC S9(9) COMP-3. PIC 9(9). PIC BZZZZZZ9.99. PIC 9(9) BINARY. TO NUM-DATA TO PATTERN

PERFORM VARYING WS-I FROM 1 BY 1 UNTIL PATTERN (WS-I: 1) NOT EQUAL SPACE END-PERFORM SUBTRACT 1 MOVE ‘$’ FROM WS-I TO PATTERN (WS-I: 1)

3.2.2 Logical Instructions:

12

Logical instructions are not easy to handle in COBOL because these instructions work on bit, and in COBOL bit handling is not an easy task. To solve this problem, there is an approach of converting the bit information in a single byte to or from an eight-byte field of COBOL accessible zeroes and ones. Determining and changing the setting of a bit is possible using COBOL. In COBOL, we need to write a routine that provides two functions (EXPAND & COMPRESS). a) EXPAND - translate the bits of a one-byte field to bytes of an eight-byte field

For each bit that is ON (1) in the TEST-BITS field the corresponding byte in the TEST-BYTES field is set to a value of one. For each bit that is OFF (0) in the TEST-BITS field the corresponding byte in the TEST-BYTES field is set to a value of zero. Input Output Example
01 TEST-RECORD. 10 TEST-BITS 10 TEST-BYTES. 15 TEST-BYTE-01 15 TEST-BYTE-02 15 TEST-BYTE-03 15 TEST-BYTE-04 15 TEST-BYTE-05 15 TEST-BYTE-06 15 TEST-BYTE-07 15 TEST-BYTE-08 PIC X. PIC X. PIC X. PIC X. PIC X. PIC X. PIC X. PIC X. - ‘0’ - ‘1’ - ‘0’ - ‘1’ - ‘0’ - ‘1’ - ‘0’ - ‘1’ PIC X. - X’55’

TEST-BITS, a one byte field (8-bits) TEST-BYTES, an eight byte field if TEST-BITS = x’55’ then TEST-BYTES will be '01010101'

b) COMPRESS - translate the bytes of an eight-byte field into bits of a one-byte field For each byte that is a one in the TEST-BYTES field the corresponding bit in the TEST-BITS field is set to ON (1). For each byte that is zero in the TEST-BYTES field the corresponding bit in the TEST-BITS field is set to OFF (0). Input Output TEST-BYTES, an eight byte field TEST-BITS, a one byte field (8-bits)

13

Example

if TEST-BYTES = '01010101' then TEST-BITS will be x’55’

In this section, we are not discussing RR or RX Type instruction. We will discuss only following instructions: a) NC b) NI c) OC d) OI e) XC f) XI g) TM a) NC - AND Character The NC instruction Ands the character string pointed to by the first operand with the character sting pointed to by the second operand. The result is stored in the first operands. Let’s take an example of this instruction. LABEL1 LABEL2 NC DC DC XL5’D1D2D3D4D5’ X'CACBCCCDCECFD6D7D8D9’

LABEL1 (4), LABEL2

After executing this instruction the value of label1 would be XL5’C0C2C0C4D5’ In COBOL, we will perform expand & compress routine to solve bit wise problem. 01 Label1 01 Label2 01 WS-2Byte. 05 ws-2Byte-N 01 WS-I 01 TEST-RECORD1. 10 TEST-BITS1 10 TEST-BYTES1. 15 TEST-BYTE1-01 PIC X. PIC X. PIC PIC 9(4) Binary. 9(4) Binary. PIC PIC X(5) VALUE XL5’D1D2D3D4D5’.

X(10) VALUE X'CACBCCCDCECFD6D7D8D9’.

14

15 TEST-BYTE1-02 15 TEST-BYTE1-03 15 TEST-BYTE1-04 15 TEST-BYTE1-05 15 TEST-BYTE1-06 15 TEST-BYTE1-07 15 TEST-BYTE1-08 01 TEST-RECORD2. 10 TEST-BITS2 10 TEST-BYTES2. 15 TEST-BYTE2-01 15 TEST-BYTE2-02 15 TEST-BYTE2-03 15 TEST-BYTE2-04 15 TEST-BYTE2-05 15 TEST-BYTE2-06 15 TEST-BYTE2-07 15 TEST-BYTE2-08

PIC X. PIC X PIC X. PIC X. PIC X. PIC X. PIC X. PIC X. PIC X. PIC X. PIC X. PIC X. PIC X. PIC X. PIC X. PIC X.

PERFORM VARYING WS-I FROM 1 BY 1 UNTIL WS-I IS GREATER THAN 4 MOVE LABEL1(WS-I:1) MOVE LABEL2(WS-I:1) TO TEST-BITS1 TO TEST-BITS2

PERFORM EXPAND ROUTINE TO EXPAND TEST-BITS1 INTO TEST-BYTE1 PERFORM EXPAND ROUTINE TO EXPAND TEST-BITS2 INTO TEST-BYTE2 IF TEST-BYTE1-01 EQUAL ‘0’ OR TEST-BYTE2-01 EQUAL ‘0’ MOVE ‘0’ END-IF IF TEST-BYTE1-02 EQUAL ‘0’ OR TEST-BYTE2-02 EQUAL ‘0’ MOVE ‘0’ END-IF IF TEST-BYTE1-03 EQUAL ‘0’ OR TEST-BYTE2-03 EQUAL ‘0’ MOVE ‘0’ TO TEST-BYTE1-03 TO TEST-BYTE1-02 TO TEST-BYTE1-01

15

END-IF IF TEST-BYTE1-04 EQUAL ‘0’ OR TEST-BYTE2-04 EQUAL ‘0’ MOVE ‘0’ END-IF IF TEST-BYTE1-05 EQUAL ‘0’ OR TEST-BYTE2-05 EQUAL ‘0’ MOVE ‘0’ END-IF IF TEST-BYTE1-06 EQUAL ‘0’ OR TEST-BYTE2-06 EQUAL ‘0’ MOVE ‘0’ END-IF IF TEST-BYTE1-07 EQUAL ‘0’ OR TEST-BYTE2-07 EQUAL ‘0’ MOVE ‘0’ END-IF IF TEST-BYTE1-08 EQUAL ‘0’ OR TEST-BYTE2-08 EQUAL ‘0’ MOVE ‘0’ END-IF PERFORM COMPRESS ROUTINE TO COMPRESS TEST-BYTE1 INTO TEST-BITS1 MOVE TEST-BITS1 END-PERFORM The instructions OC and XC also perform like NC. Similarly, the immediate instructions like NI, OI, XI would also be performed in the similar way as discussed for NC but on a single byte. Hence, we will not cover these instructions in detail. b) TM – Test under Mask The TM Instruction tests the bits pointed to by first operands. Let’s understand this with the help of an example. TM JO . HEX1+3,X'40' * TEST BIT for ON. TEST TO LABEL(WS-I:1) TO TEST-BYTE1-08 TO TEST-BYTE1-07 TO TEST-BYTE1-06 TO TEST-BYTE1-05 TO TEST-BYTE1-014

16

. . TEST. Here, HEX1 is defined as HEX1 DS XL4

The initial value of HEX1 is XL4’C1D1C2C3’ and after executing this instruction label TEST will be executed. In COBOL, for TM instruction, we will do following operation: 01 HEX1 PIC X(4) VALUE X’C1D1C2C3’ PIC X. PIC X. PIC X. PIC X PIC X. PIC X. PIC X. PIC X. PIC X. TO TEST-BITS1

01 TEST-RECORD1. 10 TEST-BITS1 10 TEST-BYTES1. 15 TEST-BYTE1-01 15 TEST-BYTE1-02 15 TEST-BYTE1-03 15 TEST-BYTE1-04 15 TEST-BYTE1-05 15 TEST-BYTE1-06 15 TEST-BYTE1-07 15 TEST-BYTE1-08 MOVE HEX1(3:1) IF TEST-BYTE1-02 EQUAL ‘1’ GO TO TEST END-IF . . . . TEST.

PERFORM EXPAND ROUTINE TO EXPAND TEST-BITS1 INTO TEST-BYTE1

17

3.2.3 Character Manipulation and Subroutines:
In this section, the following instructions would be discussed: a) MVC b) MVI c) CLC d) CLI e) MVCL f) CLCL g) BASR h) BAS i) EX

a) MVC – MOVE Character This instruction copies the consecutive bytes starting from the address specified by the second operands into consecutive addresses specified by the first operand. The number of bytes to be copied is specified by the first operand. Example: H1CYY H1C H1YY CMYY CYY MYY DYY MVC DS DS DS DS DS DS DS H1CYY, CYY 0CL4 CL2 CL2 0CL6 CL1 CL3 CL3

This instruction copies 4 bytes starting from CYY to H1CYY In COBOL, the above example would be written as follows: 01 H1CYY.

18

05 05 01 CMYY. 05 05 05

H1C H1YY CYY MYY DYY

PIC X(2). PIC X(2). PIC X(1). PIC X(3). PIC X(3). TO H1CYY.

MOVE CMYY(1:4) b) MVI – MOVE Immediate

This instruction copies the second immediate operands into the storage location specified by the first operands
MVI H1CYY + 3, CYY

This instruction copies 1 byte starting from CYY to H1CYY + 3 location In COBOL, the above example would be written as follows: MOVE CYY TO H1CYY(4:1).

c) CLC – COMPARE Character

This instruction compares the consecutive bytes treating them as characters starting from address specified the operands and sets the condition code. The number of byte to be compared is mentioned as the length parameter.
CLC JE . . . TEST. This instruction compares 4 bytes starting from CYY with H1CYY H1CYY, CYY TEST

19

In COBOL, the above example would be written as follows: IF H1CYY EQUAL CMYY(1:4) GO TO TEST END-IF . . . TEST. d) CLI – COMPARE Immediate

This instruction compares the consecutive byte pointed by the first operand with the immediate data treating them as character starting and sets the condition code.
CLI JE . . . TEST. This instruction compares CYY with H1CYY + 3 In COBOL, the above example would be written as follows: IF H1CYY(3:1) EQUAL CYY GO TO TEST END-IF . . . TEST. e) MVCL – MOVE Character Long H1CYY + 3, CYY TEST

20

The MVCL instruction copies the bytes starting from the address specified with the second operand, into the address pointed by the first operand. Both operands are even-odd register pairs. Even register contain address and odd register contain length. MVCL A B R2, R4 DS DS XL3200 XL3200

Suppose A & B are mapped with R2 and R4 respectively and initial values of R3 and R4 are 3200. So it copies all 3200 from B to A. In COBOL, we can directly move from B to A MOVE B TO A

f) CLCL – COMPARE Character Long The CLCL instruction compares the bytes starting from the address specified with the second operand, into the address pointed by the first operand. Both operands are even-odd register pairs. Even register contain address and odd register contain length. CLCL A B DS DS R2, R4 XL3200 XL3200

Suppose A & B are mapped with R2 and R4 respectively and initial values of R3 and R4 are 3200. So it compares all 3200 of B with A. In COBOL, we can directly compare B with A IF A equal B g) BASR, BAS – Branch and Save

21

The BASR instruction places the address of the next instruction to be executed into the first operand. The control is then transferred to the location specified by the second operand. If second operand is R0, then no branch occurs. Following piece of code illustrates about the use of BASR LA BASR . . . INC EQU * . . . BR R4 In COBOL, we will use PERFORM command PERFORM INC-PARA . . . INC-PARA. h) EXECUTE (EX) The EX instruction executes a single instruction specified by the second operand. Before the target instruction is executed, the low order byte of the register indicated as the first operand is ORed with second byte of instruction. We can use this instruction with MVC, CLC, PACK, TRT etc. Let’s take an example with MVC instruction EX R1, MVC1 . R5, INC R4, R5

22

. MVC1 MVC A(0), A + 1

IF the initial value of R1 IS 1 then it will move 2 bytes from location A + 1 to A. In COBOL, we will move directly 2 bytes MOVE A(2:2) TO A(1:2)

3.2.4 Arithmetic Instructions:
There are four basic Arithmetic instructions – add, subtract, multiply and divide. a) ADD In COBOL, we will use ADD command corresponding to Assembler’s AR(Add Register), A(Add), AH(Add Halfword ) AP(Add Packed). b) SUBTRACT In COBOL, we will use SUBTRACT command corresponding to Assembler’s SR(Subtract Register), S(Subtract), SH(Subtract Halfword ) SP(Subtract Packed). c) MULTIPLY In COBOL, we will use MULTIPLY command corresponding to Assembler’s MR(Multiply Register), M(Multiply), MH(Multiply Halfword ) MP(Multiply Packed). c) DIVIDE In COBOL, we will use DIVIDE command corresponding to Assembler’s DR(Divide Register), D(Divide), DP(Divide Packed).

3.2.5 Some More Instructions:
a) SLL – Shift Left Logical

23

This instruction shifts the 32-bit first operand left, the number of bits specified by the second operand. The second operand does not specify an address. The instruction below shifts contents of R1 left by 2 bits. SLL R1, 2

If the initial value of R1 is X’FFFFFFFF’ then after executing this instruction the value of R1 would be X’FFFFFFFC’ This instruction operates with register so in COBOL a 4 byte variable would be used corresponding to that register. So the above code in COBOL can be written as: 01 WS-4Byte. 05 WS-4Byte-N PIC 9(9) Binary. – corresponding to register

Multiply 4 BY WS-4Byte-N. b) SRL – Shift Right Logical This instruction shifts the 32-bit first operand right, the number of bits specified by the second operand. The second operand does not specify an address. The instruction below shifts contents of R1 left by 2 bits. SRL R1, 2

If the initial value of R1 is X’FFFFFFFF’ then after executing this instruction the value of R1 would be X’3FFFFFFF’ This instruction operates with register so in COBOL a 4 byte variable would be used corresponding to that register. So the above code in COBOL can be written as: 01 WS-4Byte.

24

05

WS-4Byte-N

PIC 9(9) Binary. – corresponding to register

DIVIDE 4 INTO WS-4Byte-N. c) CVB – Convert to Binary The CVB instruction converts the packed-decimal number in the 8-byte field specified by the second operand, to an integer in the two’s complement binary number system operand and stores it in the first operand. The instruction below converts packed number to binary. CVB R1, WORKPL8 DS PL8 000000123456789C

WORKPL8

After executing this instruction the content of R1 would be X’075BCD15’ In COBOL, we can directly move from PACKED field to Binary So the above code in COBOL can be written as: 01 01 WS-4Byte. 05 MOVE WORKPL8 WS-4Byte-N PIC S9(9) Binary. – Corresponding to register PIC S9(15) COMP-3. TO WS-4Byte-N. WORKPL8

d)

CONVERT TO DECIMAL (CVD)

The CVD instruction converts a 32-bit signed integer specified as the first operand to an 8 byte packed-decimal number and stored it as the location specified by the second operand location. The instruction below converts binary to packed number. CVD R1, WORKPL8 DS PL8

WORKPL8

Here the content of R1 is X’075BCD15’

25

After executing this instruction the content of WORKPL8 would be 000000123456789C In COBOL, we can directly move from Binary field to Packed. So the above code in COBOL can be written as: 01 01 WS-4Byte. 05 WS-4Byte-N PIC S9(9) Binary. – corresponding to register PIC S9(15) COMP-3. TO WORKPL8. WORKPL8

MOVE WS-4Byte-N e) MVN – MOVE Numeric

This instruction is used to move only numeric part of a byte from second operand to first operand; the zoned part of the first operand would not be changed. Let’s take an example of MVN: MVN FLDA FLDB FLDA, FLDB DS DS XL3’123456’ XL3’777777’

After executing this instruction, the value of FLDA would be XL3’727476’. In COBOL, the above code can be written as: 01 01 01 01 FLDA FLDB WS-I DIVIDE1. 05 05 01 QUO1-C . 10 QUO1 REM1-C . 10 REM1 DIVIDE2. 05 QUO2-C . 10 QUO2 PIC 9(4) BINARY. PIC 9(4) BINARY. PIC 9(4) BINARY. PIC X(3) Value X’123456’. PIC X(3) Value X’777777’. PIC 9(4) BINARY.

26

05

REM2-C . 10 REM2 PIC 9(4) BINARY.

PERFORM VARYING WS-I FROM 1 BY 1 UNTIL WS-I GREATER THAN 4 MOVE FLDA(WS-I:1) MOVE FLDB(WS-I:1) TO QUO1-C(2:1) TO QUO2-C(2:1)

DIVIDE QUO1 BY 16 GIVING QUO1 REMAINDER REM1 DIVIDE QUO2 BY 16 GIVING QUO2 REMAINDER REM2 COMPUTE QUO1 = 16*QUO1 + REM2 MOVE QUO1-C(2:1) END-PERFORM f) MVZ – MOVE Zoned This instruction is used to move only zoned part of a byte from second operand to first operand; the numeric part of the first operand would not be changed. Let’s take an example of MVZ: MVZ FLDA, FLDB TO FLDA(WS-I:1)

After executing this instruction, the value of FLDA would be XL3’173757’. In COBOL, the above code can be written as: PERFORM VARYING WS-I FROM 1 BY 1 UNTIL WS-I GREATER THAN 4 MOVE FLDA(WS-I:1) MOVE FLDB(WS-I:1) TO QUO1-C(2:1) TO QUO2-C(2:1)

DIVIDE QUO1 BY 16 GIVING QUO1 REMAINDER REM1 DIVIDE QUO2 BY 16 GIVING QUO2 REMAINDER REM2 COMPUTE QUO1 = 16*QUO2 + REM1 MOVE QUO1-C(2:1) END-PERFORM g) LPR – Load Positive Register TO FLDA(WS-I:1)

27

This instruction is used to load positive value of second operand to first operand. Example: LPR R1, R2

If the value of R2 IS -6 then after executing this instruction the content of R1 will be 6. In COBOL, we will move signed 4 byte variable to unsigned 4-byte variable. 01 01 MOVE B A B PIC 9(9) Binary. – corresponding to R1 PIC S9(9) Binary. – corresponding to R2 TO A

h) LNR – Load Negative Register This instruction is used to load negative value of second operand to first operand. Example: LNR R1, R2

If the value of R2 IS -6 then after executing this instruction the content of R1 will be -6. In COBOL, the above code can be written as: 01 01 MOVE B IF B IS POSITIVE MULTIPLY -1 INTO A END-IF i) LCR – Load Complement Register This instruction is used to load complement of second operand to first operand. Example: A B PIC S9(9) Binary. – corresponding to R1 PIC S9(9) Binary. – corresponding to R2 TO A

28

LCR

R1, R2

If the value of R2 IS -6 then after executing this instruction the content of R1 will be 5. In COBOL, the above code can be written as: 01 01 A B PIC S9(9) Binary. – corresponding to R1 PIC S9(9) Binary. – corresponding to R2

COMPUTE A = B* (-1) - 1

3.3 Pointers in COBOL
In Assembler the registers as well as variables both can contain the addresses and further these addresses are manipulated .These addressing of assembler can be tackled in COBOL by using the concept of POINTERS, but the major drawback with COBOL is that COBOL is high level language and hence, does not has registers.

In Assembly language, a structure can be mapped with the addresses stored in registers and after calculation and processing those addresses are dropped from the register. By USING directive, we can map the structure and by using DROP directive, we can unmap the structure. LA R02, HDBTABLE

USING FMTTBENT, R02 DROP R02 In COBOL these are handling by using POINTERS.

3.3.1 Pointer Declarations:
Declare a pointer as an elementary data item bearing the USAGE IS POINTER PICTURE. E.g.: 05 WS-POINTER USAGE IS POINTER. clause, with no

29

WS-POINTER is a four-byte field which can store the address of any data item. The pointer is then mapped to any variable of Linkage Section. SET EXAMPLE-P TO ADDRESS OF LINKAGE-VARIABLE.

3.3.2 To Get the Address of Variable which is present in the Working Storage:
Suppose there is pointer WS-POINTER which points to some object of some know types. Set up an instance of such an object in the linkage section. Example: LINKAGE SECTION. 01 NAME-STRUCTURE. 05 FIRST-NAME 05 LAST-NAME Now use the SET verb: SET ADDRESS OF NAME-STRUCTURE TO EXAMPLE-P. The variable whose address you are setting (NAME-STRUCTURE in this case) must be a 01-level or 77-level item in the LINKAGE SECTION. PIC X (18). PIC X (26).

3.3.3 Pointer Manipulations:
Pointers can further be redefined as a group level and can be used for arithmetic calculations. For Example: 05 05 Ws-pointer Ws-pointer-X 10 Ws-pointer-N usage is Pointer. redefines Ws-pointer. 9(9) Binary.

30

So Ws-pointer-N is the binary variable which can be used as calculation. Pointers can be further used to pass or receive it as a parameter. Pointers can be assigned NULL, either with Value clause or with SET verb. Example: Set WS-pointer TO NULL Pointers can be assigned to another pointer using SET verb. SET WS-POINTER TO WS-POINTER-1.

3.3.4 Pointers Traps and Pitfalls:
• Dereferencing a NULL pointer: This blunder will cause an ABEND. Always check for NULL before dereferencing a pointer.

Failure to initialize a pointer before using it: Until you initialize it, a pointer will be NULL, or it will contain garbage pointing to a random location in memory. Dereferencing it will cause an ABEND. Whenever you declare a pointer in WORKINGSTORAGE, always initialize it to NULL with a VALUE clause. Then your code has a way to defend itself. It can detect NULL, but it cannot detect garbage. Likewise: if you dynamically allocate something which contains a pointer, set the pointer to NULL or to some other reasonable value as soon as you allocate it.

Corrupting a pointer: For example, you might MOVE SPACES to a group item which contains a pointer variable. The compiler won't protect you -- it will happily trash your pointer.

Accessing freed memory: Once you deal locate a chunk of memory, you should treat it as gone forever. But if you still have a pointer to it lying around, you might accidentally try to access it through that pointer. The results are unpredictable but may include the following: 1. You abend. The operating system says you don't own that memory any more. 2. Your program grossly misbehaves because that memory is now being used for something else. It doesn't even look like what you think it should look like.

31

3. Your program subtly misbehaves because that memory is still accessible, and it looks just the way it did when you deal located it, but it is no longer valid. You can minimize this danger if, whenever you deallocate something, you set the corresponding pointer to NULL. That way (if you follow the advice given earlier) you won't even try to dereference it. Even if you follow this policy, you are still vulnerable whenever you have multiple copies of the same pointer. You might nullify one copy but try to use the other. As a result, you should avoid keeping multiple copies of pointers. When you can't avoid it, control the extra copies carefully. Designate only one of the copies to be used for deallocation.

3.4 File Handling
An Assembler program requires DCB macros (OPEN, GET, PUT, CLOSE), for processing data from external files. For input files DCB Macro would be DCBNAME DCB DSORG=PS, MACRF=GM, DDNAME=label, EODAD=BRLBL

For Output files DCB Macro would be DCBNAME DCB DSORG=PS, MACRF=PM, DDNAME=label, LRECL=reclen, RECFM=FB, BLKSIZE=blksize Let’s have a look at an assembler code: OPEN LOOP GET MVC MVC PUT B DONE (INFILE,,OUTFILE,(OUTPUT)) INFILE, INREC OUT_PART1, INREC OUT_PART2, INREC + 50 OUTFILE, OUT_PART1 LOOP

CLOSE (INFILE, , OUTFILE)

32

INREC OUT_PART1 OUT_PART2 INFILE OUTFILE

DC DS DC DS DCB DCB

CL100 CL50 CL20 ‘ ‘ CL50 DSORG=PS, MACRF=GM, DDNAME=INDD, EODAD=DONE DSORG=PS, MACRF=PM, DDNAME=OUTDD, LRECL=120, RECFM=FB, BLKSIZE=12000

In COBOL, first we need to define file in FILE-CONTROL paragraph. We define each file in the COBOL program with an external medium, and allow specification of file organization, access mode and other information in this paragraph. Each file described in an FD or SD entry in Data Division must be described in one and only one entry in File-Control Paragraph. Each data-name must appear in a Data Division entry. The record layout for the files is defined in the FD section, which is FILE DESCRITPTION entry for the files defined in the SELECT clause. So the similar COBOL code for the given assembler code is ENVIRONMENT DIVISION. INPUT-OUTPUT SECTION. FILE-CONTROL. ASSIGN INFILE TO CUSTFILE ORGANIZATION IS SEQUENTIAL. ASSIGN OUTFILE TO CUSTOUT. : DATA DIVISION. FILE SECTION. FD INFILE. 01 IN-FILE. 03 INREC FD OUTFILE. 01 OUT-REC. PIC X(100).

33

05 OUT-PART1 05 FILLER 05 OUT-PART2

PIC X(50) PIC X(20) VALUE SPACES. PIC X(50)

WORKING-STORAGE SECTION. 01 EOF-FLAG PIC X. 88 END-OF-IN-FILE VALUE 'Y'. : PROCEDURE DIVISION. MAIN-PARAGRAPH. OPEN INPUT INFILE OPEN OUTPUT OUTFILE *Main reading loop PERFORM UNTIL END-OF-IN-FILE READ IN-FILE AT END MOVE 'Y' TO EOF-FLAG NOT AT END PERFORM PRINT-DETAILS END-READ END-PERFORM STOP RUN. PRINT-DETAILS. MOVE INREC(1:50) WRITE OUT-REC. TO OUT-PART1 MOVE INREC(51:50) TO OUT-PART2

4. Some Examples for converting Assembler statement to COBOL statement

34

1)

MOVE 9(4) BINARY DATA TO X(5) Input: WORKING-STORAGE SECTION. 01 A 01 B. 05 B-N 01 C PROCEDURE DIVISION. MOVE X'B8DD' MOVE B-N MOVE C DISPLAY '"' A '"'. DISPLAY '"' B '"'. DISPLAY '"' C '"'. STOP RUN. Output: "47325" " " "47325" /* A */ /* C */ TO B. /* X'B8DD' = 47325 */ TO C. TO A. PIC 9(4) COMP-5. PIC 9(5). PIC X(5).

/* B */

2)

MOVE 9(9) BINARY DATA TO X(5) Input: WORKING-STORAGE SECTION. 01 A 01 B. 05 B-N 01 C PIC 9(9) COMP-5. PIC 9(5). PIC X(5).

PROCEDURE DIVISION. MOVE X'00023F7D' TO B. /* X'00023F7D'=147325 */ MOVE B-N MOVE C TO C. TO A.

35

DISPLAY '"' A '"'. DISPLAY '"' B '"'. DISPLAY '"' C '"'. STOP RUN. Output: Truncation occur "47325" " " "47325" /* A */ /* C */ /* B */

3)

MOVE 9(9) BINARY DATA TO X(5) Input: WORKING-STORAGE SECTION. 01 A 01 B. 05 B-N 01 C MOVE '47325' MOVE A MOVE C DISPLAY '"' A '"'. DISPLAY '"' B-N '"'. DISPLAY '"' C '"'. STOP RUN. Output: "47325" "0000047325" "47325" PIC 9(9)COMP-5. PIC 9(5). TO A. TO C. TO B-N. PIC X(5).

PROCEDURE DIVISION.

4)

MOVE X BINARY DATA TO X(3).

36

Input: WORKING-STORAGE SECTION. 01 A 01 B. 05 B-N 01 C 01 D MOVE X'92' MOVE A MOVE B-N MOVE C(3:3) DISPLAY '"' A '"'. DISPLAY '"' B-N '"'. DISPLAY '"' C '"'. DISPLAY '"' D '"'. STOP RUN. Output: "k" "00146" "00146" "146" PIC 9(4) COMP-5. PIC 9(5). PIC X(3). TO A. TO B. TO B(2:1). TO C. TO D. PIC X.

PROCEDURE DIVISION. MOVE LOW-VALUES

5) MOVE HIGH VALUE OR LOW VALUE DATA. Input: WORKING-STORAGE SECTION. 01 A. 05 B PIC 9(2) COMP-5. MOVE HIGH-VALUES TO A. PROCEDURE DIVISION.

37

DISPLAY '"' A '"'. DISPLAY '"' B '"'. MOVE LOW-VALUES DISPLAY '"' A '"'. DISPLAY '"' B '"'. STOP RUN. Output: " " " " /* A */ /* A */ TO A.

"65535" /* B */ "00000" /* B */

6)

CONVERT 2-DIGIT DISPLAY HEXADECIMAL VALUE TO ITS BINARY EQUIVALENT. Input: WORKING-STORAGE SECTION. 01 L015-DATA. 05 L015-DISPLAY-HEX. 10 L015-DISPLAY-HEX-1 PIC X. 10 L015-DISPLAY-HEX-2 PIC X. 05 L015-LEFT-NYBBLE. 10 L015-LEFT-NYBBLE-N PIC 9(4) COMP-5. 05 L015-RIGHT-NYBBLE. 10 L015-RIGHT-NYBBLE-N PIC 9(4) COMP-5. 05 L015-BINARY-HEX. 10 L015-BINARY-HEX-N * PROCEDURE DIVISION. * * MOVE 'AB' TO L015-DISPLAY-HEX. MOVE ZERO TO L015-LEFT-NYBBLE-N. MOVE ZERO TO L015-RIGHT-NYBBLE-N. PIC 9(4) COMP-5.

38

MOVE L015-DISPLAY-HEX-1 TO L015-LEFT-NYBBLE(2:1). MOVE L015-DISPLAY-HEX-2 TO L015-RIGHT-NYBBLE(2:1). * IF L015-DISPLAY-HEX-1 LESS THAN '0' COMPUTE L015-LEFT-NYBBLE-N = ((L015-LEFT-NYBBLE-N + 57) - 240) * 16 ELSE COMPUTE L015-LEFT-NYBBLE-N = ( L015-LEFT-NYBBLE-N END-IF * IF L015-DISPLAY-HEX-2 LESS THAN '0' COMPUTE L015-RIGHT-NYBBLE-N = L015-LEFT-NYBBLE-N + (L015-RIGHT-NYBBLE-N + 57) - 240 ELSE COMPUTE L015-RIGHT-NYBBLE-N = L015-LEFT-NYBBLE-N + L015-RIGHT-NYBBLE-N END-IF * MOVE L015-RIGHT-NYBBLE(2:1) TO L015-BINARY-HEX (2:1). * DISPLAY '"' L015-BINARY-HEX '"'. DISPLAY '"' L015-BINARY-HEX-N '"'. OUTPUT: " " "00171" /* ‘Hex Value of X’AB’ = 00171 */ - 240 - 240) * 16

7)

DISPLAY 1 BYTES CHARACTER IN HEXADECIMAL FORMAT. Input: WORKING-STORAGE SECTION. 01 A. 05 B 01 C. 05 D PIC X. PIC 9(4) COMP-5.

39

05 E 01 QUO 01 REM

PIC X. PIC 9(2) VALUE 0. PIC 9(2) VALUE 0.

01 F REDEFINES C PIC XX.

PROCEDURE DIVISION. MOVE LOW-VALUES TO A. MOVE 'D' TO A(2:1). DIVIDE B BY 16 GIVING QUO REMAINDER REM. IF QUO EQUAL 10 MOVE 'A' MOVE 'B' MOVE 'C' MOVE 'D' MOVE 'E' MOVE 'F' TO D. TO D. TO D. TO D. TO D. TO D. IF QUO EQUAL 11 IF QUO EQUAL 12 IF QUO EQUAL 13 IF QUO EQUAL 14 IF QUO EQUAL 15 IF QUO LESS THAN 10 MOVE QUO(2:1) TO D. * IF REM EQUAL 10 MOVE 'A' MOVE 'B' MOVE 'C' MOVE 'D' MOVE 'E' MOVE 'F' TO E. TO E. TO E. TO E. TO E. TO E. IF REM EQUAL 11 IF REM EQUAL 12 IF REM EQUAL 13 IF REM EQUAL 14 IF REM EQUAL 15 IF REM LESS THAN 10 MOVE REM(2:1) TO E.

40

DISPLAY '"' F '"'. STOP RUN.

8) DATE STATEMENT: Assembler code for date: /* MVC EDTDATE, EDPDATE ED EDTDATE, DATEVAL X'40202021612020612020' Where EDPDATE is edit-pattern DEFINED for date EDPDATE DC EDTDATE is defined as CL10 format BZZZ/ZZ/ZZ. DATEVAL IS DEFINED AS PL4 */ Equivalent COBOL code: Input: WORKING-STORAGE SECTION. 01 DATE-FMT PIC ZZZ9/99/99./*EDIT Pattern*/ 01 DATE-FMT-VAL REDEFINES DATE-FMT PIC X(10). /* Date in packed value format */ 01 WS-DATE PIC S9(7) COMP-3 VALUE 991231. PIC 9(8). TO TO WS-DATE-VAL. DATE-FMT. 01 WS-DATE-VAL PROCEDURE DIVISION. MOVE WS-DATE MOVE WS-DATE-VAL STOP RUN. Output: " 99/12/31"

DISPLAY '"' DATE-FMT-VAL '"'.

9) TIME STATEMENT: Assembler code for Time: /* SRP TIMEVAL,64-1,0 MVC HATIME,EDPTIME

41

ED

HATIME,TIMEVAL+1 X'4020217A2020'

Where EDPTIME is the edit-pattern defined for time EDPTIME DC TIMEVAL is PL4 TIMEVAL+1 Means we are leaving first byte. SRP A,64-1,0 means add 0 to A and shift 1 digit to right*/ Equivalent COBOL code: Input: WORKING-STORAGE SECTION. 01 TIME-FMT 01 WS-TIME 01 WS-TIME-VAL MOVE WS-TIME MOVE ':' TO PIC BZ9/99. PIC S9(7) COMP-3 VALUE 05593. PIC 9(7). TO WS-TIME-VAL. TIME-FMT-VAL(2:2) TIME-FMT-VAL(5:2) 01 TIME-FMT-VAL REDEFINES TIME-FMT PIC X(6). HATIME is defined as CL6 format” HH:MM”

PROCEDURE DIVISION. MOVE WS-TIME-VAL(3:2) TO MOVE WS-TIME-VAL(5:2) TO DISPLAY '"' TIME-FMT-VAL '"'. STOP RUN. Output: " 05:59"

TIME-FMT-VAL(4:1)

10) EDIT PATTERN STATEMENT:

Assembler code for Edit pattern: /* L R00, BINDATA MVC WSDATA, EDPDATA ED WSDATA, PACKDATA+2 X'402020202020202020202120' Where EDPTIME is the edit-pattern EDPDATA DC CVD R00, PACKDATA

42

BINDATA is defined as FL4. PACKDATA is PL8 PACKDATA+2 Means we are not moving first 2 byte. */ Cobol code for the edit pattern: Input: WORKING-STORAGE SECTION. 01 BIN-DATA 01 PACK-DATA 01 WS-DATA-FMT PIC S9(9) COMP-5 VALUE 47325. PIC S9(15) COMP-3. PIC BZ(9)99.

01 PACK-DATA-VAL PIC 9(15). 01 WS-DATA REDEFINES WS-DATA-FMT PIC X(12). PROCEDURE DIVISION. MOVE BIN-DATA * * MOVE BIN-DATA MOVE PACK-DATA TO TO TO PACK-DATA-VAL. PACK-DATA. PACK-DATA-VAL

MOVE PACK-DATA-VAL(5:11) TO WS-DATA(2:11) DISPLAY '"' WS-DATA '"'. STOP RUN. Output: " 00000047325"

11) Pack to Unpack Assembler code for unpack data /* ICM R00, B’1111’, 0(R15) CVD R00, PACKDATA OI PACKDATA+L'PACKDATA-1, X’0F’ UNPK UNPKDATA,PACKDATA Where PACKDATA is PL8 UNPKDATA is defined CL10. Here UNPKDATA is 10 byte & PACKDATA is having 15 So we will move only last 10 digit in the UNPKDATA. */ digits.

43

COBOL code for unpack data Input: WORKING-STORAGE SECTION. 01 BIN-DATA 01 PACK-DATA 01 UNPK-DATA MOVE BIN-DATA * * MOVE BIN-DATA MOVE PACK-DATA PIC S9(9) COMP-5 VALUE 47325. PIC S9(15) COMP-3. PIC X(10). TO TO TO PACK-DATA-VAL. PACK-DATA. PACK-DATA-VAL

01 PACK-DATA-VAL PIC 9(15). PROCEDURE DIVISION.

MOVE PACK-DATA-VAL(6:10) TO UNPK-DATA DISPLAY '"' UNPK-DATA '"'. STOP RUN. Output: "0000047325"

44

Sign up to vote on this title
UsefulNot useful