IL series articles three: array in il

zhaozj2021-02-16  56

IL series articles three:

Array in il

As the topic said, this section we studied the Array in IL. We will see how to define an array, how to query the array element, use the freewheet and the foreign differences of the foreach statement.

Let's take a look at a program I wrote with C #:

Using system;

Class array1

{

Public static void

Main

()

{

Int [] Number;

Number = new int [6];

For (int i = 0; i <6; i )

{

Number [i] = i * i;

}

Foreach (int Num in Number)

{

Console.writeLine (Num.toString ());

}

}

}

This program believes that everyone can understand it (if you don't understand, don't look down). In this program we have seen the C # how to define an array, this is not too similar to the method used in C / C . C # uses the following two sentences to define an array:

Int [] Number;

Number = new int [6];

And use a sentence in C / C

Int Number [6];

enough. What is the reason for this difference? Don't panic, you can see it right away. Another point, there is a Foreach statement in C #, how is this statement compared to the traditional for statement? Look at it, it is the above program to use ILDASM anti-compilation (for everyone to see more, I have made some modifications to the IL program generated by anti-compilation).

.assembly array1 {}

.CLASS Private Auto Ansi Beforefieldinit Array11

Extends [mscorlib] system.Object

{

Public static void

Main

() CIL Managed

{

.entrypoint

.MAXSTACK 4

.locals init (int32 [] v_0, // int [] Number

INT32 V_1, // I

INT32 V_2,

INT32 [] V_3, // a Pointer of Array

INT32 V_4)

LDC.I4.6 // Load Int32 Const 6 (Length of the Array) Onto the Stack

NEWARR [mscorlib] system.int32 // Number = new int [6],

// Length of the array must be loaded ONTO THE Stack Before

STLOC.0 // Number

LDC.I4.0 // Load first local (v_0) Onto the stack

STLOC.1 // int i = 0

Br.s loopfor // goto "loopfor", "loopfor" is only a lable

// Startfor Is a Lable TOO

Startfor: ldloc.0 // Number

LDLOC.1 // load v_1 Onto the Stack

LDLOC.1

LDLOC.1

Mul // Multiply

STELEM.I4 // i = i * i

LDLOC.1

LDC.I4.1

Add

STLOC.1 // i = i 1

LOOPFOR: LDLOC.1

LDC.I4.6

Blt.s Startfor // IF i (v_1) Less Than 6, Goto "Startfor" LDLOC.0

STLOC.3 / / LOOK IT !!

LDC.I4.0

STLOC.S V_4

Br.s loopforeach

StartForeach: LDLOC.3

LDLOC.S V_4

Ldelem.i4

STLOC.2

LDLOCA.S V_2 / / LOAD Address of local_2 (v_3)

Call instance string [mscorlib] system.int32 :: toString ()

// Cast Int to a new string instance and stord it inTo local_2

Call void [mscorlib] System.console :: WriteLine (String) // Print IT

LDLOC.S V_4

LDC.I4.1

Add

STLOC.S V_4

LoopForeach: ldloc.s v_4 // index of v_3 []

LDLOC.3

ldlen

Conv.i4 // conver len to int32

Blt.s StartForeach

Ret // Return, Must Exist, or else the program will stop here

} // end of method array1 :: main

}

Analysis of this program We can see three steps to define an array, I don't know if you see it?

1. Define an array pointer, int32 [] V_0

2. Move the array length to the top of the stack, ldc.i4.6

3. For its assignment space, NEWARR [mscorlib] system.int32

This understands why the array in the C # is defined by two steps. The reason is that in C # we put the array to the hosted stack, while in C (Int Number [6]) array is not placed on the heap. IL can do C # can't do, if the lower boundary of the array may not start from 0, etc. (next time you have the opportunity to write an example J).

Assign a value for array elements, you need four steps.

1. Move the array to the top of the stack, LDLOC.0

2. Move the index of array elements to the top of the stack, LDLOC.1

3. Move the value to be assigned to the top of the stack (here is the same MUL operation),

4. Move the value from the top of the stack, assign the element, stelem.i4

The method of selecting array elements is similar to the above, but it is not necessary to use the third step, and the ST of step 4 is replaced with LD.

There is no essential difference for the for statement and the foreach statement. When using the foreach statement, IL will produce an array pointer INT32 [] V_3 in advance. When traversing an array, the pointer of the known group will be used to this pointer, and the future instructions are not a few different than the for statement.

About the usage of the one-dimensional array is basically almost the same, the next time I might want to write some contents about the multi-dimensional array and the zigzag array.

to be continued……

转载请注明原文地址:https://www.9cbs.com/read-27970.html

New Post(0)