3 Base Instructions


These instructions form a "Turing complete" set of basic operations. They are independent of the object model that may be employed. Operations that are specifically related to the CTS's object model are contained in the Object Model Instructions section [Partition III, section 4].

3.1 add Add Numeric Values

Format

Assembly Format

Description

58

add

Add two values, returning a new value.

Stack Transition:

…, value1, value2 …, result

Description:

The add instruction adds value2 to value1 and pushes the result onto the stack. Overflow is not detected for integral operations (but see add.ovf); floating point overflow returns +inf or -inf.

The acceptable operand types and their corresponding result data type are encapsulated in Table 6-2, Binary Numeric Operations.

Exceptions:

None.

Verifiability:

See Table 6-2, Binary Numeric Operations.

3.2 add.ovf.<signed> Add Integer Values with Overflow Check

Format

Assembly Format

Description

D6

add.ovf

Add signed integer values with overflow check.

D7

add.ovf.un

Add unsigned integer values with overflow check.

Stack Transition:

…, value1, value2 …, result

Description:

The add.ovf instruction adds value1 and value2 and pushes the result onto the stack. The acceptable operand types and their corresponding result data type are encapsulated in Table 6-7, Overflow Arithmetic Operations.

Exceptions:

OverflowException is thrown if the result cannot be represented in the result type.

Verifiability:

See Table 6-7, Overflow Arithmetic Operations.

3.3 and Bitwise AND

Format

Instruction

Description

5F

and

Bitwise AND of two integral values; returns an integral value.

Stack Transition:

…, value1, value2 …, result

Description:

The and instruction computes the bitwise AND of value1 and value2 and pushes the result onto the stack. The acceptable operand types and their corresponding result data type are encapsulated in Table 6-5, Integer Operations.

Exceptions:

None.

Verifiability:

See Table 6-5, Integer Operations.

3.4 arglist Get Argument List

Format

Assembly Format

Description

FE 00

arglist

Return argument list handle for the current method.

Stack Transition:

…, argListHandle

Description:

The arglist instruction returns an opaque handle (an unmanaged pointer, type native int) representing the argument list of the current method. This handle is valid only during the lifetime of the current method. The handle can, however, be passed to other methods as long as the current method is on the thread of control. The arglist instruction may only be executed within a method that takes a variable number of arguments.

RATIONALE

This instruction is needed to implement the C "va_*" macros used to implement procedures like "printf". It is intended for use with the class library implementation of System.ArgIterator.


Exceptions:

None.

Verifiability:

It is incorrect CIL generation to emit this instruction except in the body of a method whose signature indicates that it accepts a variable number of arguments. Within such a method its use is verifiable, but verification requires that the result is an instance of the System.RuntimeArgumentHandle class.

3.5 beq.<length> Branch on Equal

Format

Assembly Format

Description

3B <int32>

beq target

Branch to target if equal.

2E <int8>

beq.s target

Branch to target if equal, short form.

Stack Transition:

…, value1, value2

Description:

The beq instruction transfers control to target if value1 is equal to value2. The effect is identical to performing a ceq instruction followed by a brtrue target. target is represented as a signed offset (4 bytes for beq, 1 byte for beq.s) from the beginning of the instruction following the current instruction.

The acceptable operand types are encapsulated in Table 6-4, Binary Comparison or Branch Operations.

If the target instruction has one or more prefix codes, control can only be transferred to the first of these prefixes.

Control transfers into and out of try, catch, filter, and finally blocks cannot be performed by this instruction. (Such transfers are severely restricted and must use the leave instruction instead; see Partition I [sections 12.4.2.5 through 12.4.2.8] for details).

Exceptions:

None.

Verifiability:

Correct CIL must observe all of the control transfer rules specified above and must guarantee that the top two items on the stack correspond to the types shown in Table 6-4, Binary Comparison or Branch Operations.

In addition, verifiable code requires the type-consistency of the stack, locals, and arguments for every possible path to the destination instruction. See Partition III, section 1.5 for more details.

3.6 bge.<length> Branch on Greater Than or Equal To

Format

Assembly Format

Description

3C <int32>

bge target

Branch to target if greater than or equal to.

2F <int8>

bge.s target

Branch to target if greater than or equal to, short form.

Stack Transition:

…, value1, value2

Description:

The bge instruction transfers control to target if value1 is greater than or equal to value2. The effect is identical to performing a clt.un instruction followed by a brfalse target. target is represented as a signed offset (4 bytes for bge, 1 byte for bge.s) from the beginning of the instruction following the current instruction.

The effect of a "bge target" instruction is identical to:

  • If stack operands are integers, then: clt followed by a brfalse target.

  • If stack operands are floating point, then : clt.un followed by a brfalse target.

The acceptable operand types are encapsulated in Table 6-4, Binary Comparison or Branch Operations.

If the target instruction has one or more prefix codes, control can only be transferred to the first of these prefixes.

Control transfers into and out of try, catch, filter, and finally blocks cannot be performed by this instruction. (Such transfers are severely restricted and must use the leave instruction instead; see Partition I [sections 12.4.2.5 through 12.4.2.8] for details).

Exceptions:

None.

Verifiability:

Correct CIL must observe all of the control transfer rules specified above and must guarantee that the top two items on the stack correspond to the types shown in Table 6-4, Binary Comparison or Branch Operations.

In addition, verifiable code requires the type-consistency of the stack, locals, and arguments for every possible path to the destination instruction. See Partition III, section 1.5 for more details.

3.7 bge.un.<length> Branch on Greater Than or Equal To, Unsigned or Unordered

Format

Assembly Format

Description

41 <int32>

bge.un target

Branch to target if greater than or equal to (unsigned or unordered).

34 <int8>

bge.un.s target

Branch to target if greater than or equal to (unsigned or unordered), short form.

Stack Transition:

…, value1, value2

Description:

The bge.un instruction transfers control to target if value1 is greater than or equal to value2, when compared unsigned (for integer values) or unordered (for floating point values). The effect is identical to performing a clt instruction followed by a brfalse target. target is represented as a signed offset (4 bytes for bge.un, 1 byte for bge.un.s) from the beginning of the instruction following the current instruction.

The acceptable operand types are encapsulated in Table 6-4, Binary Comparison or Branch Operations.

If the target instruction has one or more prefix codes, control can only be transferred to the first of these prefixes.

Control transfers into and out of try, catch, filter, and finally blocks cannot be performed by this instruction. (Such transfers are severely restricted and must use the leave instruction instead; see Partition I [sections 12.4.2.5 through 12.4.2.8] for details).

Exceptions:

None.

Verifiability:

Correct CIL must observe all of the control transfer rules specified above and must guarantee that the top two items on the stack correspond to the types shown in Table 6-4, Binary Comparison or Branch Operations.

In addition, verifiable code requires the type-consistency of the stack, locals, and arguments for every possible path to the destination instruction. See Partition III, section 1.5 for more details.

3.8 bgt.<length> Branch on Greater Than

Format

Assembly Format

Description

3D <int32>

bgt target

Branch to target if greater than.

30 <int8>

bgt.s target

Branch to target if greater than, short form.

Stack Transition:

…, value1, value2

Description:

The bgt instruction transfers control to target if value1 is greater than value2. The effect is identical to performing a cgt instruction followed by a brtrue target. target is represented as a signed offset (4 bytes for bgt, 1 byte for bgt.s) from the beginning of the instruction following the current instruction.

The acceptable operand types are encapsulated in Table 6-4, Binary Comparison or Branch Operations.

If the target instruction has one or more prefix codes, control can only be transferred to the first of these prefixes.

Control transfers into and out of try, catch, filter, and finally blocks cannot be performed by this instruction. (Such transfers are severely restricted and must use the leave instruction instead; see Partition I [sections 12.4.2.5 through 12.4.2.8] for details.)

Exceptions:

None.

Verifiability:

Correct CIL must observe all of the control transfer rules specified above and must guarantee that the top two items on the stack correspond to the types shown in Table 6-4, Binary Comparison or Branch Operations.

In addition, verifiable code requires the type-consistency of the stack, locals, and arguments for every possible path to the destination instruction. See Partition III, section 1.5 for more details.

3.9 bgt.un.<length> Branch on Greater Than, Unsigned or Unordered

Format

Assembly Format

Description

42 <int32>

bgt.un target

Branch to target if greater than (unsigned or unordered).

35 <int8>

bgt.un.s target

Branch to target if greater than (unsigned or unordered), short form.

Stack Transition:

…, value1, value2

Description:

The bgt.un instruction transfers control to target if value1 is greater than value2, when compared unsigned (for integer values) or unordered (for floating point values). The effect is identical to performing a cgt.un instruction followed by a brtrue target. target is represented as a signed offset (4 bytes for bgt.un, 1 byte for bgt.un.s) from the beginning of the instruction following the current instruction.

The acceptable operand types are encapsulated in Table 6-4, Binary Comparison or Branch Operations.

If the target instruction has one or more prefix codes, control can only be transferred to the first of these prefixes.

Control transfers into and out of try, catch, filter, and finally blocks cannot be performed by this instruction. (Such transfers are severely restricted and must use the leave instruction instead; see Partition I [sections 12.4.2.5 through 12.4.2.8] for details.)

Exceptions:

None.

Verifiability:

Correct CIL must observe all of the control transfer rules specified above and must guarantee that the top two items on the stack correspond to the types shown in Table 6-4, Binary Comparison or Branch Operations.

In addition, verifiable code requires the type-consistency of the stack, locals, and arguments for every possible path to the destination instruction. See Partition III, section 1.5 for more details.

3.10 ble.<length> Branch on Less Than or Equal To

Format

Assembly Format

Description

3E <int32>

ble target

Branch to target if less than or equal to.

31 <int8>

ble.s target

Branch to target if less than or equal to, short form.

Stack Transition:

…, value1, value2

Description:

The ble instruction transfers control to target if value1 is less than or equal to value2. target is represented as a signed offset (4 bytes for ble, 1 byte for ble.s) from the beginning of the instruction following the current instruction.

The effect of a "ble target" instruction is identical to:

  • If stack operands are integers, then: cgt followed by a brfalse target.

  • If stack operands are floating point, then: cgt.un followed by a brfalse target.

The acceptable operand types are encapsulated in Table 6-4, Binary Comparison or Branch Operations.

If the target instruction has one or more prefix codes, control can only be transferred to the first of these prefixes.

Control transfers into and out of try, catch, filter, and finally blocks cannot be performed by this instruction. (Such transfers are severely restricted and must use the leave instruction instead; see Partition I [sections 12.4.2.5 through 12.4.2.8] for details.)

Exceptions:

None.

Verifiability:

Correct CIL must observe all of the control transfer rules specified above and must guarantee that the top two items on the stack correspond to the types shown in Table 6-4, Binary Comparison or Branch Operations.

In addition, verifiable code requires the type-consistency of the stack, locals, and arguments for every possible path to the destination instruction. See Partition III, section 1.5 for more details.

3.11 ble.un.<length> Branch on Less Than or Equal To, Unsigned or Unordered

Format

Assembly Format

Description

43 <int32>

ble.un target

Branch to target if less than or equal to (unsigned or unordered).

36 <int8>

ble.un.s target

Branch to target if less than or equal to (unsigned or unordered), short form.

Stack Transition:

…, value1, value2

Description:

The ble.un instruction transfers control to target if value1 is less than or equal to value2, when compared unsigned (for integer values) or unordered (for floating point values). target is represented as a signed offset (4 bytes for ble.un, 1 byte for ble.un.s) from the beginning of the instruction following the current instruction.

The effect of a "ble.un target" instruction is identical to:

  • If stack operands are integers, then: cgt.un followed by a brfalse target.

  • If stack operands are floating point, then: cgt followed by a brfalse target.

The acceptable operand types are encapsulated in Table 6-4, Binary Comparison or Branch Operations.

If the target instruction has one or more prefix codes, control can only be transferred to the first of these prefixes.

Control transfers into and out of try, catch, filter, and finally blocks cannot be performed by this instruction. (Such transfers are severely restricted and must use the leave instruction instead; see Partition I [sections 12.4.2.5 through 12.4.2.8] for details.)

Exceptions:

None.

Verifiability:

Correct CIL must observe all of the control transfer rules specified above and must guarantee that the top two items on the stack correspond to the types shown in Table 6-4, Binary Comparison or Branch Operations.

In addition, verifiable code requires the type-consistency of the stack, locals, and arguments for every possible path to the destination instruction. See Partition III, section 1.5 for more details.

3.12 blt.<length> Branch on Less Than

Format

Assembly Format

Description

3F <int32>

blt target

Branch to target if less than.

32 <int8>

blt.s target

Branch to target if less than, short form.

Stack Transition:

…, value1, value2

Description:

The blt instruction transfers control to target if value1 is less than value2. The effect is identical to performing a clt instruction followed by a brtrue target. target is represented as a signed offset (4 bytes for blt, 1 byte for blt.s) from the beginning of the instruction following the current instruction.

The acceptable operand types are encapsulated in Table 6-4, Binary Comparison or Branch Operations.

If the target instruction has one or more prefix codes, control can only be transferred to the first of these prefixes.

Control transfers into and out of try, catch, filter, and finally blocks cannot be performed by this instruction. (Such transfers are severely restricted and must use the leave instruction instead; see Partition I [sections 12.4.2.5 through 12.4.2.8] for details.)

Exceptions:

None.

Verifiability:

Correct CIL must observe all of the control transfer rules specified above and must guarantee that the top two items on the stack correspond to the types shown in Table 6-4, Binary Comparison or Branch Operations.

In addition, verifiable code requires the type-consistency of the stack, locals, and arguments for every possible path to the destination instruction. See Partition III, section 1.5 for more details.

3.13 blt.un.<length> Branch on Less Than, Unsigned or Unordered

Format

Assembly Format

Description

44 <int32>

blt.un target

Branch to target if less than (unsigned or unordered) .

37 <int8>

blt.un.s target

Branch to target if less than (unsigned or unordered), short form.

Stack Transition:

…, value1, value2

Description:

The blt.un instruction transfers control to target if value1 is less than value2, when compared unsigned (for integer values) or unordered (for floating point values). The effect is identical to performing a clt.un instruction followed by a brtrue target. target is represented as a signed offset (4 bytes for blt.un, 1 byte for blt.un.s) from the beginning of the instruction following the current instruction.

The acceptable operand types are encapsulated in Table 6-4, Binary Comparison or Branch Operations.

If the target instruction has one or more prefix codes, control can only be transferred to the first of these prefixes.

Control transfers into and out of try, catch, filter, and finally blocks cannot be performed by this instruction. (Such transfers are severely restricted and must use the leave instruction instead; see Partition I [sections 12.4.2.5 through 12.4.2.8] for details.)

Exceptions:

None.

Verifiability:

Correct CIL must observe all of the control transfer rules specified above and must guarantee that the top two items on the stack correspond to the types shown in Table 6-4, Binary Comparison or Branch Operations.

In addition, verifiable code requires the type-consistency of the stack, locals, and arguments for every possible path to the destination instruction. See Partition III, section 1.5 for more details.

3.14 bne.un<length> Branch on Not Equal or Unordered

Format

Assembly Format

Description

40 <int32>

bne.un target

Branch to target if unequal or unordered.

33 <int8>

bne.un.s target

Branch to target if unequal or unordered, short form.

Stack Transition:

…, value1, value2

Description:

The bne.un instruction transfers control to target if value1 is not equal to value2, when compared unsigned (for integer values) or unordered (for floating point values). The effect is identical to performing a ceq instruction followed by a brfalse target. target is represented as a signed offset (4 bytes for bne.un, 1 byte for bne.un.s) from the beginning of the instruction following the current instruction.

The acceptable operand types are encapsulated in Table 6-4, Binary Comparison or Branch Operations.

If the target instruction has one or more prefix codes, control can only be transferred to the first of these prefixes.

Control transfers into and out of try, catch, filter, and finally blocks cannot be performed by this instruction. (Such transfers are severely restricted and must use the leave instruction instead; see Partition I [sections 12.4.2.5 through 12.4.2.8] for details.)

Exceptions:

None.

Verifiability:

Correct CIL must observe all of the control transfer rules specified above and must guarantee that the top two items on the stack correspond to the types shown in Table 6-4, Binary Comparison or Branch Operations.

In addition, verifiable code requires the type-consistency of the stack, locals, and arguments for every possible path to the destination instruction. See Partition III, section 1.5 for more details.

3.15 br.<length> Unconditional Branch

Format

Assembly Format

Description

38 <int32>

br target

Branch to target

2B <int8>

br.s target

Branch to target, short form.

Stack Transition:

…,

Description:

The br instruction unconditionally transfers control to target. target is represented as a signed offset (4 bytes for br, 1 byte for br.s) from the beginning of the instruction following the current instruction.

If the target instruction has one or more prefix codes, control can only be transferred to the first of these prefixes.

Control transfers into and out of try, catch, filter, and finally blocks cannot be performed by this instruction. (Such transfers are severely restricted and must use the leave instruction instead; see Partition I [sections 12.4.2.5 through 12.4.2.8] for details.)

RATIONALE

While a leave instruction can be used instead of a br instruction when the evaluation stack is empty, doing so may increase the resources required to compile from CIL to native code and/or lead to inferior native code. Therefore CIL generators should use a br instruction in preference to a leave instruction when both are legal.


Exceptions:

None.

Verifiability:

Correct CIL must observe all of the control transfer rules specified above.

In addition, verifiable code requires the type-consistency of the stack, locals, and arguments for every possible path to the destination instruction. See Partition III, section 1.5 for more details.

3.16 break Breakpoint Instruction

Format

Assembly Format

Description

01

break

Inform a debugger that a breakpoint has been reached.

Stack Transition:

…,

Description:

The break instruction is for debugging support. It signals the CLI to inform the debugger that a breakpoint has been tripped. It has no other effect on the interpreter state.

The break instruction has the smallest possible instruction size so that code can be patched with a breakpoint with minimal disturbance to the surrounding code.

The break instruction may trap to a debugger, do nothing, or raise a security exception: the exact behavior is implementation-defined.

ANNOTATION

Typically, in an externally written PE file, the break instruction would not be present in the CIL instructions. It is intended for use by debuggers in the in-memory representation of CLI methods.


Exceptions:

None.

Verifiability:

The break instruction is always verifiable.

3.17 brfalse.<length> Branch on False, Null, or Zero

Format

Assembly Format

Description

39 <int32>

brfalse target

Branch to target if value is zero (false).

2C <int8>

brfalse.s target

Branch to target if value is zero (false), short form.

39 <int32>

brnull target

Branch to target if value is null (alias for brfalse).

2C <int8>

brnull.s target

Branch to target if value is null (alias for brfalse.s), short form.

39 <int32>

brzero target

Branch to target if value is zero (alias for brfalse).

2C <int8>

brzero.s target

Branch to target if value is zero (alias for brfalse.s), short form.

Stack Transition:

…, value

Description:

The brfalse instruction transfers control to target if value (of type int32, int64, object reference, managed pointer, unmanaged pointer, or native int) is zero (false). If value is non-zero (true), execution continues at the next instruction.

target is represented as a signed offset (4 bytes for brfalse, 1 byte for brfalse.s) from the beginning of the instruction following the current instruction.

If the target instruction has one or more prefix codes, control can only be transferred to the first of these prefixes.

Control transfers into and out of try, catch, filter, and finally blocks cannot be performed by this instruction. (Such transfers are severely restricted and must use the leave instruction instead; see Partition I [sections 12.4.2.5 through 12.4.2.8] for details.)

Exceptions:

None.

Verifiability:

Correct CIL must observe all of the control transfer rules specified above and must guarantee that there is a minimum of one item on the stack.

In addition, verifiable code requires the type-consistency of the stack, locals, and arguments for every possible path to the destination instruction. See Partition III, section 1.5 for more details.

3.18 brtrue.<length> Branch on Non-false or Non-null

Format

Assembly Format

Description

3A <int32>

brtrue target

Branch to target if value is non-zero (true).

2D <int8>

brtrue.s target

Branch to target if value is non-zero (true), short form.

3A <int32>

brinst target

Branch to target if value is a non-null object reference (alias for brtrue).

2D <int8>

brinst.s target

Branch to target if value is a non-null object reference, short form (alias for brtrue.s).

Stack Transition:

…, value

Description:

The brtrue instruction transfers control to target if value (of type native int) is non-zero (true). If value is zero (false), execution continues at the next instruction.

If the value is an object reference (type O), then brinst (an alias for brtrue) transfers control if it represents an instance of an object (i.e., isn't the null object reference; see ldnull [Partition III, section 3.45]).

target is represented as a signed offset (4 bytes for brtrue, 1 byte for brtrue.s) from the beginning of the instruction following the current instruction.

If the target instruction has one or more prefix codes, control can only be transferred to the first of these prefixes.

Control transfers into and out of try, catch, filter, and finally blocks cannot be performed by this instruction. (Such transfers are severely restricted and must use the leave instruction instead; see Partition I [sections 12.4.2.5 through 12.4.2.8] for details.)

Exceptions:

None.

Verifiability:

Correct CIL must observe all of the control transfer rules specified above and must guarantee that there is a minimum of one item on the stack.

In addition, verifiable code requires the type-consistency of the stack, locals, and arguments for every possible path to the destination instruction. See Partition III, section 1.5 for more details.

3.19 call Call a Method

Format

Assembly Format

Description

28 <T>

call method

Call method described by method.

Stack Transition:

…, arg1, arg2 … argn …, retVal (not always returned)

Description:

The call instruction calls the method indicated by the descriptor method. method is a metadata token (either a methodref or methoddef; see Partition II) that indicates the method to call and the number, type, and order of the arguments that have been placed on the stack to be passed to that method, as well as the calling convention to be used. See Partition I [section 12.4 and its subsections] for a detailed description of the CIL calling sequence. The call instruction may be immediately preceded by a tail. prefix to specify that the current method state should be released before transferring control (see Partition III, section 2.1).

The metadata token carries sufficient information to determine whether the call is to a static method, an instance method, a virtual method, or a global function. In all of these cases the destination address is determined entirely from the metadata token. (Contrast with the callvirt instruction for calling virtual methods, where the destination address also depends upon the runtime type of the instance reference pushed before the callvirt; see below).

If the method does not exist in the class specified by the metadata token, the base classes are searched to find the most derived class which defines the method, and that method is called.

RATIONALE

This implements "call superclass" behavior.


The arguments are placed on the stack in left-to-right order. That is, the first argument is computed and placed on the stack, then the second argument, etc. There are three important special cases:

  1. Calls to an instance (or virtual; see the following paragraph) method must push that instance reference (the this pointer) before any of the user-visible arguments. The signature carried in the metadata does not contain an entry in the parameter list for the this pointer but uses a bit (called HASTHIS) to indicate whether the method requires passing the this pointer (see Partition II, sections 22.2.1 and 22.2.2).

    ANNOTATION

    For calls to methods on value types, the this pointer is a managed pointer, not an instance reference.


  2. It is legal to call a virtual method using call (rather than callvirt); this indicates that the method is to be resolved using the class specified by method rather than as specified dynamically from the object being invoked. This is used, for example, to compile calls to "methods on super" (i.e., the statically known parent class).

  3. Note that a delegate's Invoke method may be called with either the call or callvirt instruction.

Exceptions:

SecurityException may be thrown if system security does not grant the caller access to the called method. The security check may occur when the CIL is converted to native code rather than at runtime.

Verifiability:

Correct CIL ensures that the stack contains the correct number and type of arguments for the method being called.

For a typical use of the call instruction, verification checks that (a) method refers to a valid methodref or methoddef token; (b) the types of the objects on the stack are consistent with the types expected by the method call, and (c) the method is accessible from the call site, and (d) the method is not abstract (i.e., it has an implementation).

The call instruction may also be used to call an object's superclass constructor, or to initialize a value type location by calling an appropriate constructor, both of which are treated as special cases by verification. A call annotated by tail. is also a special case.

If the target method is global (defined outside of any type), then the method must be static.

3.20 calli Indirect Method Call

Format

Assembly Format

Description

29 <T>

calli callsitedescr

Call method indicated on the stack with arguments described by callsitedescr.

Stack Transition:

…, arg1, arg2 … argn, ftn …, retVal (not always returned)

Description:

The calli instruction calls ftn (a pointer to a method entry point) with the arguments arg1 … argn. The types of these arguments are described by the signature callsitedescr. See Partition I [section 12.4 and its subsections] for a description of the CIL calling sequence. The calli instruction may be immediately preceded by a tail. prefix to specify that the current method state should be released before transferring control. If the call would transfer control to a method of higher trust than the origin method, the stack frame would not be released; instead, the execution would continue silently as if the tail. prefix had not been supplied.

(A callee of "higher trust" is defined as one whose permission grant-set is a strict superset of the grant-set of the caller.)

The ftn argument is assumed to be a pointer to native code (of the target machine) that can be legitimately called with the arguments described by callsitedescr (a metadata token for a stand-alone signature). Such a pointer can be created using the ldftn or ldvirtftn instruction, or have been passed in from native code.

The stand-alone signature specifies the number and type of parameters being passed, as well as the calling convention (see Partition II [section 14.3]). The calling convention is not checked dynamically, so code that uses a calli instruction will not work correctly if the destination does not actually use the specified calling convention.

The arguments are placed on the stack in left-to-right order. That is, the first argument is computed and placed on the stack, then the second argument, etc. The argument-building code sequence for an instance or virtual method must push that instance reference (the this pointer, which must not be null) before any of the user-visible arguments.

ANNOTATION

For calls to methods on value types, the this pointer is a managed pointer, not an instance reference.


Exceptions:

SecurityException may be thrown if the system security does not grant the caller access to the called method. The security check may occur when the CIL is converted to native code rather than at runtime.

Verifiability:

Correct CIL requires that the function pointer contains the address of a method whose signature matches that specified by callsitedescr and that the arguments correctly correspond to the types of the destination function's parameters.

Verification checks that ftn is a pointer to a function generated by ldftn or ldvirtfn.

ANNOTATION

Implementation-Specific (Microsoft): In the first release of Microsoft's implementation of the CLI, the calli instruction is never verifiable.


3.21 ceq Compare Equal

Format

Assembly Format

Description

FE 01

ceq

Push 1 (of type int32) if value1 equals value2, else 0.

Stack Transition:

…, value1, value2 …, result

Description:

The ceq instruction compares value1 and value2. If value1 is equal to value2, then 1 (of type int32) is pushed onto the stack. Otherwise 0 (of type int32) is pushed onto the stack.

For floating point numbers, ceq will return 0 if the numbers are unordered (either or both are NaN). The infinite values are equal to themselves.

The acceptable operand types are encapsulated in Table 6-4, Binary Comparison or Branch Operations.

Exceptions:

None.

Verifiability:

Correct CIL provides two values on the stack whose types match those specified in Table 6-4, Binary Comparison or Branch Operations. There are no additional verification requirements.

3.22 cgt Compare Greater Than

Format

Assembly Format

Description

FE 02

cgt

Push 1 (of type int32) if value1 > value2, else 0.

Stack Transition:

…, value1, value2 …, result

Description:

The cgt instruction compares value1 and value2. If value1 is strictly greater than value2, then 1 (of type int32) is pushed onto the stack. Otherwise 0 (of type int32) is pushed onto the stack.

For floating point numbers, cgt returns 0 if the numbers are unordered (that is, if one or both of the arguments are NaN).

As per IEC 60559:1989, infinite values are ordered with respect to normal numbers (e.g., +infinity > 5.0 > infinity).

The acceptable operand types are encapsulated in Table 6-4, Binary Comparison or Branch Operations.

Exceptions:

None.

Verifiability:

Correct CIL provides two values on the stack whose types match those specified in Table 6-4, Binary Comparison or Branch Operations. There are no additional verification requirements.

3.23 cgt.un Compare Greater Than, Unsigned or Unordered

Format

Assembly Format

Description

FE 03

cgt.un

Push 1 (of type int32) if value1 > value2, unsigned or unordered, else 0.

Stack Transition:

…, value1, value2 …, result

Description:

The cgt.un instruction compares value1 and value2. A value of 1 (of type int32) is pushed onto the stack if

  • For floating point numbers, either value1 is strictly greater than value2, or value1 is not ordered with respect to value2.

  • For integer values, value1 is strictly greater than value2 when considered as unsigned numbers.

Otherwise 0 (of type int32) is pushed onto the stack.

As per IEC 60559:1989, infinite values are ordered with respect to normal numbers (e.g., +infinity > 5.0 > infinity).

The acceptable operand types are encapsulated in Table 6-4, Binary Comparison or Branch Operations.

Exceptions:

None.

Verifiability:

Correct CIL provides two values on the stack whose types match those specified in Table 6-4, Binary Comparison or Branch Operations. There are no additional verification requirements.

3.24 ckfinite Check for a Finite Real Number

Format

Assembly Format

Description

C3

ckfinite

Throw ArithmeticException if value is not a finite number.

Stack Transition:

…, value …, value

Description:

The ckfinite instruction throws ArithmeticException if value (a floating point number) is either a "not a number" value (NaN) or a +/ infinity value. ckfinite leaves the value on the stack if no exception is thrown. Execution is unspecified if value is not a floating point number.

Exceptions:

ArithmeticException is thrown if value is not a "normal" number.

Verifiability:

Correct CIL guarantees that value is a floating point number. There are no additional verification requirements.

3.25 clt Compare Less Than

Format

Assembly Format

Description

FE 04

clt

Push 1 (of type int32) if value1 < value2, else 0.

Stack Transition:

…, value1, value2 …, result

Description:

The clt instruction compares value1 and value2. If value1 is strictly less than value2, then 1 (of type int32) is pushed onto the stack. Otherwise 0 (of type int32) is pushed onto the stack.

For floating point numbers, clt will return 0 if the numbers are unordered (that is, one or both of the arguments are NaN).

As per IEC 60559:1989, infinite values are ordered with respect to normal numbers (e.g., +infinity > 5.0 > infinity).

The acceptable operand types are encapsulated in Table 6-4, Binary Comparison or Branch Operations.

Exceptions:

None.

Verifiability:

Correct CIL provides two values on the stack whose types match those specified in Table 6-4, Binary Comparison or Branch Operations. There are no additional verification requirements.

3.26 clt.un Compare Less Than, Unsigned or Unordered

Format

Assembly Format

Description

FE 05

clt.un

Push 1 (of type int32) if value1 < value2, unsigned or unordered, else 0.

Stack Transition:

…, value1, value2 …, result

Description:

The clt.un instruction compares value1 and value2. A value of 1 (of type int32) is pushed onto the stack if

  • For floating point numbers, either value1 is strictly less than value2, or value1 is not ordered with respect to value2.

  • For integer values, value1 is strictly less than value2 when considered as unsigned numbers.

Otherwise 0 (of type int32) is pushed onto the stack.

As per IEC 60559:1989, infinite values are ordered with respect to normal numbers (e.g., +infinity > 5.0 > infinity).

The acceptable operand types are encapsulated in Table 6-4, Binary Comparison or Branch Operations.

Exceptions:

None.

Verifiability:

Correct CIL provides two values on the stack whose types match those specified in Table 6-4, Binary Comparison or Branch Operations. There are no additional verification requirements.

3.27 conv.<to type> Data Conversion

Format

Assembly Format

Description

67

conv.i1

Convert to int8, pushing int32 onto stack.

68

conv.i2

Convert to int16, pushing int32 onto stack.

69

conv.i4

Convert to int32, pushing int32 onto stack.

6A

conv.i8

Convert to int64, pushing int64 onto stack.

6B

conv.r4

Convert to float32, pushing F onto stack.

6C

conv.r8

Convert to float64, pushing F onto stack.

D2

conv.u1

Convert to unsigned int8, pushing int32 onto stack.

D1

conv.u2

Convert to unsigned int16, pushing int32 onto stack.

6D

conv.u4

Convert to unsigned int32, pushing int32 onto stack.

6E

conv.u8

Convert to unsigned int64, pushing int64 onto stack.

D3

conv.i

Convert to native int, pushing native int onto stack.

E0

conv.u

Convert to native unsigned int, pushing native int onto stack.

76

conv.r.un

Convert unsigned integer to floating point, pushing F onto stack.

Stack Transition:

…, value …, result

Description:

Convert the value on top of the stack to the type specified in the opcode, and leave that converted value on the top of the stack. Note that integer values of less than 4 bytes are extended to int32 (not native int) when they are loaded onto the evaluation stack, and floating point values are converted to the F type.

Conversion from floating point numbers to integral values truncates the number toward zero. When converting from a float64 to a float32, precision may be lost. If value is too large to fit in a float32, the IEC 60559:1989 positive infinity (if value is positive) or IEC 60559:1989 negative infinity (if value is negative) is returned. If overflow occurs converting one integer type to another, the high-order bits are silently truncated. If the result is smaller than an int32, then the value is sign-extended to fill the slot.

If overflow occurs converting a floating point type to an integer, the value returned is unspecified. The conv.r.un operation takes an integer off the stack, interprets it as unsigned, and replaces it with a floating point number to represent the integer; either a float32, if this is wide enough to represent the integer without loss of precision, else a float64.

No exceptions are ever thrown. See conv.ovf [Partition III, section 3.28] for instructions that will throw an exception when the result type cannot properly represent the result value.

The acceptable operand types and their corresponding result data type are encapsulated in Table 6-8, Conversion Operations.

Exceptions:

None.

Verifiability:

Correct CIL has at least one value, of a type specified in Table 6-8, Conversion Operations, on the stack. The same table specifies a restricted set of types that are acceptable in verified code.

3.28 conv.ovf.<to type> Data Conversion with Overflow Detection

Format

Assembly Format

Description

B3

conv.ovf.i1

Convert to an int8 (on the stack as int32) and throw an exception on overflow.

B5

conv.ovf.i2

Convert to an int16 (on the stack as int32) and throw an exception on overflow.

B7

conv.ovf.i4

Convert to an int32 (on the stack as int32) and throw an exception on overflow.

B9

conv.ovf.i8

Convert to an int64 (on the stack as int64) and throw an exception on overflow.

B4

conv.ovf.u1

Convert to a unsigned int8 (on the stack as int32) and throw an exception on overflow.

B6

conv.ovf.u2

Convert to a unsigned int16 (on the stack as int32) and throw an exception on overflow.

B8

conv.ovf.u4

Convert to a unsigned int32 (on the stack as int32) and throw an exception on overflow.

BA

conv.ovf.u8

Convert to a unsigned int64 (on the stack as int64) and throw an exception on overflow.

D4

conv.ovf.i

Convert to an native int (on the stack as native int) and throw an exception on overflow.

D5

conv.ovf.u

Convert to a native unsigned int (on the stack as native int) and throw an exception on overflow.

Stack Transition:

…, value …, result

Description:

Convert the value on top of the stack to the type specified in the opcode, and leave that converted value on the top of the stack. If the value is too large or too small to be represented by the target type, an exception is thrown.

Conversions from floating point numbers to integral values truncate the number toward zero. Note that integer values of less than 4 bytes are extended to int32 (not native int) on the evaluation stack.

The acceptable operand types and their corresponding result data type are encapsulated in Table 6-8, Conversion Operations.

Exceptions:

OverflowException is thrown if the result cannot be represented in the result type.

Verifiability:

Correct CIL has at least one value, of a type specified in Table 6-8, Conversion Operations, on the stack. The same table specifies a restricted set of types that are acceptable in verified code.

3.29 conv.ovf.<to type>.un Unsigned Data Conversion with Overflow Detection

Format

Assembly Format

Description

82

conv.ovf.i1.un

Convert unsigned to an int8 (on the stack as int32) and throw an exception on overflow.

83

conv.ovf.i2.un

Convert unsigned to an int16 (on the stack as int32) and throw an exception on overflow.

84

conv.ovf.i4.un

Convert unsigned to an int32 (on the stack as int32) and throw an exception on overflow.

85

conv.ovf.i8.un

Convert unsigned to an int64 (on the stack as int64) and throw an exception on overflow.

86

conv.ovf.u1.un

Convert unsigned to an unsigned int8 (on the stack as int32) and throw an exception on overflow.

87

conv.ovf.u2.un

Convert unsigned to an unsigned int16 (on the stack as int32) and throw an exception on overflow.

88

conv.ovf.u4.un

Convert unsigned to an unsigned int32 (on the stack as int32) and throw an exception on overflow.

89

conv.ovf.u8.un

Convert unsigned to an unsigned int64 (on the stack as int64) and throw an exception on overflow.

8A

conv.ovf.i.un

Convert unsigned to a native int (on the stack as native int) and throw an exception on overflow.

8B

conv.ovf.u.un

Convert unsigned to a native unsigned int (on the stack as native int) and throw an exception on overflow.

Stack Transition:

…, value …, result

Description:

Convert the value on top of the stack to the type specified in the opcode, and leave that converted value on the top of the stack. If the value cannot be represented, an exception is thrown. The item at the top of the stack is treated as an unsigned value.

Conversions from floating point numbers to integral values truncate the number toward zero. Note that integer values of less than 4 bytes are extended to int32 (not native int) on the evaluation stack.

The acceptable operand types and their corresponding result data type are encapsulated in Table 6-8, Conversion Operations.

Exceptions:

OverflowException is thrown if the result cannot be represented in the result type.

Verifiability:

Correct CIL has at least one value, of a type specified in Table 6-8, Conversion Operations, on the stack. The same table specifies a restricted set of types that are acceptable in verified code.

3.30 cpblk Copy Data from Memory to Memory

Format

Instruction

Description

FE 17

cpblk

Copy data from memory to memory.

Stack Transition:

…, destaddr, srcaddr, size

Description:

The cpblk instruction copies size (of type unsigned int32) bytes from address srcaddr (of type native int, or &) to address destaddr (of type native int, or &). The behavior of cpblk is unspecified if the source and destination areas overlap.

cpblk assumes that both destaddr and srcaddr are aligned to the natural size of the machine (but see the unaligned. prefix instruction). The cpblk instruction may be immediately preceded by the unaligned. prefix instruction to indicate that either the source or the destination is unaligned.

RATIONALE

cpblk is intended for copying structures (rather than arbitrary byte-runs). All such structures, allocated by the CLI, are naturally aligned for the current platform. Therefore, there is no need for the compiler that generates cpblk instructions to be aware of whether the code will eventually execute on a 32-bit or 64-bit platform.


The operation of the cpblk instruction may be altered by an immediately preceding volatile. or unaligned. prefix instruction.

Exceptions:

NullReferenceException may be thrown if an invalid address is detected.

Verifiability:

The cpblk instruction is never verifiable. Correct CIL ensures the conditions specified above.

3.31 div Divide Values

Format

Assembly Format

Description

5B

div

Divide two values to return a quotient or floating point result.

Stack Transition:

…, value1, value2 …, result

Description:

result = value1 div value2 satisfies the following conditions:


|result| = |value1| / |value2|, and
sign(result) = +, if sign(value1) = sign(value2), or
                , if sign(value1) ~= sign(value2)

The div instruction computes result and pushes it onto the stack.

Integer division truncates toward zero.

Floating point division is per IEC 60559:1989. In particular, division of a finite number by 0 produces the correctly signed infinite value and

 
 0 / 0 = NaN infinity / infinity = NaN X / infinity = 0 

The acceptable operand types and their corresponding result data type are encapsulated in Table 6-2, Binary Numeric Operations.

Exceptions:

Integral operations throw ArithmeticException if the result cannot be represented in the result type. This can happen if value1 is the smallest representable integer value, and value2 is 1.

Integral operations throw DivideByZeroException if value2 is zero.

ANNOTATION

Implementation-Specific (Microsoft): On the x86, an OverflowException is thrown when computing (minint div 1).


Floating point operations never throw an exception (they produce NaNs or infinities instead; see Partition I [section 12.1.3]).

Example:

 
 +14 div +3 is 4 +14 div -3 is -4 -14 div +3 is -4 -14 div -3 is 4 

Verifiability:

See Table 6-2, Binary Numeric Operations.

3.32 div.un Divide Integer Values, Unsigned

Format

Assembly Format

Description

5C

div.un

Divide two values, unsigned, returning a quotient.

Stack Transition:

…, value1, value2 …, result

Description:

The div.un instruction computes value1 divided by value2, both taken as unsigned integers, and pushes the result on the stack.

The acceptable operand types and their corresponding result data type are encapsulated in Table 6-5, Integer Operations.

Exceptions:

DivideByZeroException is thrown if value2 is zero.

Example:

 
 +5 div.un +3     is 1 +5 div.un -3     is 0 -5 div.un +3     is 14316557630 or 0x55555553 -5 div.un -3     is 0 

Verifiability:

See Table 6-5, Integer Operations.

3.33 dup Duplicate the Top Value of the Stack

Format

Assembly Format

Description

25

dup

Duplicate value on the top of the stack.

Stack Transition:

…, value …, value, value

Description:

The dup instruction duplicates the top element of the stack.

Exceptions:

None.

Verifiability:

No additional requirements.

3.34 endfilter End filter Clause of SEH

Format

Assembly Format

Description

FE 11

endfilter

End exception handling filter clause.

Stack Transition:

…, value

Description:

Return from filter clause of an exception (see the Exception Handling section of Partition I [section 12.4.2] for a discussion of exceptions). Value (which must be of type int32 and is one of a specific set of values) is returned from the filter clause. It should be one of:

  • exception_continue_search (0) to continue searching for an exception handler.

  • exception_execute_handler (1) to start the second phase of exception handling where finally blocks are run until the handler associated with this filter clause is located. Then the handler is executed.

Other integer values will produce unspecified results.

The entry point of a filter, as shown in the method's exception table, must be the (lexically) first instruction in the filter's code block. The endfilter must be the (lexically) last instruction in the filter's code block (hence there can only be one endfilter for any single filter block). After executing the endfilter instruction, control logically flows back to the CLI exception handling mechanism.

Control cannot be transferred into a filter block except through the exception mechanism. Control cannot be transferred out of a filter block except through the use of a throw instruction or executing the final endfilter instruction. In particular, it is not legal to execute a ret or leave instruction within a filter block. It is not legal to embed a try block within a filter block. If an exception is thrown inside the filter block, it is intercepted and a value of exception_continue_search is returned.

Exceptions:

None.

Verifiability:

Correct CIL guarantees the control transfer restrictions specified above. Also, the stack must contain exactly one item (of type int32).

3.35 endfinally End the finally or fault Clause of an Exception Block

Format

Assembly Format

Description

DC

endfault

End fault clause of an exception block.

DC

endfinally

End finally clause of an exception block.

Stack Transition:

Description:

Return from the finally or fault clause of an exception block; see the Exception Handling section of Partition I [section 12.4.2] for details.

Signals the end of the finally or fault clause so that stack unwinding can continue until the exception handler is invoked. The endfinally or endfault instruction transfers control back to the CLI exception mechanism. This then searches for the next finally clause in the chain if the protected block was exited with a leave instruction. If the protected block was exited with an exception, the CLI will search for the next finally or fault, or enter the exception handler chosen during the first pass of exception handling.

An endfinally instruction may only appear lexically within a finally block. Unlike the endfilter instruction, there is no requirement that the block end with an endfinally instruction, and there can be as many endfinally instructions within the block as required. These same restrictions apply to the endfault instruction and the fault block, mutatis mutandis.

Control cannot be transferred into a finally (or fault block) except through the exception mechanism. Control cannot be transferred out of a finally (or fault) block except through the use of a throw instruction or executing the endfinally (or endfault) instruction. In particular, it is not legal to "fall out" of a finally (or fault) block or to execute a ret or leave instruction within a finally (or fault) block.

Note that the endfault and endfinally instructions are aliases they correspond to the same opcode.

Exceptions:

None.

Verifiability:

Correct CIL guarantees the control transfer restrictions specified above. There are no additional verification requirements.

3.36 initblk Initialize a Block of Memory to a Value

Format

Assembly Format

Description

FE 18

initblk

Set a block of memory to a given byte.

Stack Transition:

…, addr, value, size

Description:

The initblk instruction sets size (of type unsigned int32) bytes starting at addr (of type native int, or &) to value (of type unsigned int8). initblk assumes that addr is aligned to the natural size of the machine (but see the unaligned. prefix instruction [Partition III, section 2.2]).

RATIONALE

initblk is intended for initializing structures (rather than arbitrary byte-runs). All such structures, allocated by the CLI, are naturally aligned for the current platform. Therefore, there is no need for the compiler that generates initblk instructions to be aware of whether the code will eventually execute on a 32-bit or 64-bit platform.


The operation of the initblk instructions may be altered by an immediately preceding volatile. or unaligned. prefix instruction.

Exceptions:

NullReferenceException may be thrown if an invalid address is detected.

Verifiability:

The initblk instruction is never verifiable. Correct CIL code ensures the restrictions specified above.

3.37 jmp Jump to Method

Format

Assembly Format

Description

27 <T>

jmp method

Exit current method and jump to specified method.

Stack Transition:

Description:

Transfer control to the method specified by method, which is a metadata token (either a methodref or methoddef; see Partition II). The current arguments are transferred to the destination method.

The evaluation stack must be empty when this instruction is executed. The calling convention, number, and type of arguments at the destination address must match those of the current method.

The jmp instruction cannot be used to transferred control out of a try, filter, catch, fault, or finally block; or out of a synchronized region. If this is done, results are undefined. See Partition I [sections 12.4.2.5 through 12.4.2.8].

Exceptions:

None.

Verifiability:

The jmp instruction is never verifiable. Correct CIL code obeys the control flow restrictions specified above.

3.38 ldarg.<length> Load Argument onto the Stack

Format

Assembly Format

Description

FE 09 <unsigned int16>

ldarg num

Load argument numbered num onto stack.

0E <unsigned int8>

ldarg.s num

Load argument numbered num onto stack, short form.

02

ldarg.0

Load argument 0 onto stack.

03

ldarg.1

Load argument 1 onto stack.

04

ldarg.2

Load argument 2 onto stack.

05

ldarg.3

Load argument 3 onto stack.

Stack Transition:

…, value

Description:

The ldarg num instruction pushes the num'th incoming argument, where arguments are numbered 0 onward onto the evaluation stack. The ldarg instruction can be used to load a value type or a built-in value onto the stack by copying it from an incoming argument. The type of the value is the same as the type of the argument, as specified by the current method's signature.

The ldarg.0, ldarg.1, ldarg.2, and ldarg.3 instructions are efficient encodings for loading any of the first four arguments. The ldarg.s instruction is an efficient encoding for loading argument numbers 4 through 255.

For procedures that take a variable-length argument list, the ldarg instructions can be used only for the initial fixed arguments, not those in the variable part of the signature. (See the arglist instruction.)

Arguments that hold an integer value smaller than 4 bytes long are expanded to type int32 when they are loaded onto the stack. Floating point values are expanded to their native size (type F).

Exceptions:

None.

Verifiability:

Correct CIL guarantees that num is a valid argument index. See Partition III, section 1.5 for more details on how verification determines the type of the value loaded onto the stack.

3.39 ldarga.<length> Load an Argument Address

Format

Assembly Format

Description

FE 0A <unsigned int16>

ldarga argNum

Fetch the address of argument argNum.

0F <unsigned int8>

ldarga.s argNum

Fetch the address of argument argNum, short form.

Stack Transition:

…, …, address of argument number argNum

Description:

The ldarga instruction fetches the address (of type & i.e., managed pointer) of the argNum'th argument, where arguments are numbered 0 onward. The address will always be aligned to a natural boundary on the target machine (cf. cpblk and initblk [see Partition III, sections 3.30 and 3.36, respectively]). The short form (ldarga.s) should be used for argument numbers 0 through 255.

For procedures that take a variable-length argument list, the ldarga instructions can be used only for the initial fixed arguments, not those in the variable part of the signature.

RATIONALE

ldarga is used for by-ref parameter passing (see Partition I [section 12.4.1.5.2]). In other cases, ldarg and starg should be used.


Exceptions:

None.

Verifiability:

Correct CIL ensures that argNum is a valid argument index. See Partition III, section 1.5 for more details on how verification determines the type of the value loaded onto the stack.

3.40 ldc.<type> Load Numeric Constant

Format

Assembly Format

Description

20 <int32>

ldc.i4 num

Push num of type int32 onto the stack as int32.

21 <int64>

ldc.i8 num

Push num of type int64 onto the stack as int64.

22 <float32>

ldc.r4 num

Push num of type float32 onto the stack as F.

23 <float32>

ldc.r8 num

Push num of type float64 onto the stack as F.

16

ldc.i4.0

Push 0 onto the stack as int32.

17

ldc.i4.1

Push 1 onto the stack as int32.

18

ldc.i4.2

Push 2 onto the stack as int32.

19

ldc.i4.3

Push 3 onto the stack as int32.

1A

ldc.i4.4

Push 4 onto the stack as int32.

1B

ldc.i4.5

Push 5 onto the stack as int32.

1C

ldc.i4.6

Push 6 onto the stack as int32.

1D

ldc.i4.7

Push 7 onto the stack as int32.

1E

ldc.i4.8

Push 8 onto the stack as int32.

15

ldc.i4.m1

Push 1 onto the stack as int32.

15

ldc.i4.M1

Push 1 of type int32 onto the stack as int32 (alias for ldc.i4.m1).

1F <int8>

ldc.i4.s num

Push num onto the stack as int32, short form.

Stack Transition:

…, num

Description:

The ldc num instruction pushes number num onto the stack. There are special short encodings for the integers 128 through 127 (with especially short encodings for 1 through 8). All short encodings push 4-byte integers onto the stack. Longer encodings are used for 8-byte integers and 4- and 8-byte floating point numbers, as well as 4-byte values that do not fit in the short forms.

There are three ways to push an 8-byte integer constant onto the stack:

  1. Use the ldc.i8 instruction for constants that must be expressed in more than 32 bits.

  2. Use the ldc.i4 instruction followed by a conv.i8 for constants that require 9 to 32 bits.

  3. Use a short form instruction followed by a conv.i8 for constants that can be expressed in 8 or fewer bits.

There is no way to express a floating point constant that has a larger range or greater precision than a 64-bit IEC 60559:1989 number, since these representations are not portable across architectures.

Exceptions:

None.

Verifiability:

The ldc instruction is always verifiable.

3.41 ldftn Load Method Pointer

Format

Assembly Format

Description

FE 06 <T>

ldftn method

Push a pointer to a method referenced by method onto the stack.

Stack Transition:

…, ftn

Description:

The ldftn instruction pushes an unmanaged pointer (type native int) to the native code implementing the method described by method (a metadata token, either a methoddef or methodref; see Partition II) onto the stack. The value pushed can be called using the calli instruction if it references a managed method (or a stub that transitions from managed to unmanaged code).

The value returned points to native code using the calling convention specified by method. Thus a method pointer can be passed to unmanaged native code (e.g., as a callback routine). Note that the address computed by this instruction may be to a thunk produced specially for this purpose (for example, to re-enter the CIL interpreter when a native version of the method isn't available).

ANNOTATION

There are many options for implementing this instruction. Conceptually, this instruction places on the virtual machine's evaluation stack a representation of the address of the method specified. In terms of native code this may be an address (as specified), a data structure that contains the address, or any value that can be used to compute the address, depending on the architecture of the underlying machine, the native calling conventions, and the implementation technology of the VES (JIT, interpreter, threaded code, etc.).


Exceptions:

None.

Verifiability:

Correct CIL requires that method is a valid methoddef or methodref token. Verification tracks the type of the value pushed in more detail than the native int type, remembering that it is a method pointer. Such a method pointer can then be used with calli or to construct a delegate.

3.42 ldind.<type> Load Value Indirect onto the Stack

Format

Assembly Format

Description

46

ldind.i1

Indirect load value of type int8 as int32 onto the stack.

48

ldind.i2

Indirect load value of type int16 as int32 onto the stack.

4A

ldind.i4

Indirect load value of type int32 as int32 onto the stack.

4C

ldind.i8

Indirect load value of type int64 as int64 onto the stack.

47

ldind.u1

Indirect load value of type unsigned int8 as int32 onto the stack.

49

ldind.u2

Indirect load value of type unsigned int16 as int32 onto the stack.

4B

ldind.u4

Indirect load value of type unsigned int32 as int32 onto the stack.

4E

ldind.r4

Indirect load value of type float32 as F onto the stack.

4C

ldind.u8

Indirect load value of type unsigned int64 as int64 onto the stack (alias for ldind.i8).

4F

ldind.r8

Indirect load value of type float64 as F onto the stack.

4D

ldind.i

Indirect load value of type native int as native int onto the stack.

50

ldind.ref

Indirect load value of type object ref as O onto the stack.

Stack Transition:

…, addr …, value

Description:

The ldind instruction indirectly loads a value from address addr (an unmanaged pointer, native int, or managed pointer, &) onto the stack. The source value is indicated by the instruction suffix. All of the ldind instructions are shortcuts for a ldobj instruction that specifies the corresponding built-in value class.

Note that integer values of less than 4 bytes are extended to int32 (not native int) when they are loaded onto the evaluation stack. Floating point values are converted to F type when loaded onto the evaluation stack.

Correct CIL ensures that the ldind instructions are used in a manner consistent with the type of the pointer.

The address specified by addr must be aligned to a location with the natural alignment of <type>, or a NullReferenceException may occur (but see the unaligned. prefix instruction [Partition III, section 2.2, and the Memory Model section (Partition I, Section 12.6) for a definition of natural alignment]). The results of all CIL instructions that return addresses (e.g., ldloca and ldarga) are safely aligned. For data types larger than 1 byte, the byte ordering is dependent on the target CPU. Code that depends on byte ordering may not run on all platforms.

The operation of the ldind instructions may be altered by an immediately preceding volatile. or unaligned. prefix instruction.

RATIONALE

Signed and unsigned forms for the small integer types are needed so that the CLI can know whether to sign-extend or zero-extend. The ldind.u8 and ldind.u4 variants are provided for convenience; ldind.u8 is an alias for ldind.i8; ldind.u4 and ldind.i4 have different opcodes, but their effect is identical.


Exceptions:

NullReferenceException may be thrown if an invalid address is detected.

Verifiability:

Correct CIL only uses an ldind instruction in a manner consistent with the type of the pointer.

3.43 ldloc Load Vocal Variable onto the Stack

Format

Assembly Format

Description

FE 0C <unsigned int16>

ldloc indx

Load local variable of index indx onto stack.

11 <unsigned int8>

ldloc.s indx

Load local variable of index indx onto stack, short form.

06

ldloc.0

Load local variable 0 onto stack.

07

ldloc.1

Load local variable 1 onto stack.

08

ldloc.2

Load local variable 2 onto stack.

09

ldloc.3

Load local variable 3 onto stack.

Stack Transition:

…, value

Description:

The ldloc indx instruction pushes the contents of the local variable number indx onto the evaluation stack, where local variables are numbered 0 onward. Local variables are initialized to 0 before entering the method only if the initialize flag on the method is true (see Partition I). The ldloc.0, ldloc.1, ldloc.2, and ldloc.3 instructions provide an efficient encoding for accessing the first four local variables. The ldloc.s instruction provides an efficient encoding for accessing local variables 4 through 255.

ANNOTATION

The "zero init flag" syntax in the assembler syntax is the .local init directive; and in the file format, it is the flag CorILMethod_InitLocals (see Partition II, section 24.4.4).


The type of the value is the same as the type of the local variable, which is specified in the method header. See Partition I [section 12.1.6.1].

Local variables that are smaller than 4 bytes long are expanded to type int32 when they are loaded onto the stack. Floating point values are expanded to their native size (type F).

Exceptions:

VerificationException is thrown if the "zero initialize" bit for this method has not been set, and the assembly containing this method has not been granted SecurityPermission.SkipVerification (and the CIL does not perform automatic definite-assignment analysis).

Verifiability:

Correct CIL ensures that indx is a valid local index. See Partition III, section 1.5 for more details on how verification determines the type of a local variable. For the ldloca indx instruction, indx must lie in the range 0 to 65534 inclusive (specifically, 65535 is not valid).

RATIONALE

The reason for excluding 65535 is pragmatic: likely implementations will use a 2-byte integer to track both a local's index, as well as the total number of locals for a given method. If an index of 65535 had been made legal, it would require a wider integer to track the number of locals in such a method.


Also, for verifiable code, this instruction must guarantee that it is not loading an uninitialized value whether that initialization is done explicitly by having set the "zero initialize" bit for the method, or by previous instructions (where the CLI performs definite-assignment analysis).

3.44 ldloca.<length> Load Local Variable Address

Format

Assembly Format

Description

FE 0D <unsigned int16>

ldloca index

Load address of local variable with index indx.

12 <unsigned int8>

ldloca.s index

Load address of local variable with index indx, short form.

Stack Transition:

…, address

Description:

The ldloca instruction pushes the address of the local variable number index onto the stack, where local variables are numbered 0 onward. The value pushed onto the stack is already aligned correctly for use with instructions like ldind and stind. The result is a managed pointer (type &). The ldloca.s instruction provides an efficient encoding for use with the local variables 0 through 255.

ANNOTATION

Local variables for which ldloca is executed must be aligned as described in Partition III, section 3.42, because the address obtained by ldloca may be used as an argument to ldind.


Exceptions:

VerificationException is thrown if the the "zero initialize" bit for this method has not been set, and the assembly containing this method has not been granted Security Permission.SkipVerification (and the CIL does not perform automatic definite-assignment analysis).

Verifiability:

Correct CIL ensures that indx is a valid local index. See Partition III, section 1.5 for more details on how verification determines the type of a local variable. For the ldloca indx instruction, indx must lie in the range 0 to 65534 inclusive (specifically, 65535 is not valid).

RATIONALE

The reason for excluding 65535 is pragmatic: likely implementations will use a 2-byte integer to track both a local's index, as well as the total number of locals for a given method. If an index of 65535 had been made legal, it would require a wider integer to track the number of locals in such a method.


Also, for verifiable code, this instruction must guarantee that it is not loading an uninitialized value whether that initialization is done explicitly by having set the "zero initialize" bit for the method, or by previous instructions (where the CLI performs definite-assignment analysis).

3.45 ldnull Load a Null Pointer

Format

Assembly Format

Description

14

ldnull

Push null reference onto the stack.

Stack Transition:

…, null value

Description:

The ldnull pushes a null reference (type O) onto the stack. This is used to initialize locations before they become live or when they become dead.

RATIONALE

It might be thought that ldnull is redundant: why not use ldc.i4.0 or ldc.i8.0 instead? The answer is that ldnull provides a size-agnostic null analogous to a ldc.i instruction, which does not exist. However, even if CIL were to include a ldc.i instruction, it would still benefit verification algorithms to retain the ldnull instruction because it makes type tracking easier.


Exceptions:

None.

Verifiability:

The ldnull instruction is always verifiable, and produces a value that verification considers compatible with any other reference type.

3.46 leave.<length> Exit a Protected Region of Code

Format

Assembly Format

Description

DD <int32>

leave target

Exit a protected region of code.

DE <int8>

leave.s target

Exit a protected region of code, short form.

Stack Transition:

…,

Description:

The leave instruction unconditionally transfers control to target. target is represented as a signed offset (4 bytes for leave, 1 byte for leave.s) from the beginning of the instruction following the current instruction.

The leave instruction is similar to the br instruction, but it can be used to exit a try, filter, or catch block, whereas the ordinary branch instructions can only be used in such a block to transfer control within it. The leave instruction empties the evaluation stack and ensures that the appropriate surrounding finally blocks are executed.

It is not legal to use a leave instruction to exit a finally block. To ease code generation for exception handlers, it is legal from within a catch block to use a leave instruction to transfer control to any instruction within the associated try block.

If an instruction has one or more prefix codes, control can only be transferred to the first of these prefixes.

Exceptions:

None.

Verifiability:

Correct CIL requires that the computed destination lie within the current method. See Partition III, section 1.5 for more details.

3.47 localloc Allocate Space in the Local Dynamic Memory Pool

Format

Assembly Format

Description

FE 0F

localloc

Allocate space from the local memory pool.

Stack Transition:

size address

Description:

The localloc instruction allocates size (type native unsigned int) bytes from the local dynamic memory pool and returns the address (a managed pointer, type &) of the first allocated byte. The block of memory returned is initialized to 0 only if the initialize flag on the method is true (see Partition I). The area of memory is newly allocated. When the current method returns, the local memory pool is available for reuse.

ANNOTATION

The standard appears to be in error on the return type. A managed pointer is always a pointer to a specific type. The probable correct return type is an unmanaged pointer, although this is a point that has not been approved at this time through the ECMA committee. In any case, the localloc instruction isn't verifiable, so, from the point of view of the Standard, the precise type doesn't matter too much.


ANNOTATION

The "zero init flag" syntax in the assembler syntax is the .local init directive; and in the file format, it is the flag CorILMethod_InitLocals (see Partition II, section 24.4.4).


address is aligned so that any built-in data type can be stored there using the stind instructions and loaded using the ldind instructions.

The localloc instruction cannot occur within an exception block: filter, catch, finally, or fault.

RATIONALE

localloc is used to create local aggregates whose size must be computed at runtime. It can be used for C's intrinsic alloca method.


Exceptions:

StackOverflowException is thrown if there is insufficient memory to service the request.

Verifiability:

Correct CIL requires that the evaluation stack be empty, apart from the size item. This instruction is never verifiable.

3.48 mul Multiply Values

Format

Assembly Format

Description

5A

mul

Multiply values.

Stack Transition:

…, value1, value2 …, result

Description:

The mul instruction multiplies value1 by value2 and pushes the result onto the stack. Integral operations silently truncate the upper bits on overflow (see mul.ovf [Partition III, section 3.49]).

For floating point types, 0 x infinity = NaN.

The acceptable operand types and their corresponding result data types are encapsulated in Table 6-2, Binary Numeric Operations.

Exceptions:

None.

Verifiability:

See Table 6-2, Binary Numeric Operations.

3.49 mul.ovf.<type> Multiply Integer Values with Overflow Check

Format

Assembly Format

Description

D8

mul.ovf

Multiply signed integer values. Signed result must fit in same size.

D9

mul.ovf.un

Multiply unsigned integer values. Unsigned result must fit in same size.

Stack Transition:

…, value1, value2 …, result

Description:

The mul.ovf instruction multiplies integers, value1 and value2, and pushes the result onto the stack. An exception is thrown if the result will not fit in the result type.

The acceptable operand types and their corresponding result data types are encapsulated in Table 6-7, Overflow Arithmetic Operations.

Exceptions:

OverflowException is thrown if the result cannot be represented in the result type.

Verifiability:

See Table 6-7, Overflow Arithmetic Operations.

3.50 neg Negate

Format

Assembly Format

Description

65

neg

Negate value.

Stack Transition:

…, value …, result

Description:

The neg instruction negates value and pushes the result on top of the stack. The return type is the same as the operand type.

Negation of integral values is standard twos complement negation. In particular, negating the most negative number (which does not have a positive counterpart) yields the most negative number. To detect this overflow, use the sub.ovf instruction instead (i.e., subtract from 0) [see Partition III, section 3.65].

Negating a floating point number cannot overflow; negating NaN returns NaN.

The acceptable operand types and their corresponding result data types are encapsulated in Table 6-3, Unary Numeric Operations.

Exceptions:

None.

Verifiability:

See Table 6-3, Unary Numeric Operations.

3.51 nop No Operation

Format

Assembly Format

Description

00

nop

Do nothing.

Stack Transition:

…, …,

Description:

The nop operation does nothing. It is intended to fill in space if bytecodes are patched.

Exceptions:

None.

Verifiability:

The nop instruction is always verifiable.

3.52 not Bitwise Complement

Format

Assembly Format

Description

66

not

Bitwise complement

Stack Transition:

…, value …, result

Description:

Compute the bitwise complement of the integer value on top of the stack and leave the result on top of the stack. The return type is the same as the operand type.

The acceptable operand types and their corresponding result data type are encapsulated in Table 6-5, Integer Operations.

Exceptions:

None.

Verifiability:

See Table 6-5, Integer Operations.

3.53 or Bitwise OR

Format

Instruction

Description

60

or

Bitwise OR of two integer values, returns an integer.

Stack Transition:

…, value1, value2 …, result

Description:

The or instruction computes the bitwise OR of the top two values on the stack and leaves the result on the stack.

The acceptable operand types and their corresponding result data type are encapsulated in Table 6-5, Integer Operations.

Exceptions:

None.

Verifiability:

See Table 6-5, Integer Operations.

3.54 pop Remove the Top Element of the Stack

Format

Assembly Format

Description

26

pop

Pop a value from the stack.

Stack Transition:

…, value

Description:

The pop instruction removes the top element from the stack.

Exceptions:

None.

Verifiability:

No additional requirements.

3.55 rem Compute Remainder

Format

Assembly Format

Description

5D

rem

Remainder of dividing value1 by value2.

Stack Transition:

…, value1, value2 …, result

Description:

The acceptable operand types and their corresponding result data type are encapsulated in Table 6-2, Binary Numeric Operations.

For Integer Operands:

result = value1 rem value2 satisfies the following conditions:

result = value1 value2x(value1 div value2), and

0 _ |result| < |value2|, and

sign(result) = sign(value1),

where div is the division instruction, which truncates toward zero.

The rem instruction computes result and pushes it onto the stack.

For Floating Point Operands:

rem is defined similarly, except that if value2 is zero or value1 is infinity, the result is NaN. If value2 is infinity, the result is value1 (negated for infinity). This definition is different from the one for floating point remainders in the IEC 60559:1989 Standard. That standard specifies that value1 div value2 is the nearest integer instead of truncating toward zero. System.Math.IEEERemainder (see the .NET Framework Standard Library Annotated Reference) provides the IEC 60559:1989 behavior.

ANNOTATION

Implementation-Specific (Microsoft): In the Microsoft CLI, where value2 is +infinity or infinity, the result is simply value1. In effect, delete the phrase "(negated for infinity)" immediately above. This amendment will be proposed for incorporation into the standard.


Exceptions:

Integral operations throw DivideByZeroException if value2 is zero.

Integral operations may throw ArithmeticException if value1 is the smallest representable integer value and value2 is 1.

ANNOTATION

Implementation-Specific (Microsoft): On the x86, an OverflowException is thrown when computing (System.Int32.MaxValue rem 1).


Example:

 
 +10 rem +6        is 4         (+10 div +6 = 1) +10 rem -6        is 4         (+10 div -6 = -1) -10 rem +6        is -4        (-10 div +6 = -1) -10 rem -6        is -4        (-10 div -6 = 1) 

For the various floating point values of 10.0 and 6.0, rem gives the same values; System.Math.IEEERemainder, however, gives the following values:

 
 System.Math.IEEERemainder(+10.0,+6.0) is  -2(+10.0 div +6.0 =  1.666...7) System.Math.IEEERemainder(+10.0,-6.0) is  -2(+10.0 div -6.0 = -1.666...7) System.Math.IEEERemainder(-10.0,+6.0) is   2(-10.0 div +6.0 = -1.666...7) System.Math.IEEERemainder(-10.0,-6.0) is   2(-10.0 div -6.0 =  1.666...7) 

Verifiability:

See Table 6-2, Binary Numeric Operations.

3.56 rem.un Compute Integer Remainder, Unsigned

Format

Assembly Format

Description

5E

rem.un

Remainder of unsigned dividing value1 by value2

Stack Transition:

…, value1, value2 …, result

Description:

result = value1 rem.un value2 satisfies the following conditions:

result = value1 value2x(value1 div.un value2), and

0 _result < value2,

where div.un is the unsigned division instruction. The rem.un instruction computes result and pushes it onto the stack. Rem.un treats its arguments as unsigned integers, while rem treats them as signed integers. rem.un is unspecified for floating point numbers.

The acceptable operand types and their corresponding result data type are encapsulated in Table 6-5, Integer Operations.

Exceptions:

Integral operations throw DivideByZeroException if value2 is zero.

Example:

 
 +5 rem.un +3 is 2                     (+5 div.un +3 = 1) +5 rem.un -3 is 5                     (+5 div.un -3 =+ 0) -5 rem.un +3 is 2                     ( -5 div.un +3 = 1431655763 or 0x55555553) -5 rem.un -3 is -5 or 0xfffffffb      ( -5 div.un -3 = 0) 

Verifiability:

See Table 6-5, Integer Operations.

3.57 ret Return from Method

Format

Assembly Format

Description

2A

ret

Return from method, possibly returning a value.

Stack Transition:

retVal on callee evaluation stack (not always present)

…, retVal on caller evaluation stack (not always present)

Description:

Return from the current method. The return type, if any, of the current method determines the type of value to be fetched from the top of the stack and copied onto the stack of the method that called the current method. The evaluation stack for the current method must be empty except for the value to be returned.

The ret instruction cannot be used to transfer control out of a try, filter, catch, or finally block. From within a try or catch [block], use the leave instruction with a destination of a ret instruction that is outside all enclosing exception blocks. Because the filter and finally blocks are logically part of exception handling, not the method in which their code is embedded, correctly generated CIL does not perform a method return from within a filter or finally [block]. See Partition I [sections 12.4.2.5 through 12.4.2.8].

Exceptions:

None.

Verifiability:

Correct CIL obeys the control constraints described above. Verification requires that the type of retVal is compatible with the declared return type of the current method.

3.58 shl Shift Integer Left

Format

Assembly Format

Description

62

shl

Shift an integer left (shifting in zeros), return an integer.

Stack Transition:

…, value, shiftAmount …, result

Description:

The shl instruction shifts value (int32, int64, or native int) left by the number of bits specified by shiftAmount. shiftAmount is of type int32, int64, or native int. The return value is unspecified if shiftAmount is greater than or equal to the width of value. See Table 6-6, Shift Operations, for details of which operand types are allowed, and their corresponding result type.

Exceptions:

None.

Verifiability:

See Table 6-6, Shift Operations.

3.59 shr Shift Integer Right

Format

Assembly Format

Description

63

shr

Shift an integer right (shift in sign), return an integer.

Stack Transition:

…, value, shiftAmount …, result

Description:

The shr instruction shifts value (int32, int64, or native int) right by the number of bits specified by shiftAmount. shiftAmount is of type int32, int64, or native int. The return value is unspecified if shiftAmount is greater than or equal to the width of value. shr replicates the high-order bit on each shift, preserving the sign of the original value in the result. See Table 6-6, Shift Operations, for details of which operand types are allowed, and their corresponding result type.

Exceptions:

None.

Verifiability:

See Table 6-6, Shift Operations.

3.60 shr.un Shift Integer Right, Unsigned

Format

Assembly Format

Description

64

shr.un

Shift an integer right (shift in zero), return an integer.

Stack Transition:

…, value, shiftAmount …, result

Description:

The shr.un instruction shifts value (int32, int 64, or native int) right by the number of bits specified by shiftAmount. shiftAmount is of type int32 or native int. The return value is unspecified if shiftAmount is greater than or equal to the width of value. shr.un inserts a zero bit on each shift. See Table 6-6, Shift Operations, for details of which operand types are allowed, and their corresponding result type.

Exceptions:

None.

Verifiability:

See Table 6-6, Shift Operations.

3.61 starg.<length> Store a Value in an Argument Slot

Format

Assembly Format

Description

FE 0B <unsigned int16>

starg num

Store a value to the argument numbered num.

10 <unsigned int8>

starg.s num

Store a value to the argument numbered num, short form.

Stack Transition:

…, value …,

Description:

The starg num instruction pops a value from the stack and places it in argument slot num (see Partition I [sections 12.1.5 and 12.6.2.2]). The type of the value must match the type of the argument, as specified in the current method's signature. The starg.s instruction provides an efficient encoding for use with the first 256 arguments.

For procedures that take a variable[-length] argument list, the starg instructions can be used only for the initial fixed arguments, not those in the variable part of the signature.

Storing into arguments that hold an integer value smaller than 4 bytes long truncates the value as it moves from the stack to the argument. Floating point values are rounded from their native size (type F) to the size associated with the argument.

Exceptions:

None.

Verifiability:

Correct CIL requires that num is a valid argument slot.

Verification also checks that the verification type of value matches the type of the argument, as specified in the current method's signature (verification types are less detailed than CLI types).

3.62 stind.<type> Store Value Indirect from Stack

Format

Assembly Format

Description

52

stind.i1

Store value of type int8 into memory at address.

53

stind.i2

Store value of type int16 into memory at address.

54

stind.i4

Store value of type int32 into memory at address.

55

stind.i8

Store value of type int64 into memory at address.

56

stind.r4

Store value of type float32 into memory at address.

57

stind.r8

Store value of type float64 into memory at address.

DF

stind.i

Store value of type native int into memory at address.

51

stind.ref

Store value of type object ref (type O) into memory at address.

Stack Transition:

…, addr, val

Description:

The stind instruction stores a value val at address addr (an unmanaged pointer, type native int, or managed pointer, type &). The address specified by addr must be aligned to the natural size of val or a NullReferenceException may occur (but see the unaligned. prefix instruction [Partition III, section 2.2]). The results of all CIL instructions that return addresses (e.g., ldloca and ldarga) are safely aligned. For data types larger than 1 byte, the byte ordering is dependent on the target CPU. Code that depends on byte ordering may not run on all platforms.

Typesafe operation requires that the stind instruction be used in a manner consistent with the type of the pointer.

The operation of the stind instruction may be altered by an immediately preceding volatile. or unaligned. prefix instruction.

Exceptions:

NullReferenceException is thrown if addr is not naturally aligned for the argument type implied by the instruction suffix.

Verifiability:

Correct CIL ensures that addr be a pointer whose type is known and is assignment compatible with that of val.

3.63 stloc Pop Value from Stack to Local Variable

Format

Assembly Format

Description

FE 0E <unsigned int16>

stloc indx

Pop value from stack into local variable indx.

13 <unsigned int8>

stloc.s indx

Pop value from stack into local variable indx, short form.

0A

stloc.0

Pop value from stack into local variable 0.

0B

stloc.1

Pop value from stack into local variable 1.

0C

stloc.2

Pop value from stack into local variable 2.

0D

stloc.3

Pop value from stack into local variable 3.

Stack Transition:

…, value

Description:

The stloc indx instruction pops the top value off the evalution stack and moves it into local variable number indx (see Partition I [sections 12.1.5 and 12.6.2.2]), where local variables are numbered 0 onward. The type of value must match the type of the local variable as specified in the current method's locals signature. The stloc.0, stloc.1, stloc.2, and stloc.3 instructions provide an efficient encoding for the first four local variables; the stloc.s instruction provides an efficient encoding for local variables 4 through 255.

Storing into locals that hold an integer value smaller than 4 bytes long truncates the value as it moves from the stack to the local variable. Floating point values are rounded from their native size (type F) to the size associated with the argument.

Exceptions:

None.

Verifiability:

Correct CIL requires that indx is a valid local index. For the stloc indx instruction, indx must lie in the range 0 to 65534 inclusive (specifically, 65535 is not valid).

RATIONALE

The reason for excluding 65535 is pragmatic: likely implementations will use a 2-byte integer to track both a local's index, as well as the total number of locals for a given method. If an index of 65535 had been made legal, it would require a wider integer to track the number of locals in such a method.


Verification also checks that the verification type of value matches the type of the local, as specified in the current method's locals signature.

3.64 sub Subtract Numeric Values

Format

Assembly Format

Description

59

sub

Subtract value2 from value1, returning a new value.

Stack Transition:

…, value1, value2 …, result

Description:

The sub instruction subtracts value2 from value1 and pushes the result onto the stack. Overflow is not detected for the integral operations (see sub.ovf [Partition III, section 3.65]); for floating point operands, sub returns +inf on positive overflow, -inf on negative overflow, and zero on floating point underflow.

The acceptable operand types and their corresponding result data type are encapsulated in Table 6-2, Binary Numeric Operations.

Exceptions:

None.

Verifiability:

See Table 6-2, Binary Numeric Operations.

3.65 sub.ovf.<type> Subtract Integer Values, Checking for Overflow

Format

Assembly Format

Description

DA

sub.ovf

Subtract native int from a native int. Signed result must fit in same size.

DB

sub.ovf.un

Subtract native unsigned int from a native unsigned int. Unsigned result must fit in same size.

Stack Transition:

…, value1, value2 …, result

Description:

The sub.ovf instruction subtracts value2 from value1 and pushes the result onto the stack. The type of the values and the return type are specified by the instruction. An exception is thrown if the result does not fit in the result type.

The acceptable operand types and their corresponding result data type are encapsulated in Table 6-7, Overflow Arithmetic Operations.

Exceptions:

OverflowException is thrown if the result cannot be represented in the result type.

Verifiability:

See Table 6-7, Overflow Arithmetic Operations.

3.66 switch Table Switch on Value

Format

Assembly Format

Description

45 <unsigned int32> <int32>… <int32>

switch ( t1, t2 ... tn )

Jump to one of n values.

Stack Transition:

…, value …,

Description:

The switch instruction implements a jump table. The format of the instruction is an unsigned int32 representing the number of targets n, followed by n int32 values specifying jump targets; these targets are represented as offsets (positive or negative) from the beginning of the instruction following this switch instruction.

The switch instruction pops value off the stack and compares it, as an unsigned integer, to n. If value is less than n, execution is transferred to the value'th target, where targets are numbered from 0 (i.e., a value of 0 takes the first target, a value of 1 takes the second target, etc.). If value is not less than n, execution continues at the next instruction (fall through).

If the target instruction has one or more prefix codes, control can only be transferred to the first of these prefixes.

Control transfers into and out of try, catch, filter, and finally blocks cannot be performed by this instruction. (Such transfers are severely restricted and must use the leave instruction instead; see Partition I [sections 12.4.2.5 through 12.4.2.8] for details.)

Exceptions:

None.

Verifiability:

Correct CIL obeys the control transfer constraints listed above. In addition, verification requires the type-consistency of the stack, locals, and arguments for every possible way of reaching all destination instructions. See Partition III, section 1.5 for more details.

3.67 xor Bitwise XOR

Format

Assembly Format

Description

61

xor

Bitwise XOR of integer values; returns an integer.

Stack Transition:

..., value1, value2 ..., result

Description:

The xor instruction computes the bitwise XOR of value1 and value2 and leaves the result on the stack.

The acceptable operand types and their corresponding result data type are encapsulated in Table 6-5, Integer Operations.

Exceptions:

None.

Verifiability:

See Table 6-5, Integer Operations.



The Common Language Infrastructure Annotated Standard (Microsoft. NET Development Series)
The Common Language Infrastructure Annotated Standard (Microsoft. NET Development Series)
ISBN: N/A
EAN: N/A
Year: 2002
Pages: 121

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