Appendix A: IL Quick Reference


This appendix lists the entire set of IL instructions in the CIL and MSIL instruction sets. Chapters 2 and 3 describe nearly all of the facets discussed below in detail and with more context. Metadata, defs, refs, and specs, and the assembly file format are all discussed in Chapter 4. Lastly, Chapter 5 describes the base classes referred to by many instructions, such as int32, int64, float32, and native int. It's recommended that you use those chapters to decipher any information that lacks sufficient context in the following reference information.

IL Reference Table

The tables below describe all 226 of the IL instructions at your disposal. This is not meant to be an exhaustive description of each instruction; that would consume a book in itself. Rather, this should serve for a quick lookup when you are trying to remember an instruction or the format for using one. Chapter 3 discusses in more detail some of the more interesting and important instructions.

The table below describes a few attributes of each instruction (a.k.a. opcode):

  • Name and Opcode represent the textual and binary encoding for an instruction, respectively. If you're working with IL, you'll refer to it by name; the actual assembly contains the binary encoding, however. The Bytes column indicates how many bytes the binary form consumes in the file; instructions that take arguments (described below) can consume more space, as indicated by the (+Ops) part.

  • The Stack Transition depicts the effect a given instruction has on the state of the execution stack. As discussed in Chapter 3, IL is a stack-based language. The format is <before> __ <after>, where is used to represent some uninteresting (and unmodified) stack state. For example, , a, b __ means that a and b are popped off the stack and nothing is pushed back on. Similarly, , a __ , b means that a is popped off and b is pushed on.

  • Each IL instruction may take arguments that are encoded in the binary representation and not dynamically consumed off the execution stack. If this is the case, the Name will say <operand> and the Operand column describes the type of operand accepted.

  • Lastly, the Description column summarizes briefly what the instruction does. Again, these are not complete descriptions. Please refer to the latest CLI specification for more details.

Primitives

The primitive instructions form the base-level machine instructions, including arithmetic, some control, flow, comparisons, and conversions.

Name

Stack Transition

Operand

Flow Control

Opcode

Bytes(+Ops)

Description

add

, val_L1, val_L2 __ , val_R1

n/a

1

0x58

n/a

Adds val_L1 and val_L2 from the top of the stack and pushes the result onto the evaluation stack.

add.ovf

, val_L1, val_L2 __ , val_R1

n/a

n/a

0xD6

1

Adds the integer values val_L1 and val_L2 from the top of the stack, performs an overflow check, and pushes the result onto the evaluation stack.

add.ovf.un

, val_L1, val_L2 __ , val_R1

n/a

n/a

0xD7

1

Adds two unsigned integer values, val_L1 and val_L2, from the top of the stack, performs an overflow check, and pushes the result onto the evaluation stack.

and

, val_L1, val_L2 __ , val_R1

n/a

n/a

0x5F

1

Computes the bitwise AND of two values, val_L1 and val_L2, and pushes the result onto the evaluation stack.

arglist

__ , i4_R1

n/a

n/a

0xFE00

2

Returns an unmanaged pointer (System.RuntimeArgumentHandle) to the argument list of the current method. The lifetime of the handle ends when the current method returns, and can only be generated inside a method that takes a variable number of arguments.

br <operand>

__

Branch Target (i4)

Unconditional Branch

0x38

1 (+4)

Unconditionally transfers control to a target instruction <operand>.

break

__

n/a

Break

0x1

1

Signals the Common Language Infrastructure (CLI) to inform the debugger that a break point has been tripped.

brfalse <operand>

, i4_L1 __

Branch Target (i4)

Conditional Branch

0x39

1 (+4)

Transfers control to a target instruction <operand> if i4_L1 is false, a null reference (Nothing in Visual Basic), or zero.

brtrue <operand>

, i4_L1 __

Branch Target (i4)

Conditional Branch

0x3A

1 (+4)

Transfers control to a target instruction <operand> if i4_L1 is true, is not null, or is nonzero.

ceq

, val_L1, val_L2 __ , i4_R1

n/a

n/a

0xFE01

2

Compares two values, val_L1 and val_L2. If they are equal, the integer value 1 (int32) is pushed onto the evaluation stack; otherwise 0 (int32) is pushed onto the evaluation stack.

cgt

, val_L1, val_L2 __ , i4_R1

n/a

n/a

0xFE02

2

Compares two values val_L1 and val_L2. If the first value is greater than the second, the integer value 1 (int32) is pushed onto the evaluation stack; otherwise, 0 (int32) is pushed onto the evaluation stack.

cgt.un

, val_L1, val_L2 __ , i4_R1

n/a

n/a

0xFE03

2

Compares two unsigned or unordered values, val_L1 and val_L2. If the first value is greater than the second, the integer value 1 (int32) is pushed onto the evaluation stack; otherwise, 0 (int32) is pushed onto the evaluation stack.

ckfinite

, val_L1 __ , r8_R1

n/a

n/a

0xC3

1

Throws an ArithmeticException if val_L1 (a floating point number) is not a finite number, meaning that it is either "not a number" or is an infinity value.

clt

, val_L1, val_L2 __ , i4_R1

n/a

n/a

0xFE04

2

Compares two values val_L1 and val_L2. If the first value is less than the second, the integer value 1 (int32) is pushed onto the evaluation stack; otherwise, 0 (int32) is pushed onto the evaluation stack.

clt.un

, val_L1, val_L2 __ , i4_R1

n/a

n/a

0xFE05

2

Compares the unsigned or unordered values val_L1 and val_L2. If the first value is less than the second, then the integer value 1 (int32) is pushed onto the evaluation stack; otherwise, 0 (int32) is pushed onto the evaluation stack.

conv.i

, val_L1 __ , i4_R1

n/a

n/a

0xD3

1

Converts the value val_L1 on top of the evaluation stack to native int.

conv.i1

, val_L1 __ , i4_R1

n/a

n/a

0x67

1

Converts the value val_L1 on top of the evaluation stack to int8, then extends (pads) it to int32.

conv.i2

, val_L1 __ , i4_R1

n/a

n/a

0x68

1

Converts the value val_L1 on top of the evaluation stack to int16, then extends (pads) it to int32.

conv.i4

, val_L1 __ , i4_R1

n/a

n/a

0x69

1

Converts val_L1 on top of the evaluation stack to int32.

conv.i8

, val_L1 __ , i8_R1

n/a

n/a

0x6A

1

Converts the value val_L1 on top of the evaluation stack to int64.

conv.ovf.i

, val_L1 __ , i4_R1

n/a

n/a

0xD4

1

Converts the signed value val_L1 on top of the evaluation stack to signed native int, throwing an OverflowException on overflow.

conv.ovf.i.un

, val_L1 __ , i4_R1

n/a

n/a

0x8A

1

Converts the unsigned value val_L1 on top of the evaluation stack to signed native int, throwing an OverflowException on overflow.

conv.ovf.i1

, val_L1 __ , i4_R1

n/a

n/a

0xB3

1

Converts the signed value val_L1 on top of the evaluation stack to signed int8 and extends it to int32, throwing an OverflowException on overflow.

conv.ovf.i1.un

, val_L1 __ , i4_R1

n/a

n/a

0x82

1

Converts the unsigned value val_L1 on top of the evaluation stack to signed int8 and extends it to int32, throwing an OverflowException on overflow.

conv.ovf.i2

, val_L1 __ , i4_R1

n/a

n/a

0xB5

1

Converts the signed value val_L1 on top of the evaluation stack to signed int16 and extends it to int32, throwing an OverflowException on overflow.

conv.ovf.i2.un

, val_L1 __ , i4_R1

n/a

n/a

0x83

1

Converts the unsigned value val_L1 on top of the evaluation stack to signed int16 and extends it to int32, throwing an OverflowException on overflow.

conv.ovf.i4

, val_L1 __ , i4_R1

n/a

n/a

0xB7

1

Converts the signed value val_L1 on top of the evaluation stack to signed int32, throwing an OverflowException on overflow.

conv.ovf.i4.un

, val_L1 __ , i4_R1

n/a

n/a

0x84

1

Converts the unsigned value val_L1 on top of the evaluation stack to signed int32, throwing an OverflowException on overflow.

conv.ovf.i8

, val_L1 __ , i8_R1

n/a

n/a

0xB9

1

Converts the signed value val_L1 on top of the evaluation stack to signed int64, throwing an OverflowException on overflow.

conv.ovf.i8.un

, val_L1 __ , i8_R1

n/a

n/a

0x85

1

Converts the unsigned value val_L1 on top of the evaluation stack to signed int64, throwing an OverflowException on overflow.

conv.ovf.u

, val_L1 __ , i4_R1

n/a

n/a

0xD5

1

Converts the signed value val_L1 on top of the evaluation stack to unsigned native int, throwing an OverflowException on overflow.

conv.ovf.u.un

, val_L1 __ , i4_R1

n/a

n/a

0x8B

1

Converts the unsigned value value_1 on top of the evaluation stack to unsigned native int, throwing an OverflowException on overflow.

conv.ovf.u1

, val_L1 __ , i4_R1

n/a

n/a

0xB4

1

Converts the signed value val_L1 on top of the evaluation stack to unsigned int8 and extends it to int32, throwing an OverflowException on overflow.

conv.ovf.u1.un

, val_L1 __ , i4_R1

n/a

n/a

0x86

1

Converts the unsigned value val_L1 on top of the evaluation stack to unsigned int8 and extends it to int32, throwing an OverflowException on overflow.

conv.ovf.u2

, val_L1 __ , i4_R1

n/a

n/a

0xB6

1

Converts the signed value val_L1 on top of the evaluation stack to unsigned int16 and extends it to int32, throwing an OverflowException on overflow.

conv.ovf.u2.un

, val_L1 __ , i4_R1

n/a

n/a

0x87

1

Converts the unsigned value val_L1 on top of the evaluation stack to unsigned int16 and extends it to int32, throwing an OverflowException on overflow.

conv.ovf.u4

, val_L1 __ , i4_R1

n/a

n/a

0xB8

1

Converts the signed value val_L1 on top of the evaluation stack to unsigned int32, throwing an OverflowException on overflow.

conv.ovf.u4.un

, val_L1 __ , i4_R1

n/a

n/a

0x88

1

Converts the unsigned value val_L1 on top of the evaluation stack to unsigned int32, throwing an OverflowException on overflow.

conv.ovf.u8

, val_L1 __ , i8_R1

n/a

n/a

0xBA

1

Converts the signed value val_L1 on top of the evaluation stack to an unsigned int64, throwing an OverflowException on overflow.

conv.ovf.u8.un

, val_L1 __ , i8_R1

n/a

n/a

0x89

1

Converts the unsigned value val_L1 on top of the evaluation stack to an unsigned int64, throwing an OverflowException on overflow.

conv.r.un

, val_L1 __ , r8_R1

n/a

n/a

0x76

1

Converts the unsigned integer value val_L1 on top of the evaluation stack to float32.

conv.r4

, val_L1 __ , r4_R1

n/a

n/a

0x6B

1

Converts the value val_L1 on top of the evaluation stack to float32.

conv.r8

, val_L1 __ , r8_R1

n/a

n/a

0x6C

1

Converts the value val_L1 on top of the evaluation stack to float64.

conv.u

, val_L1 __ , i4_R1

n/a

n/a

0xE0

1

Converts the value val_L1 on top of the evaluation stack to unsigned native int, and extends it to native int.

conv.u1

, val_L1 __ , i4_R1

n/a

n/a

0xD2

1

Converts the value val_L1 on top of the evaluation stack to unsigned int8, and extends it to int32.

conv.u2

, val_L1 __ , i4_R1

n/a

n/a

0xD1

1

Converts the value val_L1 on top of the evaluation stack to unsigned int16, and extends it to int32.

conv.u4

, val_L1 __ , i4_R1

n/a

n/a

0x6D

1

Converts the value val_L1 on top of the evaluation stack to unsigned int32, and extends it to int32.

conv.u8

, val_L1 __ , i8_R1

n/a

n/a

0x6E

1

Converts the value val_L1 on top of the evaluation stack to unsigned int64, and extends it to int64.

cpblk

, i4_L1, i4_L2, i4_L3 __

n/a

n/a

0xFE17

2

Copies a specified number bytes i4_L3 from a source address i4_L1 of type native int or & to a destination address i4_L2 also of type native int or &.

div

, val_L1, val_L2 __ , val_R1

n/a

n/a

0x5B

1

Divides two values val_L1 and val_L2 and pushes the result as a floating point (float) or quotient (int32) onto the evaluation stack.

div.un

, val_L1, val_L2 __ , val_R1

n/a

n/a

0x5C

1

Divides two unsigned integer values, val_L1 and val_L2, and pushes the result (int32) onto the evaluation stack.

dup

, val_L1 __ , val_R1, val_R2

n/a

n/a

0x25

1

Copies the current topmost value on the evaluation stack, val_L1, and then pushes the copy onto the evaluation stack.

endfilter

, i4_L1 __

n/a

Method Return

0xFE11

2

Transfers control from the filter clause of an exception back to the CLI exception handler. The value i4_L1 can be either 0 or 1 to indicate the CLI should continue its search for an exception handler, or that the filter will handle the exception, respectively. Exception handling is detailed further in Chapter 3.

endfinally

__

n/a

Method Return

0xDC

1

Transfers control from the fault or finally clause of an exception block back to the CLI exception handler.

initblk

, i4_L1, i4_L2, i4_L3 __

n/a

n/a

0xFE18

2

Initializes a specified block of memory starting at a specific address i4_L1 (of type native int or &) of a given size i4_L3, by filling it with bytes whose initial values are i4_L2.

jmp <operand>

__

Method Token (i4)

Method Call

0x27

1 (+4)

Exits current method and jumps to specified method <operand>.

ldarg <operand>

__ , val_R1

Ordinal (i2)

n/a

0xFE09

2 (+2)

Loads an argument (referenced by a specified index value <operand>) onto the stack. Arguments begin at 0 and vary based on the method signature. The 0th argument is the this pointer for instance methods.

ldarga <operand>

__ , i4_R1

Ordinal (i2)

n/a

0xFE0A

2 (+2)

Load an argument address onto the evaluation stack as a managed pointer. This pointer is used for byref parameter passing only and is only valid for the lifetime of a method.

ldc.i4 <operand>

__ , i4_R1

Integer (i4)

n/a

0x20

1 (+4)

Pushes a supplied constant value <operand> of type int32 onto the evaluation stack as an int32.

ldc.i8 <operand>

__ , i8_R1

Integer (i8)

n/a

0x21

1 (+8)

Pushes a supplied constant value <operand> of type int64 onto the evaluation stack as an int64.

ldc.r4 <operand>

__ , r4_R1

Float (r4)

n/a

0x22

1 (+4)

Pushes a supplied constant value <operand> of type float32 onto the evaluation stack as type float.

ldc.r8 <operand>

__ , r8_R1

Float (r8)

n/a

0x23

1 (+8)

Pushes a supplied constant value <operand> of type float64 onto the evaluation stack as type float.

ldftn <operand>

__ , i4_R1

Method Token (i4)

n/a

0xFE06

2 (+4)

Pushes an unmanaged function pointer (type native int) to the native code implementing a specific method <operand> onto the evaluation stack. The calli instruction may be used to invoke the method indirectly through the resulting pointer.

ldind.i

, i4_L1 __ , i4_R1

n/a

n/a

0x4D

1

Loads a value of type native int as a native int onto the evaluation stack indirectly by dereferencing i4_L1.

ldind.i1

, i4_L1 __ , i4_R1

n/a

n/a

0x46

1

Loads a value of type int8 as an int32 onto the evaluation stack indirectly by dereferencing i4_L1.

ldind.i2

, i4_L1 __ , i4_R1

n/a

n/a

0x48

1

Loads a value of type int16 as an int32 onto the evaluation stack indirectly by dereferencing i4_L1.

ldind.i4

, i4_L1 __ , i4_R1

n/a

n/a

0x4A

1

Loads a value of type int32 as an int32 onto the evaluation stack indirectly by dereferencing i4_L1.

ldind.i8

, i4_L1 __ , i8_R1

n/a

n/a

0x4C

1

Loads a value of type int64 as an int64 onto the evaluation stack indirectly by dereferencing i4_L1.

ldind.r4

, i4_L1 __ , r4_R1

n/a

n/a

0x4E

1

Loads a value of type float32 as a type float onto the evaluation stack indirectly by dereferencing i4_L1.

ldind.r8

, i4_L1 __ , r8_R1

n/a

n/a

0x4F

1

Loads a value of type float64 as a type float onto the evaluation stack indirectly by dereferencing i4_L1.

ldind.ref

, i4_L1 __ , ref_R1

n/a

n/a

0x50

1

Loads an object reference onto the evaluation stack indirectly by dereferencing i4_L1.

ldind.u1

, i4_L1 __ , i4_R1

n/a

n/a

0x47

1

Loads a value of type unsigned int8 as an int32 onto the evaluation stack indirectly by dereferencing i4_L1.

ldind.u2

, i4_L1 __ , i4_R1

n/a

n/a

0x49

1

Loads a value of type unsigned int16 as an int32 onto the evaluation stack indirectly by dereferencing i4_L1.

ldind.u4

, i4_L1 __ , i4_R1

n/a

n/a

0x4B

1

Loads a value of type unsigned int32 as an int32 onto the evaluation stack indirectly by dereferencing i4_L1.

ldloc <operand>

__ , val_R1

Ordinal (i2)

n/a

0xFE0C

2 (+2)

Pushes the contents of the local variable at a specific index <operand> onto the evaluation stack. Local values smaller than 4 bytes get expanded to int32 in the process of loading onto the stack, and floating points expand to their native size float.

ldloca <operand>

__ , i4_R1

Ordinal (i2)

n/a

0xFE0D

2 (+2)

Loads the address of the local variable at a specific index <operand> onto the evaluation stack as a managed pointer. This may be used for byref argument passing and lives only as long as the containing method.

ldnull

__ , ref_R1

n/a

n/a

0x14

1

Pushes a null reference onto the evaluation stack.

ldtoken <operand>

__ , i4_R1

XxxRef Token (i4)

n/a

0xD0

1 (+4)

Converts a metadata token <operand> to its runtime representation, pushing it onto the evaluation stack. The token can be: (1) a methoddef, methodref, or methodspec, in which case a RuntimeMethodHandle results; (2) a typedef, typeref, or typespec, in which case a RuntimeTypeHandle is pushed; (3) a fielddef or fieldref, in which case a RuntimeFieldHandle is pushed.

ldvirtftn <operand>

, ref_L1 __ , i4_R1

Method Token (i4)

n/a

0xFE07

2 (+4)

Pushes an unmanaged pointer (type native int) to the native code implementing a particular virtual method <operand> associated with a specified object ref_L1 onto the evaluation stack. The resulting pointer can be used to invoke indirectly using the calli instruction.

leave <operand>

__

Branch Target (i4)

Unconditional Branch

0xDD

1 (+4)

Exits a protected region of code, unconditionally transferring control to a specific target instruction <operand>.

leave.s <operand>

__

Branch Target (i1)

Unconditional Branch

0xDE

1 (+1)

Exits a protected region of code, unconditionally transferring control to a target instruction <operand> (short form).

localloc

, i4_L1 __ , i4_R1

n/a

n/a

0xFE0F

2

Allocates a certain number of bytes i4_L1 from the local dynamic memory pool and pushes the address (a pointer of type native int) to the first allocated byte onto the evaluation stack. When the current method exits, the allocated memory will automatically become eligible for reuse.

mkrefany <operand>

, i4_L1 __ , val_R1

Type Token (i4)

n/a

0xC6

1 (+4)

Pushes a typed reference to an instance of a specific type referenced by the pointer i4_L1 onto the evaluation stack.

mul

, val_L1, val_L2 __ , val_R1

n/a

n/a

0x5A

1

Multiplies two values val_L1 and val_L2 and pushes the result on the evaluation stack.

mul.ovf

, val_L1, val_L2 __ , val_R1

n/a

n/a

0xD8

1

Multiplies two integer values val_L1 and val_L2, performs an overflow check, and pushes the result onto the evaluation stack.

mul.ovf.un

, val_L1, val_L2 __ , val_R1

n/a

n/a

0xD9

1

Multiplies two unsigned integer values val_L1 and val_L2, performs an overflow check, and pushes the result onto the evaluation stack.

neg

, val_L1 __ , val_R1

n/a

n/a

0x65

1

Negates a value val_L1 and pushes the result onto the evaluation stack.

nop

__

n/a

n/a

0x0

1

Fills space if opcodes are patched. No meaningful operation is performed although a processing cycle can be consumed. The C# compiler inserts nop instructions, for example, so that a debugger can be attached to curly braces.

not

, val_L1 __ , val_R1

n/a

n/a

0x66

1

Computes the bitwise complement of the integer value val_L1 on top of the stack and pushes the result onto the evaluation stack as the same type.

or

, val_L1, val_L2 __ , val_R1

n/a

n/a

0x60

1

Computes the bitwise complement of the two integer values, val_L1 and val_L2, on top of the stack and pushes the result onto the evaluation stack.

pop

, val_L1 __

n/a

n/a

0x26

1

Pops the value val_L1 off of the top of the evaluation stack.

refanytype

, val_L1 __ , i4_R1

n/a

n/a

0xFE1D

2

Retrieves the type token embedded in the typed reference val_L1.

refanyval <operand>

, val_L1 __ , i4_R1

Type Token (i4)

n/a

0xC2

1 (+4)

Retrieves the address (type &) embedded in the typed reference val_L1.

rem

, val_L1, val_L2 __ , val_R1

n/a

n/a

0x5D

1

Divides two values, val_L1 and val_L2, and pushes the remainder onto the evaluation stack.

rem.un

, val_L1, val_L2 __ , val_R1

n/a

n/a

0x5E

1

Divides two unsigned values, val_L1 and val_L2, and pushes the remainder onto the evaluation stack.

ret

, <lvaries> __

n/a

Method Return

0x2A

1

Returns from the current method, copying a return value (if present) <lvaries> from the current evaluation stack onto the evaluation stack of the calling method. <lvaries> must be zero items for void return types. The stack must be empty after popping <lvalies> off of the stack.

shl

, val_L1, val_L2 __ , val_R1

n/a

n/a

0x62

1

Shifts an integer value val_L1 to the left (in zeroes) by a specified number of bits val_L2, pushing the result onto the evaluation stack.

shr

, val_L1, val_L2 __ , val_R1

n/a

n/a

0x63

1

Shifts an integer value val_L1 (in sign) to the right by a specified number of bits val_L2, pushing the result onto the evaluation stack.

shr.un

, val_L1, val_L2 __ , val_R1

n/a

n/a

0x64

1

Shifts an unsigned integer value val_L1 (in zeroes) to the right by a specified number of bits val_L2, pushing the result onto the evaluation stack.

sizeof <operand>

__ , i4_R1

Type Token (i4)

n/a

0xFE1C

2 (+4)

Pushes the size, in bytes, of a supplied value type <operand> onto the evaluation stack.

starg <operand>

, val_L1 __

Ordinal (i2)

n/a

0xFE0B

2 (+2)

Stores the value on top of the evaluation stack val_L1 in the argument slot at the index specified by <operand>.

stind.i

, i4_L1, val_L2 __

n/a

n/a

0xDF

1

Stores a value i4_L1 of type native int at the supplied address val_L2.

stind.i1

, i4_L1, val_L2 __

n/a

n/a

0x52

1

Stores a value i4_L1 of type int8 at the supplied address val_L2.

stind.i2

, i4_L1, val_L2 __

n/a

n/a

0x53

1

Stores a value i4_L1 of type int16 at the supplied address val_L2.

stind.i4

, i4_L1, val_L2 __

n/a

n/a

0x54

1

Stores a value i4_L1 of type int32 at the supplied address val_L2.

stind.i8

, i4_L1, i8_L2 __

n/a

n/a

0x55

1

Stores a value i4_L1 of type int64 at the supplied address val_L2.

stind.r4

, i4_L1, r4_L2 __

n/a

n/a

0x56

1

Stores a value i4_L1 of type float32 at the supplied address val_L2.

stind.r8

, i4_L1, r8_L2 __

n/a

n/a

0x57

1

Stores a value i4_L1 of type float64 at the supplied address val_L2.

stind.ref

, i4_L1, val_L2 __

n/a

n/a

0x51

1

Stores the object reference value i4_L1 at the supplied address val_L2.

stloc <operand>

, val_L1 __

Ordinal (i2)

n/a

0xFE0E

2 (+2)

Pops the current value val_L1 from the top of the evaluation stack and stores it in the local variable slot at the index specified by <operand>.

stobj <operand>

, i4_L1, val_L2 __

Type Token (i4)

n/a

0x81

1 (+4)

Copies a value i4_L1 of a specified type <operand> from the evaluation stack into the supplied memory address val_L2.

sub

, val_L1, val_L2 __ , val_R1

n/a

n/a

0x59

1

Subtracts one value val_L2 from another value val_L1, pushing the result onto the evaluation stack.

sub.ovf

, val_L1, val_L2 __ , val_R1

n/a

n/a

0xDA

1

Subtracts one integer value val_L2 from another integer value val_L1, performs an overflow check, and pushes the result onto the evaluation stack.

sub.ovf.un

, val_L1, val_L2 __ , val_R1

n/a

n/a

0xDB

1

Subtracts one unsigned integer value val_L2 from another unsigned integer value val_L1, performs an overflow check, and pushes the result onto the evaluation stack.

switch <operands>

, i4_L1 __

N+1 Integers (i4)

Conditional Branch

0x45

1 (+4*n)

Implements a jump table. The <operands> format is one unsigned int32, which represents the number of targets N. It is then followed by N int32 values, which specify the positive or negative offsets for each jump. Switch pops i4_L1 off the stack, and if it is less than N, control transfers to the i4_L1th switch offset (0-based). Otherwise, it falls through to the next instruction.

xor

, val_L1, val_L2 __ , val_R1val_R1

n/a

n/a

0x61

1

Computes the bitwise XOR of the top two values, val_L1 and val_L2, on the evaluation stack, pushing the result onto the evaluation stack.

Object Model Instructions

These instructions have to do with the type system, interacting with things such as methods, fields, instance construction, runtime type checking, and array manipulation.

Name

Stack Transition

Operand

Flow Control

Opcode

Bytes (+Ops)

Description

call <operand>

, <lvaries> __ ,<rvaries>

Method Token (i4)

Method Call

0x28

1 (+4)

Calls the method indicated by the passed method descriptor <operand>. Avariable number of arguments are passed to the method as <lvaries>, including the this parameter for instance methods (leftmost argument); once the method returns, either zero or one items will be pushed onto the stack, representing a void and nonvoid return type, respectively.

calli <operand>

, <lvaries> __ , <rvaries>

Signature Token (i4)

Method Call

0x29

1 (+4)

Calls the method indicated on the evaluation stack (as a pointer to an entry point) with arguments described by a calling convention. <lvaries> and <rvaries> represent the arguments and optional return value, respectively, as described above for the call instruction.

callvirt <operand>

, <lvaries> __ , <rvaries>

Method Token (i4)

Method Call

0x6F

1 (+4)

Calls a late-bound method on an object, pushing the return value onto the evaluation stack. <lvaries> and <rvaies> represent the arguments and optional return value, respectively, as described above for the call instruction.

castclass <operand>

, ref_L1 __ , ref_R1

Type Token (i4)

n/a

0x74

1 (+4)

Attempts to cast an object ref_L1 passed by reference to the specified class <operand>. If ref_L1 refers to an object of a dynamically compatible type, the result is that ref_L1 is pushed back onto the stack. Otherwise, an InvalidCast Exception is raised.

box <operand>

, val_L1 __ , ref_R1

Type Token (i4)

n/a

0x8C

1 (+4)

Converts a value type val_L1 of type <operand> to an object reference. Boxing involves complex logic, described further in Chapters 2 and 3.

cpobj <operand>

, i4_L1, i4_L2 __

Type n/a Token (i4)

0x70

1 (+4)

Copies the value type located at the address val_L2 (native int, or managed or unmanaged pointer) to the address specified by val_L1(also of type native int, or managed or unmanaged pointer).

initobj <operand>

, i4_L1 __

Type Token (i4)

n/a

0xFE15

2 (+4)

Zeroes out the value at the address i4_L1. This has the effect of setting each of its fields to a null reference or a 0 of the appropriate primitive type.

isinst <operand>

, ref_L1 __ , i4_R1

Type Token (i4)

n/a

0x75

1 (+4)

Tests whether an object reference ref_L1 is an instance of a particular class <operand>. If the object is of a dynamically compatible type, the reference will be pushed back onto the stack. Otherwise, a null reference is pushed.

ldelem <operand>

, ref_L1, i4_L2 __ , val_R1

Type Token (i4)

n/a

0xA3

1 (+4)

Loads the element at index i4_L2 from the array pointed to by ref_L1 onto the stack. The array must contain elements of type <operand>. An IndexOutOfRangeException will be generated if i4_L2 is outside of the bounds of the target array.

ldelem.i

, ref_L1, i4_L2 __ , i4_R1

n/a

n/a

0x97

1

Loads the element at index i4_L2 from the array pointed to by ref_L1 onto the stack as a native int. The array must contain elements of type native int. An IndexOutOfRangeException will be generated if i4_L2 is outside of the bounds of the target array.

ldelem.i1

, ref_L1, i4_L2 __ , i4_R1

n/a

n/a

0x90

1

Loads the element at index i4_L2 from the array pointed to by ref_L1 onto the stack as an int32. The array must contain elements of type int8. An IndexOutOfRangeException will be generated if i4_L2 is outside of the bounds of the target array.

ldelem.i2

, ref_L1, i4_L2 __ , i4_R1

n/a

n/a

0x92

1

Loads the element at index i4_L2 from the array pointed to by ref_L1 onto the stack as an int32. The array must contain elements of type int16. An IndexOutOfRangeException will be generated if i4_L2 is outside of the bounds of the target array.

ldelem.i4

, ref_L1, i4_L2 __ , i4_R1

n/a

n/a

0x94

1

Loads the element at index i4_L2 from the array pointed to by ref_L1 onto the stack as an int32. The array must contain elements of type int32. An IndexOutOfRangeException will be generated if i4_L2 is outside of the bounds of the target array.

ldelem.i8

, ref_L1, i4_L2 __ , i8_R1

n/a

n/a

0x96

1

Loads the element at index i4_L2 from the array pointed to by ref_L1 onto the stack as an int64. The array must contain elements of type int64. An IndexOutOfRangeException will be generated if i4_L2 is outside of the bounds of the target array.

ldelem.r4

, ref_L1, i4_L2 __ , r4_R1

n/a

n/a

0x98

1

Loads the element at index i4_L2 from the array pointed to by ref_L1 onto the stack as a float. The array must contain elements of type float32. An IndexOutOfRangeException will be generated if i4_L2 is outside of the bounds of the target array.

ldelem.r8

, ref_L1, i4_L2 __ , r8_R1

n/a

n/a

0x99

1

Loads the element at index i4_L2 from the array pointed to by ref_L1 onto the stack as a float. The array must contain elements of type float64. An IndexOutOfRangeException will be generated if i4_L2 is outside of the bounds of the target array.

ldelem.ref

, ref_L1, i4_L2 __ , ref_R1

n/a

n/a

0x9A

1

Loads the element at index i4_L2 from the array pointed to by ref_L1 onto the stack as an object reference. An IndexOutOfRangeException will be generated if i4_L2 is outside of the bounds of the target array.

ldelem.u1

, ref_L1, i4_L2 __ , i4_R1

n/a

n/a

0x91

1

Loads the element at index i4_L2 from the array pointed to by ref_L1 onto the stack as an int32. The array must contain elements of type unsigned int8. An IndexOutOfRangeException will be generated if i4_L2 is outside of the bounds of the target array.

ldelem.u2

, ref_L1, i4_L2 __ ,i4_R1

n/a

n/a

0x93

1

Loads the element at index i4_L2 from the array pointed to by ref_L1 onto the stack as an int32. The array must contain elements of type unsigned int16. An IndexOutOfRangeException will be generated if i4_L2 is outside of the bounds of the target array.

ldelem.u4

, ref_L1, i4_L2 __ ,i4_R1

n/a

n/a

0x95

1

Loads the element at index i4_L2 from the array pointed to by ref_L1 onto the stack as an int32. The array must contain elements of type unsigned int32. An IndexOutOfRangeException will be generated if i4_L2 is outside of the bounds of the target array.

ldelema <operand>

, ref_L1, i4_L2 __ , i4_R1

Type Token (i4)

n/a

0x8F

1 (+4)

Loads the address of the array element at index i4_L2 from the array pointed to by ref_L1 onto the stack as a managed pointer. The array must contain elements of type <operand>. An IndexOutOfRangeException will be generated if i4_L2 is outside of the bounds of the target array.

ldfld , <operand>

ref_L1 __ , val_R1

Field Token (i4)

n/a

0x7B

1 (+4)

Pushes the value of a field <operand> for the object ref_L1 whose reference is currently on the evaluation stack.

ldflda <operand>

, ref_L1 __ , i4_R1

Field Token (i4)

n/a

0x7C

1 (+4)

Loads a pointer containing the address of a field <operand> for the object ref_L1 whose reference is currently on the evaluation stack.

ldlen

, ref_L1 __ , i4_R1

n/a

n/a

0x8E

1

Pushes the number of elements of a zero-based, 1-dimensional array pointed to by ref_L1 onto the evaluation stack.

ldobj <operand>

, i4_L1 __ , val_R1

Type Token (i4)

n/a

0x71

1 (+4)

Copies the value pointed to by the managed or unmanaged pointer i4_L1 (of type <operand>) to the top of the evaluation stack.

ldsfld <operand>

__ , val_R1

Field Token (i4)

n/a

0x7E

1 (+4)

Pushes the value of a static field <operand> onto the evaluation stack.

ldsflda <operand>

__ , i4_R1

Field Token (i4)

n/a

0x7F

1 (+4)

Loads a pointer containing the address of a static field <operand> onto the evaluation stack.

ldstr <operand>

__ , ref_R1

String Token (i4)

n/a

0x72

1 (+4)

Pushes a new object reference onto the stack pointing to a string literal indexed by the metadata <operand>.

newarr <operand>

, i4_L1 __ , ref_R1

Type Token (i4)

n/a

0x8D

1 (+4)

Pushes an object reference to a new zero-based, 1-dimensional array whose elements are of the type <operand> onto the evaluation stack. Its element count is i4_L1, and is zeroed out (i.e., value types are 0s, and reference types are nulls).

newobj <operand>

, <lvaries> __ , ref_R1

Method Token (i4)

Method Call

0x73

1 (+4)

Creates a new object or a new instance of a value type, pushing an object reference onto the evaluation stack. The <operand> specifies a constructor method token to be called for object initialization, and <lvaries> corresponds to arguments to that constructor. It can be zero or more items.

rethrow

__

n/a

Exception Throw

0xFE1A

2

Rethrows the current exception, without resetting the stack trace. This is only valid within the body of a catch handler.

stelem <operand>

, ref_L1, i4_L2, val_L3 __

Type Token (i4)

n/a

0xA4

1 (+4)

Stores the item val_L3 in the array pointed to by ref_L1 at element index i4_L2. The array must contain elements of type <operand>.

stelem.i

, ref_L1, i4_L2, i4_L3 __

n/a

n/a

0x9B

1

Stores the item i4_L3 into the array pointed to by ref_L1 at element index i4_L2. The array must contain elements of type native int.

stelem.i1

, ref_L1, i4_L2, i4_L3 __

n/a

n/a

0x9C

1

Stores the item i4_L3 into the array pointed to by ref_L1 at element index i4_L2. The array must contain elements of type int8.

stelem.i2

, ref_L1, i4_L2, i4_L3 __

n/a

n/a

0x9D

1

Stores the item i4_L3 into the array pointed to by ref_L1 at element index i4_L2. The array must contain elements of type int16.

stelem.i4

, ref_L1, i4_L2, i4_L3 __

n/a

n/a

0x9E

1

Stores the item i4_L3 into the array pointed to by ref_L1 at element index i4_L2. The array must contain elements of type int32.

stelem.i8

, ref_L1, i4_L2, i8_L3 __

n/a

n/a

0x9F

1

Stores the item i8_L3 in the array pointed to by ref_L1 at element index i4_L2. The array must contain elements of type int64.

stelem.r4

, ref_L1, i4_L2, r4_L3 __

n/a

n/a

0xA0

1

Stores the item r4_L3 into the array pointed to by ref_L1 at element index i4_L2. The array must contain elements of type float32.

stelem.r8

, ref_L1, i4_L2, r8_L3 __

n/a

n/a

0xA1

1

Stores the item r8_L3 in the array pointed to by ref_L1 at element index i4_L2. The array must contain elements of type float64.

stelem.ref

, ref_L1, i4_L2, ref_L3 __

n/a

n/a

0xA2

1

Stores the item ref_L3 into the array pointed to by ref_L1 at element index i4_L2.

stfld <operand>

, ref_L1, val_L2 __

Field Token (i4)

n/a

0x7D

1 (+4)

Replaces the value stored in the field <operand> of an object reference or pointer

ref_L1 with a new value val_L2.stsfld

, val_L1 __

Field

n/a

0x80

1 (+4)

<operand>

Token (i4)

Replaces the value of a static field <operand> with a value val_L1 from the evaluation stack.

throw

, ref_L1 __

n/a

Exception Throw

0x7A

1

Throws the exception object ref_L1 currently on the evaluation stack. Exceptions are described in detail in Chapter 3.

unbox <operand>

, ref_L1 __ , i4_R1

Type Token (i4)

n/a

0x79

1 (+4)

Converts the boxed representation of a value type referred to by ref_L1 to its unboxed form, of type <operand>. Please refer to Chapters 2 and 3 for more information about the boxing and unboxing process.

unbox.any <operand>

, ref_L1 __ , val_R1

Type Token (i4)

n/a

0xA5

1 (+4)

Converts the boxed representation of a type referred to by ref_L1 to its unboxed form, of type <operand>. This instruction works generically for all types, including reference types, for which it simply echoes back the original reference. Please refer to Chapters 2 and 3 for more information about the boxing and unboxing process.

Macros

The macro instructions are simply those that are shortcuts for instructions already described above. They often offer convenience, which can lead to simpler code generation or a more compact binary IL encoding.

Name

Stack Transition

Operand

Flow Control

Opcode

Bytes (+Ops)

Description

beq <operand>

, val_L1, val_L2 __

Branch Target (i4)

Conditional Branch

0x3B

1 (+4)

Transfers control to a target instruction <operand> if the two values, val_L1 and val_L2, are equal.

beq.s <operand>

, val_L1, val_L2 __

Branch Target (i1)

Conditional Branch

0x2E

1 (+1)

Transfers control to a target instruction <operand> (short form) if the two values, val_L1 and val_L2, are equal.

bge <operand>

, val_L1, val_L2 __

Branch Target (i4)

Conditional Branch

0x3C

1 (+4)

Transfers control to a target instruction <operand> if the first value, val_L1, is greater than or equal to the second value, val_L2.

bge.s <operand>

, val_L1, val_L2 __

Branch Target (i1)

Conditional Branch

0x2F

1 (+1)

Transfers control to a target instruction <operand> (short form) if the first value, val_L1, is greater than or equal to the second value, val_L2.

bge.un <operand>

, val_L1, val_L2 __

Branch Target (i4)

Conditional Branch

0x41

1 (+4)

Transfers control to a target instruction <operand> if the first value, val_L1, is greater than or equal to the second value, val_L2, when comparing unsigned integer values or unordered float values.

bge.un.s <operand>

, val_L1, val_L2 __

Branch Target (i1)

Conditional Branch

0x34

1 (+1)

Transfers control to a target instruction <operand> (short form) if the first value, val_L1, is greater than or equal to the second value, val_l2, when comparing unsigned integer values or unordered float values.

bgt <operand>

, val_L1, val_L2 __

Branch Target (i4)

Conditional Branch

0x3D

1 (+4)

Transfers control to a target instruction <operand> if the first value, val_L1, is greater than the second value, val_L2.

bgt.s <operand>

, val_L1, val_L2 __

Branch Target (i1)

Conditional Branch

0x30

1 (+1)

Transfers control to a target instruction <operand> (short form) if the first value, val_L1, is greater than the second value, val_L2.

bgt.un <operand>

, val_L1, val_L2 __

Branch Target (i4)

Conditional Branch

0x42

1 (+4)

Transfers control to a target instruction <operand> if the first value, val_L1, is greater than the second value, val_L2, when comparing unsigned integer values or unordered float values.

bgt.un.s <operand>

, val_L1, val_L2 __

Branch Target (i1)

Conditional Branch

0x35

1 (+1)

Transfers control to a target instruction <operand> (short form) if the first value, val_L1, is greater than the second value, val_L2, when comparing unsigned integer values or unordered float values.

ble <operand>

, val_L1, val_L2 __

Branch Target (i4)

Conditional Branch

0x3E

1 (+4)

Transfers control to a target instruction <operand> if the first value, val_L1, is less than or equal to the second value, val_L2.

ble.s <operand>

, val_L1, val_L2 __

Branch Target (i1)

Conditional Branch

0x31

1 (+1)

Transfers control to a target instruction <operand> (short form) if the first value, val_L1, is less than or equal to the second value, val_L2.

ble.un <operand>

, val_L1, val_L2 __

Branch Target (i4)

Conditional Branch

0x43

1 (+4)

Transfers control to a target instruction <operand> if the first value, val_L1, is less than or equal to the second value, val_L2, when comparing unsigned integer values or unordered float values.

ble.un.s <operand>

, val_L1, val_L2 __

Branch Target (i1)

Conditional Branch

0x36

1 (+1)

Transfers control to a target instruction <operand> (short form) if the first value, val_L1, is less than or equal to the second value, val_L2, when comparing unsigned integer values or unordered float values.

blt <operand>

, val_L1, val_L2 __

Branch Target (i4)

Conditional Branch

0x3F

1 (+4)

Transfers control to a target instruction <operand> if the first value, val_L1, is less than the second value, val_L2.

blt.s <operand>

, val_L1, val_L2 __

Branch Target (i1)

Conditional Branch

0x32

1 (+1)

Transfers control to a target instruction <operand> (short form) if the first value, val_L1, is less than the second value, val_L2.

blt.un <operand>

, val_L1, val_L2 __

Branch Target (i4)

Conditional Branch

0x44

1 (+4)

Transfers control to a target instruction <operand> if the first value, val_L1, is less than the second value, val_L2, when comparing unsigned integer values or unordered float values.

blt.un.s <operand>

, val_L1, val_L2 __

Branch Target (i1)

Conditional Branch

0x37

1 (+1)

Transfers control to a target instruction <operand> (short form) if the first value, val_L1, is less than the second value, val_L2, when comparing unsigned integer values or unordered float values.

bne.un <operand>

, val_L1, val_L2 __

Branch Target (i4)

Conditional Branch

0x40

1 (+4)

Transfers control to a target instruction <operand> when two unsigned integer values or unordered float values, val_L1 and val_L2, are not equal.

bne.un.s <operand>

, val_L1, val_L2 __

Branch Target (i1)

Conditional Branch

0x33

1 (+1)

Transfers control to a target instruction <operand> (short form) when two unsigned integer values or unordered float values, val_L1 and val_L2, are not equal.

br.s <operand>

__

Branch Target (i1)

Unconditional Branch

0x2B

1 (+1)

Unconditionally transfers control to a target instruction <operand> (short form).

brfalse.s <operand>

, i4_L1 __

Branch Target (i1)

Conditional Branch

0x2C

1 (+1)

Transfers control to a target instruction <operand> if i4_L1 is false, a null reference, or zero.

brtrue.s <operand>

, i4_L1 __

Branch Target (i1)

Conditional Branch

0x2D

1 (+1)

Transfers control to a target instruction <operand> (short form) if i4_L1 is true, not null, or nonzero.

ldarg.0

__ , val_R1

n/a

n/a

0x2

1

Loads the argument at index onto the evaluation stack. The 0th argument is the this pointer for instance methods.

ldarg.1

__ , val_R1

n/a

n/a

0x3

1

Loads the argument at index 1 onto the evaluation stack.

ldarg.2

__ , val_R1

n/a

n/a

0x4

1

Loads the argument at index 2 onto the evaluation stack.

ldarg.3

__ , val_R1

n/a

n/a

0x5

1

Loads the argument at index 3 onto the evaluation stack.

ldarg.s <operand>

__ , val_R1

Ordinal (i1)

n/a

0xE

1 (+1)

Loads an argument (referenced by the specified index in short form <operand>) onto the stack. Arguments begin at 0 and vary based on the method signature. The 0th argument is the this pointer for instance methods.

ldarga.s <operand>

__ , i4_R1

Ordinal (i1)

n/a

0xF

1 (+1)

Load an argument address, in short form, onto the evaluation stack as a managed pointer. This pointer is used for byref parameter passing only and is only valid for the lifetime of a method.

ldc.i4.0

__ , i4_R1

n/a

n/a

0x16

1

Pushes the integer value of 0 onto the evaluation stack as an int32.

ldc.i4.1

__ , i4_R1

n/a

n/a

0x17

1

Pushes the integer value of 1 onto the evaluation stack as an int32.

ldc.i4.2

__ , i4_R1

n/a

n/a

0x18

1

Pushes the integer value of 2 onto the evaluation stack as an int32.

ldc.i4.3

__ , i4_R1

n/a

n/a

0x19

1

Pushes the integer value of 3 onto the evaluation stack as an int32.

ldc.i4.4

__ , i4_R1

n/a

n/a

0x1A

1

Pushes the integer value of 4 onto the evaluation stack as an int32.

ldc.i4.5

__ , i4_R1

n/a

n/a

0x1B

1

Pushes the integer value of 5 onto the evaluation stack as an int32.

ldc.i4.6

__ , i4_R1

n/a

n/a

0x1C

1

Pushes the integer value of 6 onto the evaluation stack as an int32.

ldc.i4.7

__ , i4_R1

n/a

n/a

0x1D

1

Pushes the integer value of 7 onto the evaluation stack as an int32.

ldc.i4.8

__ , i4_R1

n/a

n/a

0x1E

1

Pushes the integer value of 8 onto the evaluation stack as an int32.

ldc.i4.m1

__ , i4_R1

n/a

n/a

0x15

1

Pushes the integer value of -1 onto the evaluation stack as an int32.

ldc.i4.s <operand>

__ , i4_R1

Integer (i1)

n/a

0x1F

1 (+1)

Pushes the supplied int8 constant value <operand> onto the evaluation stack as an int32, short form.

ldloc.0

__ , val_R1

n/a

n/a

0x6

1

Loads the local variable at index 0 onto the evaluation stack.

ldloc.1

__ , val_R1

n/a

n/a

0x7

1

Loads the local variable at index 1 onto the evaluation stack.

ldloc.2

__ , val_R1

n/a

n/a

0x8

1

Loads the local variable at index 2 onto the evaluation stack.

ldloc.3

__ , val_R1

n/a

n/a

0x9

1

Loads the local variable at index 3 onto the evaluation stack.

ldloc.s <operand>

__ , val_R1

Ordinal (i1)

n/a

0x11

1 (+1)

Pushes the contents of the local variable at a specific index <operand> (short form) onto the evaluation stack. Local values smaller than 4 bytes get expanded to int32 in the process of loading onto the stack, and floating points expand to their native size float.

ldloca.s <operand>

__ , i4_R1

Ordinal (i1)

n/a

0x12

1 (+1)

Loads the address of the local variable at a specific index <operand> (short form) onto the evaluation stack as a managed pointer. This may be used for byref argument passing, and lives only as long as the containing method.

starg.s <operand>

, val_L1 __

Ordinal (i1)

n/a

0x10

1 (+1)

Stores the value on top of the evaluation stack val_L1 in the argument slot at a specified index <operand> , short form.

stloc.0

, val_L1 __

n/a

n/a

0xA

1

Pops the current value val_L1 from the top of the evaluation stack and stores it in the local variable slot at index 0.

stloc.1

, val_L1 __

n/a

n/a

0xB

1

Pops the current value val_L1 from the top of the evaluation stack and stores it in the local variable slot at index 1.

stloc.2

, val_L1 __

n/a

n/a

0xC

1

Pops the current value val_L1 from the top of the evaluation stack and stores it in the local variable slot at index 2.

stloc.3

, val_L1 __

n/a

n/a

0xD

1

Pops the current value val_L1 from the top of the evaluation stack and stores it in the local variable slot at index 3.

stloc.s <operand>

, val_L1 __

Ordinal (i1)

n/a

0x13

1 (+1)

Pops the current value val_L1 from the top of the evaluation stack and stores it in the local variable slot at the index specified by <operand> (short form).

Prefixes

Prefixes are unique in that they modify the instruction, which they precede. They do not get evaluated in isolation but rather change the semantics of the following instruction in some interesting way.

Name

Stack Transition

Operand

Flow Control

Opcode

Bytes (+Ops)

Description

constrained. <operand>

__

Type Token (i4)

n/a

0xFE16

2 (+4)

Used for callvirt instructions when the runtime type of an object is not known statically to be a value or reference type. Thus, compilers do not know whether to emit a box instruction or not. This occurs when the type of an object is parameterized by a generic type parameter, for example. Constrained. encapsulates the decision whether to box or not based on runtime type information, ensuring the right thing happens.

readonly.

__

n/a

n/a

0xFE1E

2

Can only appear just prior to a ldelema instruction, which loads the address to a precise element in an array. The purpose is to skip the runtime type check when dealing with arrays of a type parameterized by a generic parameter, in which case the check would be inefficient and incorrect.

tail.

__

n/a

n/a

0xFE14

2

tail. may prefix any call, callvirt, or calli instruction. It tells the engine that the current method's actual call instruction is executed. The return value of the target method is used for the return value of the calling method. This avoids unnecessarily growing the call stack, for example for recursive algorithms.

unaligned. <operand>

__

Integer (i1)

n/a

0xFE12

2 (+1)

Indicates that an address currently atop the evaluation stack might not be aligned to the natural size of the immediately following ldind, stind, ldfld, stfld, ldobj, stobj, initblk, or cpblk instruction.

volatile.

__

n/a

n/a

0xFE13

2

Specifies that an address currently atop the evaluation stack might be volatile, and the results of reading that location cannot be cached or that multiple stores to that location cannot be suppressed.




Professional. NET Framework 2.0
Professional .NET Framework 2.0 (Programmer to Programmer)
ISBN: 0764571354
EAN: 2147483647
Year: N/A
Pages: 116
Authors: Joe Duffy

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