READ THIS BEFORE CONVERTING ASSEMBLER CODE TO COBOL CODE
2
Table of Contents
1. Introduction: 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 approa approach ch which which would would be hel helpfu pfull for the same. same. The major major diffic difficult ulties ies while while conver convertin tingg 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.
•
Progr Programm amming ing in assemb assembler ler langua language ge is not as flexib flexible le or useruser-fri friend endly ly as COBOL 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
DSECT
EMPNUM
DS
F
------ > Fu Fullword
EMPNAME
DS
CL30
------ > Char Type
EMPDEPT
DS
CL10
------ > Char Type
4
EMPDESG
DS
CL3
------ > Char Type
EMPDOB
DS
XL10
------ > Hex Type
EMPDOJ
DS
XL10
------ > Hex Type
EMPSAL
DS
PL5
------ > Pa P ack 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
EMPNUM
PIC S9 (9) BINARY.
05
EMPNAME
PIC X(30).
05
EMPDEPT
PIC X(10).
05
EMPDESG
PIC X(03).
05
EMPDOB
PIC X(10).
05
EMPDOJ
PIC X(10).
05
EMPSAL
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
DS
0CL8
H1CYM
DS
0CL6
H1CYY
DS
0CL4
H1C
DS
CL2
H1YY
DS
CL2
H1MM
DS
CL2
H1DD
DS
CL2
ORG
H1C + 1
DS
CL7
H1CYMD
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 f ollowing COBOL Copy Book: 01
H1CYMD
01
filler
REDEFINES
10
H1CYM
10
filler
REDEFINES
H1CYM.
20
H1CY H1CYY Y
PIC PIC X(4) X(4)..
20
filler
REDEFINES
30
H1C
PIC X(2).
30
H1YY
PIC X(2).
20 01
PIC X(8). H1CYMD. PIC X(6).
H1MM
H1CYY.
PIC X(2).
10
H1DD
PIC X(2).
filler
REDEFINES
H1CYMD.
10
filler
PIC X(1).
10
H1CYMD
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 PACK
WorkPL rkPL8 8, Zndat ndata a
where variables are defined as WorkPL8
DS
PL8
Zndata
DS
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
PIC
S9 (15) COMP-3.
Zndata
P IC
XL3
Wrkfld
P IC
999.
MOVE Zndata
TO Wrkfld
MOVE 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
PIC
S9 (15) COMP-3.
Zndata
P IC
XL3
Wrkfld
P IC
999.
MOVE WorkPL8
TO Wrkfld
MOVE Wrkfld
TO Zndata
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
where variable is defined as SOURCE
DS
XL5 X’0200010301’
TABLE
DC
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
SOURCE
PIC X(5).
01
TABLE
PIC X(5) VALUE X’C1C2C3C4C6’.
01
WS-I
PIC 9(4) Binary.
01
WS-2Byte. 05
WS-2Byte-N
PIC 9(4) Binary VALUE 0.
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
R2,R2
TRT BUFFER(80),SCANTAB2 B BRTAB B
BRTAB(R2) NONE
B
ALPHA
B
DIGIT
In storage: BUFFER
DS
CL80
SCANTAB2
DC
256X'00'
ORG SCANTAB2+C'A'
If alphabetic, set value in
DC
register 2 to 04
9X'04'
ORG SCANTAB2+C'J' DC
9X'04'
ORG SCANTAB2+C'S' DC
8X'04'
ORG SCANTAB2+C'0'
If numeric, set value in
DC
register 2 to 08
10X'08'
ORG
Result:
9
If no alphabetic or numeric character is found, the t he 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
BUFFER
PIC X(80).
01
WS-I
PIC 9(4) Binary.
01
WS-2Byte. 05
WS-2Byte-N
PIC 9(4) Binary VALUE 0.
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 start from C1 – C9 AND BUFFER(WS-I :1) IS Less than X’CA’)
D 1 – D9
OR (BUFFER(W (BUFFER(WS-I S-I :1) IS Greater Greater than X’D0’
E2 – E9 */
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
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
PTOTAL,TOTAL
TOTAL
CONVERT TO VIEWABLE FORM
DC PL4'12347'
EDIT PATTERN
.....
- - - -> OTHER CONSTANTS
PTOTAL
DC XL9'4020202021204B2020'
EDIT PATTERN
The result would be PTOTAL ----- > XL9’404040F1F2F34BF4F7’ XL9’404040F1F2F34BF4F7’ - > ‘ 123.47’ In COBOL, we can edit data using edited picture numerical literals. So we define data 01
TOTAL
PIC S9(7) COMP-3 VALUE 12347.
01
NUM-DATA
PIC 9(7).
01
PTOTAL
PIC BZZZZZ9.99.
MOVE TOTAL
TO NUM-DATA
MOVE NUMDATA
TO PTOTAL
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
DC
PL5'1234567' => X'001234567C'
PATTERN1
DC
X'40202020202021204B2020'
LA
R1, PATTERN1+7
EDMK
PATTERN1, MONEY1
BCTR
R1, 0
POINT TO PAST SS SET BY NON-ZERO DIGIT
11
MVI * PATTERN1
0(R1),C'$' Result => ‘ $12345.67’ => X'40405BF1F2F3F4F54BF6F7' X'40405BF1F2F3F4F54BF6F7'
• Example #2: Insert $ - Significance is started by significance starter (SS) MONEY2
DC
PL5'123' => X'000000123C'
PATTERN2
DC
X'40202020202021204B2020'
LA
R1, PATTERN2+7
EDMK
PATTERN2, MONEY2
BCTR
R1, 0
POINT TO PAST SS SET BY SIGNIFICANCE STARTER
MVI 0(R1), C'$' * PATTERN2 Result => ‘
$1.23 ‘=> X'4040404040405BF14BF2F3‘ X'4040404040405BF14BF2F3‘
* If MONEY2 = PL5'23' then result is ‘
$0.23’
COBOL code for the above example: Here value of Money is 1234567 or 123 01 MONEY
PIC S9(9) COMP-3.
01 NUM-DATA
PIC 9(9).
01 PATTERN
PIC BZZZZZZ9.99.
01 WS-I
PIC 9(9) BINARY.
MOVE MONEY
TO NUM-DATA
MOVE NUM-DATA
TO PATTERN
PERFORM VARYING WS-I FROM 1 BY 1 UNTIL PATTERN (WS-I: 1) NOT EQUAL SPACE END-PERFORM SUBTRACT 1
FROM WS-I
MOVE ‘$’
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 conver convertin tingg the bit inform informati ation on in a single single byte to or from from an eight-byt eight-byte e field field of COBOL COBOL accessible zeroes and ones. Determining and changing changing the setting of a bit is possible possible using COBOL. In COBOL, we need to write a routine that provides two functions (EXPAND & COMPRESS). a) EXPA EXPAND ND - tran transl slat ate e the the bits bits of a oneone-by byte te fiel field d to byte bytess of an eigh eightt-by byte te fiel field d
For each bit that is ON (1) in the TEST-BITS field the corresponding byte in the TEST-BYTES field field is set set to a valu value e of one. For each bit that that is OFF OFF (0) (0) in the TEST TEST-B -BIT ITSS fiel field d the the corresponding byte in the TEST-BYTES field is set to a value of zero. Input
TEST-BITS, a one byte field (8-bits)
Output
TEST-BYTES, an eight byte field
Example
if TEST-BITS = x’55’ then t hen TEST-BYTES will be '01010101'
01 TEST-RECORD. 10 TEST-BITS
PIC X.
- X’55’
10 TEST-BYTES. 15 TEST-BYTE-01
PIC X.
- ‘0’
15 TEST-BYTE-02
PIC X.
- ‘1’
15 TEST-BYTE-03
PIC X.
- ‘0’
15 TEST-BYTE-04
PIC X.
- ‘1’
15 TEST-BYTE-05
PIC X.
- ‘0’
15 TEST-BYTE-06
PIC X.
- ‘1’
15 TEST-BYTE-07
PIC X.
- ‘0’
15 TEST-BYTE-08
PIC X.
- ‘1’
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
TEST-BYTES, an eight byte field
Output
TEST-BITS, a one byte field (8-bits)
13
Example
if TEST-BYTES = '01010101' '01010101' then TEST-BITS will be x’55’ 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 LABEL1
DC
XL5’D1D2D3D XL5’D1D2D3D4D5’ 4D5’
LABEL2 LABEL2
DC
X'CACBCCCDCE X'CACBCCCDCECFD6D7 CFD6D7D8D9’ D8D9’
NC
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
PIC
X(5)
VALUE XL5’D1D2D3D4D5’.
01 Label2
PIC
X(10) VALUE X'CACBCCCDCECFD6D7D8D9’.
PIC PIC
9(4) Binary.
PIC
9(4) Binary.
01 WS-2Byte. 05 ws-2B -2Byte-N e-N 01 WS-I 01 TEST-RECORD1. 10 TEST-BITS1
PIC X.
10 TEST-BYTES1. 15 TEST-BYTE1-01
PIC X.
14
15 TEST-BYTE1-02
PIC X.
15 TEST-BYTE1-03
PIC X
15 TEST-BYTE1-04
PIC X.
15 TEST-BYTE1-05
PIC X.
15 TEST-BYTE1-06
PIC X.
15 TEST-BYTE1-07
PIC X.
15 TEST-BYTE1-08
PIC X.
01 TEST-RECORD2. 10 TEST-BITS2
PIC X.
10 TEST-BYTES2. 15 TEST-BYTE2-01
PIC X.
15 TEST-BYTE2-02
PIC X.
15 TEST-BYTE2-03
PIC X.
15 TEST-BYTE2-04
PIC X.
15 TEST-BYTE2-05
PIC X.
15 TEST-BYTE2-06
PIC X.
15 TEST-BYTE2-07
PIC X.
15 TEST-BYTE2-08
PIC X.
PERFORM VARYING WS-I FROM 1 BY 1 UNTIL WS-I IS GREATER THAN 4 MOVE LABEL1(WS-I:1)
TO TEST-BITS1
MOVE LABEL2(WS-I:1)
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’
TO TEST-BYTE1-01
END-IF IF TEST-BYTE1-02 EQUAL ‘0’ OR TEST-BYTE2-02 EQUAL ‘0’ MOVE ‘0’
TO TEST-BYTE1-02
END-IF IF TEST-BYTE1-03 EQUAL ‘0’ OR TEST-BYTE2-03 EQUAL ‘0’ MOVE ‘0’
TO TEST-BYTE1-03
15
END-IF IF TEST-BYTE1-04 EQUAL ‘0’ OR TEST-BYTE2-04 EQUAL ‘0’ MOVE ‘0’
TO TEST-BYTE1-014
END-IF IF TEST-BYTE1-05 EQUAL ‘0’ OR TEST-BYTE2-05 EQUAL ‘0’ MOVE ‘0’
TO TEST-BYTE1-05
END-IF IF TEST-BYTE1-06 EQUAL ‘0’ OR TEST-BYTE2-06 EQUAL ‘0’ MOVE ‘0’
TO TEST-BYTE1-06
END-IF IF TEST-BYTE1-07 EQUAL ‘0’ OR TEST-BYTE2-07 EQUAL ‘0’ MOVE ‘0’
TO TEST-BYTE1-07
END-IF IF TEST-BYTE1-08 EQUAL ‘0’ OR TEST-BYTE2-08 EQUAL ‘0’ MOVE ‘0’
TO TEST-BYTE1-08
END-IF PERFORM COMPRESS ROUTINE TO COMPRESS TEST-BYTE1 INTO TEST-BITS1 MOVE TEST-BITS1
TO LABEL(WS-I:1)
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
HEX1+3,X'40' * TEST BIT for ON.
JO
TEST
.
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’
01 TEST-RECORD1. 10 TEST-BITS1
PIC X.
10 TEST-BYTES1. 15 TEST-BYTE1-01
PIC X.
15 TEST-BYTE1-02
PIC X.
15 TEST-BYTE1-03
PIC X
15 TEST-BYTE1-04
PIC X.
15 TEST-BYTE1-05
PIC X.
15 TEST-BYTE1-06
PIC X.
15 TEST-BYTE1-07
PIC X.
15 TEST-BYTE1-08
PIC X.
MOVE HEX1(3:1)
TO TEST-BITS1
PERFORM EXPAND ROUTINE TO EXPAND TEST-BITS1 INTO TEST-BYTE1 IF TEST-BYTE1-02 EQUAL ‘1’ GO TO TEST END-IF . . . . TEST.
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
DS
0CL4
H1C
DS
CL2
H1YY
DS
CL2
CMYY
DS
0CL6
C YY
DS
CL1
MYY
DS
CL3
DYY
DS
CL3
MVC
H1CYY, CYY
This instruction copies 4 bytes starting from CYY to H1CYY In COBOL, the above example would be written as follows: f ollows: 01
H1CYY.
18
01
05
H1C
PIC X(2).
05
H1YY
PIC X(2).
05
CY Y
PIC X(1).
05
MYY
PIC X(3).
05
DYY
PIC X(3).
CMYY.
MOVE CMYY(1:4)
TO H1CYY.
b) MVI – MOVE Immediate
This This instru instructi ction on copie copiess the second second immed immediat iate e opera operand ndss into into the storag storage e location specified by the first operands 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: f ollows: 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
H1CYY, CYY
JE
TEST
. . . TEST. This instruction compares 4 bytes starting from CYY with H1CYY
19
In COBOL, the above example would be written as follows: f ollows: IF H1CYY EQUAL 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 with the immed immediat iate e data data treati treating ng them them as charac character ter starti starting ng and sets sets the condition code. CLI
H1CYY + 3, CYY
JE
TEST
. . . TEST. This instruction compares CYY with H1CYY + 3 In COBOL, the above example would be written as follows: f ollows: IF H1CYY(3:1) EQUAL CYY GO TO TEST END-IF . . . TEST. e) MVCL – MOVE Character Long
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
R2, R4
A
DS
XL3200
B
DS
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
R2, R4
A
DS
XL3200
B
DS
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
R5, INC
BASR
R4, R5
. . . 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. i nstruction. We can use this instruction with MVC, CLC, PACK, TRT etc. Let’s take an example with MVC instruction EX
R1, MVC1 .
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). Packed). b) SUBTRACT
In COBOL, we will use SUBTRACT command corresponding to Assembler’s SR(Subtract Register), S(Subtract), SH(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 This inst instru ruct ctio ion n oper operat ates es with with regi regist ster er so in COBO COBOL L a 4 byte byte vari variab able le woul would d be used 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 This inst instru ruct ctio ion n oper operat ates es with with regi regist ster er so in COBO COBOL L a 4 byte byte vari variab able le woul would d be used 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
WORKPL8
DS
PL8
-
000000123456789C
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
WS-4Byte. 05
01
WS-4Byte-N
WORKPL8
PIC S9(9) Bi Binary. – Corresponding to register PIC S9(15) COMP-3.
MOVE WORKPL8
TO WS-4Byte-N.
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
WORKPL8
DS
PL8
Here the content of R1 is X’075BCD15’ X ’075BCD15’
25
After executing this instruction the content of WORKPL8 would be 000000123456789C 000000123456789C In COBOL, we can directly move from Binary field to Packed. So the above code in COBOL can be written as: 01
WS-4Byte. 05
01
WS-4Byte-N e-N
WORKPL8
PIC S9(9) Binary. – corresp esponding ing to regi egister PIC S9(15) COMP-3.
MOVE WS-4Byte-N
TO WORKPL8.
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
DS
XL3’123456’
FLDB
DS
XL3’777777’
After executing this instruction, the value of FLDA would be XL3’727476’. In COBOL, the above code can be written as: 01
FLDA
PIC X(3) Value X’123456’.
01
FLDB
PIC X(3) Value X’777777’.
01
WS-I
PIC 9(4) BINARY.
01
DIVIDE1. 05
QUO1-C . 10 QUO1
05
REM1-C . 10 REM1
01
PIC 9(4) BINARY. PIC 9(4) BINARY.
DIVIDE2. 05
QUO2-C . 10 QUO2
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)
TO QUO1-C(2:1)
MOVE FLDB(WS-I: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 QU QUO1-C(2: (2:1)
TO FL FLDA(WS (WS-I:1) :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
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)
TO QUO1-C(2:1)
MOVE FLDB(WS-I: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 QU QUO1-C(2: (2:1)
TO FL FLDA(WS (WS-I:1) :1)
END-PERFORM g) LPR – Load Positive Register
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 t o unsigned 4-byte variable. 01
A
PIC 9(9) Binary. – corresponding to R1
01
B
PIC S9(9) Binary. – corresponding to R2
MOVE B
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
A
PIC S9(9) Binary. – corresponding to R1
01
B
PIC S9(9) Binary. – corresponding to R2
MOVE B
TO
A
IF B IS POSITIVE P OSITIVE 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:
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
A
PIC S9(9) Binary. – corresponding to R1
01
B
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 pointer as an an elementary data item bearing the USAGE IS POINTER
clause, with no
PICTURE. E.g.: 05 WS-POINTER
USAGE IS POINTER.
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 Get the Addres Addresss of Vari Variab able le which which is pres presen entt in the Work Working ing 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
PIC X (18).
05 LAST-NAME
PIC X (26).
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.
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
usage is Pointer.
Ws-pointer-X
redefines Ws-pointer.
10 Ws-pointer-N
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 NULL,, or it will will cont contai ain n garb garbag age e poin pointi ting ng to a rand random om loca locati tion on in me memo mory ry.. 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 gone fore foreve ver. r. But But if you you stil stilll have have a poin pointer ter to it lyin lyingg arou around nd,, you you migh mightt accidentally try to access it through that pointer. The results are unpredictable but may include the following: 1. You abend. abend. The operati operating ng system system says says you don't don't own that that memory memory any any more. more. 2. Your Your program program grossly grossly misbeh misbehave avess because because that memory memory is now being being used for something else. It doesn't even look like what you think it should look like.
31
3. Your progra program m subtly misbehaves misbehaves because because that that memory memory is still still accessible, accessible, and 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
D CB
DSORG=PS, MA MACRF=GM, DD DDNAME=label, EO EODAD=BRLBL
For Output files DCB Macro would be DCBNAME
D CB
DSORG=PS, MACRF=PM, DDNAME=label, LRECL=reclen, RECFM=FB, BLKSIZE=blksize
Let’s have a look at an assembler code:
LOOP
DONE
OPEN
(INFILE,,OUTFILE,(OUTPUT))
G ET
INFILE, INREC
MVC
OUT_PART1, INREC
MVC
OUT_PART2, IN INREC + 50
P UT
OUTFILE, OU OUT_PART1
B
LOOP
CLOSE (INFILE, , OUTFILE)
32
INREC
DC
CL100
OUT_PART1
DS
CL50
DC
CL20 ‘ ‘
OUT_PART2
DS
CL50
INFILE
D CB
DSORG=PS, MACRF=GM, DDNAME=INDD, EODAD=DONE
OUTFILE
D CB
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
PIC X(100).
FD OUTFILE. 01 OUT-REC.
33
05 OUT-PART1
PIC X(50)
05 FILLER
PIC X(20) VALUE SPACES.
05 OUT-PART2
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)
TO OUT-PART1
MOVE MO VE INREC( INREC(51: 51:50 50)) TO OUT-PA OUT-PART2 RT2 WRITE OUT-REC.
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
PIC X(5).
01 B. 05 B-N
PIC 9(4) COMP-5.
01 C
PIC 9(5).
PROCEDURE DIVISION. MOVE X'B8DD' MOVE B-N MOVE C
TO B. /* X'B8DD' = 47325 */ TO C.
TO A.
DISPLAY '"' A '"'. DISPLAY '"' B '"'. DISPLAY '"' C '"'. STOP RUN. Output:
"47325" " "
/* B */
"47325"
2)
/* A */ /* C */
MOVE MOV E 9(9) 9(9) BINARY BINARY DATA DATA TO X(5) X(5) Input:
WORKING-STORAGE SECTION. 01 A
PIC X(5).
01 B. 05 B-N 01 C
PIC 9(9) COMP-5. PIC 9(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"
/* B */
" "
"47325"
3)
/* A */ /* C */
MOVE 9(9) BINARY DATA TO X(5) Input:
WORKING-STORAGE SECTION. 01 A
PIC X(5).
01 B. 05 B-N 01 C
PIC 9(9)COMP-5. PIC 9(5).
PROCEDURE DIVISION. MOVE '47325'
TO A.
MOVE A
TO C.
MOVE C
TO B-N.
DISPLAY '"' A '"'. DISPLAY '"' B-N '"'. DISPLAY '"' C '"'. STOP RUN. Output:
"47325" "0000047325" "47325"
4)
MOVE X BINARY DATA TO X(3).
36
Input:
WORKING-STORAGE SECTION. 01 A
PIC X.
01 B. 05 B-N
PIC 9(4) COMP-5.
01 C
PIC 9(5).
01 D
PIC X(3).
PROCEDURE DIVISION. MOVE X'92'
TO A.
MOVE LOW-VALUES MOVE A
TO B.
TO B(2:1).
MOVE B-N
TO C.
MOVE C(3:3)
TO D.
DISPLAY '"' A '"'. DISPLAY '"' B-N '"'. DISPLAY '"' C '"'. DISPLAY '"' D '"'. STOP RUN. Output:
"k" "00146" "00146" "146"
5) MOVE HIGH VALUE OR LOW VALUE DATA. Input:
WORKING-STORAGE SECTION. 01 A. 05 B
PIC 9(2) COMP-5.
PROCEDURE DIVISION. MOVE HIGH-VALUES
TO A.
37
DISPLAY '"' A '"'. DISPLAY '"' B '"'. MOVE LOW-VALUES
TO A.
DISPLAY '"' A '"'. DISPLAY '"' B '"'. STOP RUN. Output:
" "
/* A */
"65535 "65535"" /* B */ " "
/* A */
"00000" /* B */
6)
CONV CONVE ERT 2-DI -DIGIT GIT DISP DISPLA LAY Y HEXA HEXADE DECI CIM MAL VALU VALUE E TO ITS ITS BINA BINARY RY EQUI EQUIV VAL ALEN ENT. T. 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 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
PIC 9(4) COMP-5.
* PROCEDURE DIVISION. * * MOVE 'AB'
TO L015-DISPLAY-HEX.
MOVE ZERO TO L015-LEFT-NYBBLE-N. L015-LEFT-NYBBLE-N. MOVE ZERO TO L015-RIGHT-NYBBLE-N. L015-RIGHT-NYBBLE-N.
38
MOVE L015-DISPLAY-HEX-1 TO L015-LEFT-NYBBLE(2:1). 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
- 240) * 16
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
- 240
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 */
7)
DISP DISPLA LAY Y 1 BYTE BYTESS CHAR CHARAC ACTE TER R IN HEXA HEXADE DECI CIMA MAL L FORM FORMAT AT.. Input:
WORKING-STORAGE SECTION. 01 A. 05 B
PIC 9(4) COMP-5.
01 C. 05 D
PIC X.
39
05 E
PIC X.
01 F REDEFINES C PIC XX. 01 QUO
PIC 9(2) VALUE 0.
01 REM
PIC 9(2) VALUE 0.
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'
TO D.
IF QUO EQUAL 11 MOVE 'B'
TO D.
IF QUO EQUAL 12 MOVE 'C'
TO D.
IF QUO EQUAL 13 MOVE 'D'
TO D.
IF QUO EQUAL 14 MOVE 'E'
TO D.
IF QUO EQUAL 15 MOVE 'F'
TO D.
IF QUO LESS THAN 10 MOVE QUO(2:1) TO D. * IF REM EQUAL 10 MOVE 'A'
TO E.
IF REM EQUAL 11 MOVE 'B'
TO E.
IF REM EQUAL 12 MOVE 'C'
TO E.
IF REM EQUAL 13 MOVE 'D'
TO E.
IF REM EQUAL 14 MOVE 'E'
TO E.
IF REM EQUAL 15 MOVE 'F'
TO E.
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
Where EDPDATE is edit-pattern DEFINED for date EDPDATE DC
X'40202021612020612020'
EDTDATE is defined as CL10 format BZZZ/ZZ/ZZ. DATEVAL IS DEFINED AS PL4 */
Equivalent COBOL code: Input:
WORKING-STORAGE SECTION. 01 DAT DATEE-FM FMT T
PIC PIC ZZZ9 ZZZ9/9 /99/ 9/99 99./ ./**EDIT Pattern*/
01 DATE-FMT-VAL REDEFINES DATE-FMT PIC X(10). /* Date in packed value format */ 01 WS-D WS-DAT ATE E
PIC PIC S9(7 S9(7)) COMP COMP-3 -3 VAL VALUE UE 9912 991231 31..
01 WS-DATE-VAL
PIC 9(8).
PROCEDURE DIVISION. MOVE WS-DATE MOVE WS-DATE-VAL
TO TO
WS-DATE-VAL. WS-DATE-VAL. DATE-FMT.
DISPLAY '"' DATE-FMT-VAL '"'. STOP RUN. Output:
" 99/12/31"
9) TIME STATEMENT: Assembler code for Time: /* SRP TIMEVAL,64-1,0 MVC HATIME,EDPTIME
41
ED
HATIME,TIMEVAL+1
Where EDPTIME is the edit-pattern defined for time EDPTIME DC
X'4020217A2020'
HATIME is defined as CL6 format” HH:MM” TIMEVAL is PL4
TIMEVAL+1 Means we are leaving first byte. SRP A,64-1,0 means add add 0 to A and shift 1 digit to right*/
Equivalent COBOL code: Input:
WORKING-STORAGE SECTION. 01 TIME-FMT
PIC BZ9/99.
01 TIME-FMT-VAL REDEFINES TIME-FMT PIC X(6). 01 WS-TIME
PIC S9(7) COMP-3 VALUE 05593.
01 WS-TIME-VAL
PIC 9(7).
PROCEDURE DIVISION. MOVE WS-TIME
TO
WS-TIME-VAL. WS-TIME-VAL.
MOVE WS-TIME-VAL(3:2) WS-TIME-VAL(3:2) TO MOVE ':'
TO
TIME-FMT-VAL(2:2) TIME-FMT-VAL(2:2)
TIME-FMT-VAL(4:1) TIME-FMT-VAL(4:1)
MOVE WS-TIME-VAL(5:2) WS-TIME-VAL(5:2) TO
TIME-FMT-VAL(5:2) TIME-FMT-VAL(5:2)
DISPLAY '"' TIME-FMT-VAL '"'. STOP RUN. Output:
" 05:59"
10) EDIT PATTERN STATEMENT:
Assembler code for Edit pattern: /* L
R00, BINDATA
CVD R00, PACKDATA MVC WSDATA, EDPDATA ED
WSDATA, PACKDATA+2
Where EDPTIME is the edit-pattern EDPDATA DC
X'402020202020202020202120'
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
PIC S9(9) COMP-5 VALUE 47325. PIC S9(15) COMP-3.
01 PACK-DATA-VAL PIC 9(15). 01 WS-DATA-FMT
PIC BZ(9)99.
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’ PACKDATA+L'PACKDATA-1
UNPK UNPKDATA,PACKDATA Where PACKDATA is PL8 UNPKDATA is defined CL10.
Here UNPKDATA is 10 byte & PACKDATA is having 15
digits.
So we will move only last 10 digit in the UNPKDATA. */
43
COBOL code for unpack data Input:
WORKING-STORAGE SECTION. 01 BIN-DATA 01 PACK-DATA
PIC S9(9) COMP-5 VALUE 47325. PIC S9(15) COMP-3.
01 PACK-DATA-VAL PIC 9(15). 01 UNPK-DATA
PIC X(10).
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(6:10) TO UNPK-DATA DISPLAY '"' UNPK-DATA '"'. STOP RUN. Output:
"0000047325"
44