Addressing Classes and Value Types

Addressing Classes and Value Types

Being object-oriented in its base, IL offers quite a few instructions dedicated specifically to manipulating class and value type instances:

  • ldnull (0x14)  Load a null object reference on the stack.

  • ldobj <token> (0x71)  Load an instance value type specified by <token> on the stack. This instruction pops from the stack the managed pointer to the value type instance to be loaded. <token> must be a valid TypeDef or TypeRef token. The name of the instruction is somewhat misleading, for it deals with value type instances rather than objects (class instances). The ILAsm notation requires full specification of the value type so that it can be resolved to the token. For example:

    ldobj [.module other.dll]Foo.Bar

  • stobj <token> (0x81)  Pop the value type value—no, that’s not a typo—from the stack, pop the managed pointer to the value type instance from the stack, and store the value type value in the instance. <token> indicates the value type and must be a valid TypeDef or TypeRef token. The ILAsm notation is similar to that used for ldobj.

  • ldstr <token> (0x72)  Load a string reference on the stack. <token> is a token of a user-defined string, whose RID portion is actually an offset in the #US blob stream. This instruction performs a lot of work: by the token, the Unicode string is retrieved from the #US stream, an instance of the [mscorlib]System.String class is created on the base of the retrieved string, and the object reference is pushed on the stack. In ILAsm, the string is specified explicitly either as a composite quoted string:

    ldstr "Hello"+" World!"

    or as a byte array:

    ldstr bytearray(A1 00 A2 00 A3 00 A4 00 A5 00 00 00)

    In the first case, at compile time the composite quoted string is converted to Unicode before being stored in the #US stream. In the second case, the byte array is stored “as is” without conversion. It can be padded with one 0 byte to make the byte count even. Storing a string in the #US stream gives the compiler the string token, which it puts into the IL stream.

  • cpobj <token> (0x70)  Copy the value of one value type instance to another instance. This instruction pops the source and the target instance pointers and pushes nothing on the stack. Both instances must be of the value type specified by <token>, either a TypeDef or a TypeRef token. The ILAsm notation for this instruction is similar to that used for ldobj or stobj.

  • newobj <token> (0x73)  Allocate memory for a new instance of a class—not a value type—and call the instance constructor method specified by <token>. This instruction pushes the object reference on the stack. <token> must be a valid MethodDef or MemberRef token. The instruction pops from the stack all the arguments explicitly specified in the constructor signature but does not pop the instance pointer. (No instance exists yet; it’s being created.) The newobj instruction is also used for array creation:

    newobj instance void [mscorlib]System.Object::.ctor( ) newobj instance void int32[0...,0... ]::.ctor(int32int32)

    An array conmstructor takes as many parameters as there are undefined lower bounds and sizes of the array being created. (And hence the same number of integer values must be loaded on the stack before newobj is invoked.) In the example just shown, both lower bounds of the two-dimensional array are specified in the array type, so we need to specify only two sizes.

  • initobj <token> (0xFE 0x15)  Initialize the value type instance. This instruction takes an instance pointer—a managed pointer to a value type instance—from the stack. <token> specifies the value type and must be a valid TypeDef or TypeRef token. The initobj instruction zeroes all the fields of the value type instance, so if you need more sophisticated initialization, you might want to define .ctor or .cctor and call it instead.

  • castclass <token> (0x74)  Cast a class instance to the class specified by <token>. This instruction takes the object reference to the original instance from the stack and pushes the object reference to the cast instance on the stack. <token> must be a valid TypeDef or TypeRef token.

  • isinst <token> (0x75)  Check to see whether the object reference on the stack is an instance of the class specified by <token>. <token> must be a valid TypeDef or TypeRef token. This instruction pops the object reference from the stack and pushes the result on the stack. If the check succeeds, the result is an object reference, as if castclass had been invoked; otherwise, it is a null reference, as if ldnull had been invoked. The check succeeds under the following conditions:

    • If <token> indicates a class and the object reference on the stack is an instance of this class or of any class derived from it

    • If <token> indicates an interface and the object reference is an instance of the class implementing this interface

    • If <token> indicates a value type and the object reference is a boxed instance of this value type

  • box <token> (0x8C)  Convert a value type instance to an object reference. <token> specifies the value type being converted and must be a valid TypeDef or TypeRef token. This instruction pops the value type instance from the stack, creates a new instance of the type as an object, and pushes the object reference to this instance on the stack.

  • unbox <token> (0x79)  Revert a boxed value type instance from the object form to its value type form. <token> specifies the value type being converted and must be a valid TypeDef or TypeRef token. This instruction takes an object reference from the stack and puts a managed pointer to the value type instance on the stack.

  • mkrefany <token> (0xC6)  Pop a pointer—either managed or unmanaged—from the stack and convert it to a typed reference (typedref). The typed reference is an opaque handle that carries both type information and an instance pointer. The type of the created typedref is specified by <token>, which must be a valid TypeDef or TypeRef token. Typically, this instruction is used to create the typedref values to be passed as arguments to methods that expect typedref parameters. These methods split the typed references into type information and instance pointers using the refanytype and refanyval instructions.

  • refanytype (0xFE 0x1D)  Pop a typed reference from the stack, retrieve the type information, and push the [internal] type [handle] on the stack. This instruction has no parameters.

  • refanyval (0xC2)  Pop a typed reference from the stack, retrieve the instance pointer (& or native int), and push it on the stack. This instruction has no parameters.

  • ldtoken < token> (0xD0)  Convert <token> to an internal metadata handle to be used in calls to the [mscorlib]System.Reflection methods in the .NET Framework class library. The admissible token types are MethodDef, MemberRef, TypeDef, TypeRef, and FieldDef. The handle pushed on the stack is an instance of one of the following value types: [mscorlib]System.RuntimeMethodHandle, [mscorlib]System.RuntimeTypeHandle, or [mscorlib]System.RuntimeFieldHandle.

    The ILAsm notation requires full specification for classes (value types), methods, and fields used in ldtoken. This instruction is the only IL instruction that is not specific to methods only or fields only, and thus the keyword method or field must be used:

    ldtoken [mscorlib]System.String ldtoken method instance void [mscorlib]System.Object::.ctor( ) ldtoken field int32 Foo.Bar::ff

  • sizeof <token> (0xFE 0x1C)  Load the size in bytes of the value type specified by <token> on the stack. <token> must be a valid TypeDef or TypeRef token.

  • throw (0x7A)  Pop the object reference from the stack and throw it as a managed exception. See Chapter 11 for details about structured exception handling.

  • rethrow (0xFE 0x1A)  Throw the caught exception again. This instruction can be used exclusively within exception handlers.



Inside Microsoft. NET IL Assembler
Inside Microsoft .NET IL Assembler
ISBN: 0735615470
EAN: 2147483647
Year: 2005
Pages: 147
Authors: SERGE LIDIN

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net