While the stated goal of this blog is to address issues that affect the day-to-day work of most developers, from time to time I'll publish something for the propeller-heads in the audience. This is one of those times.
The instruction set for a CLI compliant execution engine is described by ECMA's CLI Partition III (CIL Instruction Set). The Compact Framework execution engine implementation supports most, but not all, of these instructions. In general, the decision to support an opcode was based on whether it could be generated by one of the compilers supported by CF (C# and Visual Basic, at this time).
An unsupported instruction or prefix is one that will cause an InvalidProgramException if it is encountered by the execution engine. This is in contrast to an instruction or prefix that is simply ignored by the execution engine. CF 1.x had 7 unsupported instructions and 3 unsupported prefixes. CF 2.0 has 7 unsupported instructions and 2 unsupported prefixes. In addition, CF 2.0 has 1 new instruction and 3 new prefixes.
The unsupported instructions in CF 2.0 fall into four categories:
[Edited to fix table layout]
calli jmp
arglist mkrefany refanyval refanytype
localloc
unaligned. tail.
The calli, arglist, mkrefany, refanyval, and refanytype instructions are used to support features of Managed C++. calli supports the closely coupled native/managed interop done by managed C++. The other four instructions are primarily used in the MC++ varargs implementation. Since CF doesn't support MC++, these instructions were left out.
calli
arglist
mkrefany
refanyval
refanytype
The localloc instruction is used to allocate bytes from the local memory pool. It's use is similar to that of the standard C runtime alloca() function. It wasn't implemented because, while it can be generated by the C# compiler, it isn't widely used and can be easily avoided.
alloca()
The unaligned. and tail. prefixes were omitted because CF doesn't have any customer scenarios that require them.
unaligned.
tail.
The unbox.any instruction and the constrained. and readonly. prefixes were added to support generics. unbox.any extracts the value contained in a boxed type and is the equivalent of an unbox followed by ldobj. readonly. optimizes access to elements of a generic array by avoiding a type check when fetching an array element by guaranteeing that the element has not been modified. constrained. was introduced to allow the callvirt instruction to work in a uniform way with both value types and references types.
unbox.any
constrained.
readonly.
unbox
ldobj
callvirt
The no. prefix indicates that the execution engine need not check for type, range, and/or null exceptions when the next instruction is executed. CF 2.0 ignores this instruction because it is designated as optional in the ECMA specification.
no.
A quick trip through any subject must naturally leave out a lot of information. If you have questions about opcode specifications, the ECMA spec is the place to start. If you want to see how the compiler translates high-level code into IL opcodes, use ILDasm.exe to disassemble your executable. You can find a tutorial here. Most of what I know about IL, I've learned from ILDasm. If you still have questions, feel free to ask.
~Dan
0x00
nop
0x50
ldind.ref
0xA0
stelem.r4
0x01
break
0x51
stind.ref
0xA1
stelem.r8
0x02
ldarg.0
0x52
stind.i1
0xA2
stelem.ref
0x03
ldarg.1
0x53
stind.i2
0xA3
ldelem
0x04
ldarg.2
0x54
stind.i4
0xA4
stelem
0x05
ldarg.3
0x55
stind.i8
0xA5
0x06
ldloc.0
0x56
stind.r4
0xB3
conv.ovf.i1
0x07
ldloc.1
0x57
stind.r8
0xB4
conv.ovf.u1
0x08
ldloc.2
0x58
add
0xB5
conv.ovf.i2
0x09
ldloc.3
0x59
sub
0xB6
conv.ovf.u2
0x0A
stloc.0
0x5A
mul
0xB7
conv.ovf.i4
0x0B
stloc.1
0x5B
div
0xB8
conv.ovf.u4
0x0C
stloc.2
0x5C
div.un
0xB9
conv.ovf.i8
0x0D
stloc.3
0x5D
rem
0xBA
conv.ovf.u8
0x0E
ldarg.s
0x5E
rem.un
0xC2
0x0F
ldarga.s
0x5F
and
0xC3
ckfinite
0x10
starg.s
0x60
or
0xC6
0x11
ldloc.s
0x61
xor
0xD0
ldtoken
0x12
ldloca.s
0x62
shl
0xD1
conv.u2
0x13
stloc.s
0x63
shr
0xD2
conv.u1
0x14
ldnull
0x64
shr.un
0xD3
conv.i
0x15
ldc.i4.m1
0x65
neg
0xD4
conv.ovf.i
0x16
ldc.i4.0
0x66
not
0xD5
conv.ovf.u
0x17
ldc.i4.1
0x67
conv.i1
0xD6
add.ovf
0x18
ldc.i4.2
0x68
conv.i2
0xD7
add.ovf.un
0x19
ldc.i4.3
0x69
conv.i4
0xD8
mul.ovf
0x1A
ldc.i4.4
0x6A
conv.i8
0xD9
mul.ovf.un
0x1B
ldc.i4.5
0x6B
conv.r4
0xDA
sub.ovf
0x1C
ldc.i4.6
0x6C
conv.r8
0xDB
sub.ovf.un
0x1D
ldc.i4.7
0x6D
conv.u4
0xDC
endfinally
0x1E
ldc.i4.8
0x6E
conv.u8
0xDD
leave
0x1F
ldc.i4.s
0x6F
0xDE
leave.s
0x20
ldc.i4
0x70
cpobj
0xDF
stind.i
0x21
ldc.i8
0x71
0xE0
conv.u
0x22
ldc.r4
0x72
ldstr
0xFE 0x00
0x23
ldc.r8
0x73
newobj
0xFE 0x01
ceq
0x25
dup
0x74
castclass
0xFE 0x02
cgt
0x26
pop
0x75
isinst
0xFE 0x03
cgt.un
0x27
jmp
0x76
conv.r.un
0xFE 0x04
clt
0x28
call
0x79
0xFE 0x05
clt.un
0x29
0x7A
throw
0xFE 0x06
ldftn
0x2A
ret
0x7B
ldfld
0xFE 0x07
ldvirtftn
0x2B
br.s
0x7C
ldflda
0xFE 0x09
ldarg
0x2C
brfalse.s
0x7D
stfld
0xFE 0x0A
ldarga
0x2D
brtrue.s
0x7E
ldsfld
0xFE 0x0B
starg
0x2E
beq.s
0x7F
ldsflda
0xFE 0x0C
ldloc
0x2F
bge.s
0x80
stsfld
0xFE 0x0D
ldloca
0x30
bgt.s
0x81
stobj
0xFE 0x0E
stloc
0x31
ble.s
0x82
conv.ovf.i1.un
0xFE 0x0F
0x32
blt.s
0x83
conv.ovf.i2.un
0xFE 0x11
endfilter
0x33
bne.un.s
0x84
conv.ovf.i4.un
0xFE 0x12
0x34
bge.un.s
0x85
conv.ovf.i8.un
0xFE 0x13
volatile.
0x35
bgt.un.s
0x86
conv.ovf.u1.un
0xFE 0x14
0x36
ble.un.s
0x87
conv.ovf.u2.un
0xFE 0x15
initobj
0x37
blt.un.s
0x88
conv.ovf.u4.un
0xFE 0x16
0x38
br
0x89
conv.ovf.u8.un
0xFE 0x17
cpblk
0x39
brfalse
0x8A
conv.ovf.i.un
0xFE 0x18
initblk
0x3A
brtrue
0x8B
conv.ovf.u.un
0xFE 0x19
0x3B
beq
0x8C
box
0xFE 0x1A
rethrow
0x3C
bge
0x8D
newarr
0xFE 0x1C
sizeof
0x3D
bgt
0x8E
ldlen
0xFE 0x1D
0x3E
ble
0x8F
ldelema
0xFE 0x1E
0x3F
blt
0x90
ldelem.i1
0x40
bne.un
0x91
ldelem.u1
0x41
bge.un
0x92
ldelem.i2
0x42
bgt.un
0x93
ldelem.u2
0x43
ble.un
0x94
ldelem.i4
0x44
blt.un
0x95
ldelem.u4
0x45
switch
0x96
ldelem.i8
0x46
ldind.i1
0x97
ldelem.i
0x47
ldind.u1
0x98
ldelem.r4
0x48
ldind.i2
0x99
ldelem.r8
0x49
ldind.u2
0x9A
ldelem.ref
0x4A
ldind.i4
0x9B
stelem.i
0x4B
ldind.u4
0x9C
stelem.i1
0x4C
ldind.i8
0x9D
stelem.i2
0x4D
ldind.i
0x9E
stelem.i4
0x4E
ldind.r4
0x9F
stelem.i8
0x4F
ldind.r8
The instruction set for a CLI compliant execution engine is described by ECMA's CLI Partition III (CIL
Dan Elliott recently posted about the IL OpCodes supported by the .NET Compact Framework . This got me
PingBack from http://blog.deanoc.com/?p=72