In my previous mainframe COBOL programming days, there were occasions when a question arose about the behavior of the COBOL compiler. Inevitably, I would resort to compiling my COBOL program with the appropriate compile directive to include the actual assembler language output. I suppose you can call me a " curious geek" ”the shoe certainly does fit.
.NET offers a similar opportunity to view MSIL with a handy utility called ILDASM. You execute this utility using the VS .NET command prompt (Chapter 2 covers this command prompt feature). With the ILDASM utility, you have the option of displaying your program's MSIL in the ILDASM GUI, or you can send the output to a text file.
For this discussion, refer back to the sample code project you created earlier in this chapter (DefineDataTypesSampleCobol) . Recall there were a couple of things that I wanted to show you. For example:
How do you know that the COBOL .NET data type 9(4) COMP-5 does in fact map to the .NET data type Sysetm.Int16?
How do you know that the changed COBOL .NET PICTURE description 9(5) COMP-5 will cause a mapping to the .NET data type System.Int8 as a one- dimensional array?
Let's execute the ILDASM utility. As you can see in Figure 6-6, you execute the ILDASM utility from the Visual Studio .NET Command Prompt window. The path information used for your executable file (and output file, if you so choose) will differ .
Note | Figure 6-6 shows the executable file named DefineDataTypesSampleCOBOL.exe. |
I have included a snippet of the COBOL sample program code in Listing 6-7 to assist in this ILDASM discussion.
. . . 000050 REPOSITORY. 000060* .NET Framework Classes 000070 CLASS SYS-INT16 AS "System.Int16" 000080 CLASS SYS-INT32 AS "System.Int32" 000090 CLASS SYS-DOUBLE AS "System.Double". 000100* 000110 DATA DIVISION. 000120 WORKING-STORAGE SECTION. 000130* Declare Data Items with COBOL.NET Data Types 000140 77 My-First-Number-Intrinsic PIC S9(4) USAGE IS COMP-5. 000150 77 My-First-Number-Int8Demo PIC S9(5) USAGE IS COMP-5. 000160 77 My-Second-Number-Intrinsic PIC S9(9) USAGE IS COMP-5. 000170 77 My-Third-Number-Intrinsic USAGE IS COMP-2. 000180* Declare Data Items using .NET Data Types 000190 77 My-First-Number-ObjectRef OBJECT REFERENCE SYS-INT16. 000200 77 My-Second-Number-ObjectRef OBJECT REFERENCE SYS-INT32. 000210 77 My-Third-Number-ObjectRef OBJECT REFERENCE SYS-DOUBLE. 000220 000230 01 NULL-X PIC X(1). 000240 LINKAGE SECTION. 000250* 000260 PROCEDURE DIVISION. 000270* Move numeric literal to Data Item 000280 MOVE 32767 TO My-First-Number-Int8Demo. 000290 MOVE 32767 TO My-First-Number-Intrinsic. 000300* Commented out to shorten ILDASM output display. 000310* Display "Pic5 " My-First-Number-Int8Demo 000320* Display "Pic4 " My-First-Number-Intrinsic 000330* 000340* DISPLAY "Enter X and Press Enter to Exit.". 000350* ACCEPT NULL-X. 000360* 000370 END PROGRAM MAIN.
I have added a field called My-First-Number-Int8Demo at line 150 with the PIC value of S9(5). Additionally, I have added logic statements at lines 280 through 350.
By default, the ILDASM GUI is used to view the MSIL, as shown in Figure 6-7.
In the ILDASM display, notice the difference between My-First-Number-Intrinsic and My-First-Number-Int8Demo. If you are interested, you can doubleclick the Procedure tag (see Figure 6-8). Then, get ready for a lesson in learning to read intermediate language. Well, since you insisted, double-click the Procedure tag and look inside.
After you double-click the Procedure tag, you will see the full MSIL file for this program. I will grab a snippet from the ILDASM display to discuss further. The MSIL code snippet in Listing 6-8 is actual MSIL. Please take a look the entire snippet and pay special attention to lines IL_0058 through IL_0070.
IL_0026: stloc __MainSubInfo IL_002a: ldc.i4.s 32 IL_002c: ldsfld int32 MAIN::__CompInitialInfo IL_0031: or IL_0032: stsfld int32 MAIN::__CompInitialInfo IL_0037: ldsfld int32 MAIN::__CompInitialInfo IL_003c: ldc.i4.4 IL_003d: and IL_003e: brtrue.s IL_004a IL_0040: call void MAIN::__InitialProgram() IL_0045: call void MAIN::__ThreadInitialize() IL_004a: ldsfld int32 MAIN::__CompInitialInfo IL_004f: ldc.i4.4 IL_0050: or IL_0051: stsfld int32 MAIN::__CompInitialInfo IL_0056: br.s IL_0058 IL_0058: ldsfld unsigned int8[] MAIN::'MY-FIRST-NUMBER-INT8DEMO_001CEDB0' IL_005d: ldc.i4.0 IL_005e: ldelema unsigned int8 IL_0063: ldc.i4 0x7fff IL_0068: conv.i4 IL_0069: stind.i4 IL_006a: ldc.i4 0x7fff IL_006f: conv.i2 IL_0070: stsfld int16 MAIN::'MY-FIRST-NUMBER-INTRINSIC_001CECF8' IL_0075: leave.s IL_009b
Let's take just a few lines of MSIL and figure out exactly what's going on. Remember, this MSIL represents two lines (two MOVE statements, both moving the value of 32767) of original COBOL .NET logic. Table 6-1 shows the MSIL code and a brief description what the MSIL accomplishes.
MSIL CODE | DESCRIPTION |
---|---|
IL_0058: ldsfld | Load the static field (the Int8 array). |
IL_005d: ldc.i4.0 | Load the numeric constant, which is zero for now. |
IL_005e: ldelema | Load the address of the array element. |
IL_0063: ldc.i4 | Load the numeric constant, 0x7fff or 32767. |
IL_0068: conv.i4 | Convert the length to Int32. |
IL_0069: stind.i4 | Store a value of type natural int. |
IL_006a: ldc.i4 | Load the numeric constant, 0x7fff or 32767. |
IL_006f: conv.i2 | Convert the length to Int16. |
IL_0070: stsfld | Replace the value of a static field. |
So, you can see that the COBOL .NET field that you kept with the original picture definition of S9(4) maps to an Int16 (as intended). Additionally, as the MSIL line IL_006f shows, after the value of 32767 is moved, the data type remains as Int16. On the other hand, the field that you changed to S9(5) appears to transition from an Int8 type array up to an Int32 type data item. Interesting? Fun? Remind you of assembler programming?
Now it is your turn . Perhaps you can execute the ILDASM utility against the Visual Basic sample code DefineDataTypesSampleVB. Check to see why I made the claim that the VB .NET data types and the native .NET data types are equivalent. This ILDASM utility will really help answer these types of questions and many more. Have fun with it.
Tip | Run ILDASM with the /? option at the command line to discover the many options available when executing this utility. |