Addressing Arguments and Local Variables

Addressing Arguments and Local Variables

A special group of IL instructions is dedicated to loading the values of method arguments and local variables on the evaluation stack and storing the values taken from the stack in local variables and method arguments.

Method Argument Loading

The following instructions are used for loading method argument values on the evaluation stack:

  • ldarg <unsigned int16> (0xFE 0x09)  Load the argument number <unsigned int16> on the stack. The argument enumeration is zero-based, but it’s important to remember that instance methods have an “invisible” argument not specified in the method signature: the class instance pointer, this, which is always argument number 0. Because static methods don’t have such an “invisible” argument, for them argument number 0 is the first argument specified in the method signature.

  • ldarg.s <unsigned int8> (0x0E)  The short-parameter form of ldarg.

  • ldarg.0 (0x02)  Load argument number 0 on the stack.

  • ldarg.1 (0x03)  Load argument number 1 on the stack.

  • ldarg.2 (0x04)  Load argument number 2 on the stack.

  • ldarg.3 (0x05)  Load argument number 3 on the stack.

Method Argument Address Loading

These two instructions are used for loading method argument addresses on the evaluation stack:

  • ldarga <unsigned int16> (0xFE 0x0A)  Load the address of argument number <unsigned int16> on the stack.

  • ldarga.s <unsigned int8> (0x0F)  The short-parameter form of ldarga.

Method Argument Storing

These two instructions are used for storing a value from the stack in a method argument slot:

  • starg <unsigned int16> (0xFE 0x0B)  Take a value from the stack and store it in argument slot number <unsigned int16>. The value on the stack must be of the same type as the argument slot or must be convertible to the type of the argument slot. The convertibility rules and effects are the same as those for conversion operations, discussed earlier in this chapter. With vararg methods, the starg instruction cannot target the arguments of the variable part of the signature.

  • starg.s <unsigned int8> (0x10)  The short-parameter form of starg.

Method Argument List

The following instruction is used exclusively in vararg methods to retrieve the method argument list and put an instance of the value type [mscorlib]System.RuntimeArgumentHandle on the stack. Chapter 9, “Methods,” discusses the application of this instruction.

  • arglist (0xFE 0x00)  Get the argument list handle.

Local Variable Loading

Local variable loading instructions are similar to argument loading instructions except that no “invisible” items appear among the local variables, so local variable number 0 is always the first one specified in the local variable signature.

  • ldloc <unsigned int16> (0xFE 0x0C)  Load the value of local variable number <unsigned int16> on the stack. Local variable numbers can range from 0 to 0xFFFE.

  • ldloc.s <unsigned int8> (0x11)  The short-parameter form of ldloc.

  • ldloc.0 (0x06)  Load the value of local variable number 0 on the stack.

  • ldloc.1 (0x07)  Load the value of local variable number 1 on the stack.

  • ldloc.2 (0x08)  Load the value of local variable number 2 on the stack.

  • ldloc.3 (0x09)  Load the value of local variable number 3 on the stack.

Local Variable Reference Loading

The following instructions load references (managed pointers) to the local variables on the evaluation stack:

  • ldloca <unsigned int16> (0xFE 0x0D)  Load the address of local variable number <unsigned int16> on the stack. The local variable number can vary from 0 to 0xFFFE.

  • ldloca.s <unsigned int8> (0x12)  The short-parameter form of ldloca.

Local Variable Storing

It would be strange to have local variables and be unable to assign values to them. The following two instructions take care of this aspect of our life:

  • stloc <unsigned int16> (0xFE 0x0E)  Pop the value from the stack and store it in local variable slot number <unsigned int16>. The value on the stack must be of the same type as the argument slot or must be convertible to the type of the argument slot. The convertibility rules and effects are the same as those for the conversion operations, discussed earlier in this chapter.

  • stloc.s <unsigned int8> (0x13)  The short-parameter form of stloc. You’ve probably noticed that using short-parameter forms of argument and local variable manipulation instructions results in a double gain against the standard form: not only is the parameter 1 byte instead of 2, but also the opcode is shorter.

Local Block Allocation

With all due respect to the object-oriented approach, sometimes it is necessary (or just convenient) to obtain a plain, C-style chunk of memory. The IL instruction set provides an instruction for such allocation. It is to be noted, however, that the chunk of memory is allocated on the thread stack rather than on the heap. I’m talking about the native stack and heap now, used by the JIT-compiled code.

  • localloc (0xFE 0x0F)  Allocate a block of memory on the native thread stack. The instruction takes the block size (native unsigned int) from the evaluation stack and puts a managed pointer (&) to the allocated block on the evaluation stack. If not enough space is available on the native thread stack, a StackOverflow exception is thrown. This instruction must not appear within any structured exception handling block. Like any other block instruction, localloc is unverifiable.

Prefix Instructions

The prefix instructions listed in this section have no meaning per se but are used as prefixes for the pointer-consuming instructions—that is, instructions that take a pointer value from the stack—that immediately follow them, such as ldind.*, stind.*, ldfld, stfld, ldobj, stobj, initblk, and stblk. When they are used as prefixes of instructions that don’t consume pointers, the prefix instructions are ignored and do not carry on to the nearest pointer-consuming instruction.

  • unaligned. <unsigned int8> (0xFE 0x12)  Indicates that the pointer(s) on the stack are <unsigned int8>-aligned rather than aligned on the pointer size. The <unsigned int8> parameter must be 1, 2, or 4.

  • volatile. (0xFE 0x13)  Indicates that the pointer on the stack is volatile—that is, it can be modified from another thread of execution and the results of its dereferencing therefore cannot be cached for performance considerations.

A prefix instruction affects only the immediately following instruction and does not mark the respective pointer as unaligned or volatile throughout the entire method. Both prefixes can be used with the same instruction—in other words, the pointer on the stack can be marked as both unaligned and volatile; in such a case, the order of appearance of the prefixes does not matter.

The ILAsm syntax requires the prefix instructions to be separated from the next instruction by at least a space symbol:

volatile. ldind.i4 // Correct volatile.  ldind.i4 // Correct volatile.ldind.i4 // Syntax error

Such a mistake is unlikely with the unaligned. instruction because it requires an integer parameter:

unaligned. ldind.i4



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