home comics writing pictures archive about

2016-03-29 - In IL: Instructions and the Stack

In IL

So now that we’ve learned where local variables are stored it’s time to learn what we can do with them. In most high level languages you write a series of symbols which indicate what you want to happen with each symbol implying the action they represent. In IL you have a series of instruction and their arguments with the name of each instruction implying the action it will perform. Before we get to instructions though we need to understand stacks.

A Stack is a data structure that can be imagined as a pile of things. You can “push” things onto the top of the pile or “pop” things off of the top of the pile. Depending on the implementation you may also be able to look at things on the top of the pile without removing them. In IL every method has an Evaluation Stack. Most instructions pop things from this stack, push things onto this stack, or both. The stack is used to store temporary values similar to how registers work in some computer processors.

There are a bunch of instructions in IL so I will start by summarizing some of the common ones.

nop (No OPeration)

Used to fill up space for various uses. Such as allowing instructions to be patched in later.

Instruction Description Binary Format
nop Does nothing 0x00

ldc (LoaD Constant)

Pushes a value, determined by the instruction or its argument, onto the stack.

Instruction Description Binary Format
ldc.i4.m1 Loads –1 onto the stack as a 4-byte integer 0x15
ldc.i4.X Loads X onto the stack as a 4-byte integer where X is 0-8 0x16 - 0x1E
ldc.i4.s <num> Loads “short” 1-byte integer <num> onto the stack as a 4-byte integer 0x1F <int8>
ldc.i4 <num> Loads 4-byte integer <num> onto the stack 0x20 <int32>
ldc.i8 <num> Loads 8-byte integer <num> onto the stack 0x21 <int64>
ldc.r4 <num> Loads 4-byte floating-point value <num> onto the stack 0x22 <float32>
ldc.r8 <num> Loads 8-byte floating-point value <num> onto the stack 0x23 <float64>

ldstr (LoaD STRing)

Pushes a reference to a string onto the stack

Instruction Description Binary Format
ldstr <string> Loads a reference to <string> onto the stack 0x72 <T>

<T> represents a metadata token. These are 4-byte values that indicate a location where the actual data is stored in the file containing the code.

ldloc (LoaD LOCal variable)

Push the value of a local variable onto the stack.

Instruction Description Binary Format
ldcloc.X Loads the value of local variable X onto the stack where X is 0-3 0x06 - 0x09
ldcloc.s <index> Loads the value of local variable with “short” index <index> onto the stack 0x11 <uint8>
ldcloc <index> Loads the value of local variable with index <index> onto the stack 0xFE 0x0C <uint16>

conv (CONVersion)

Pops a value off of the stack, converts it to the type based on the specific instruction used and pushes the result onto the stack.

Instruction Description Binary Format
conv.i1 Converts the value on the stack to a 1-byte integer 0x67
conv.i2 Converts the value on the stack to a 2-byte integer 0x68
conv.i4 Converts the value on the stack to a 4-byte integer 0x69
conv.i8 Converts the value on the stack to a 8-byte integer 0x6A
conv.r4 Converts the value on the stack to a 4-byte floating-point value 0x6B
conv.r8 Converts the value on the stack to a 8-byte floating-point value 0x6C
conv.u4 Converts the value on the stack to a 4-byte unsigned integer 0x6D
conv.u8 Converts the value on the stack to a 8-byte unsigned integer 0x6E
conv.u2 Converts the value on the stack to a 2-byte unsigned integer 0xD1
conv.u1 Converts the value on the stack to a 1-byte unsigned integer 0xD2

box

Pops a value-type value off of the stack, boxes it as the specified reference type and pushes the result onto the stack.

Instruction Description Binary Format
box <type> Boxes the value on the stack as the specified <type> 0x8C <T>

stloc (SeT LOCal variable)

Pops a value off of the stack and sets it as the value of a local variable.

Instruction Description Binary Format
stloc.X Sets the value of local variable X with a value from the stack where X is 0-3 0x0A - 0x0D
stloc.s <index> Sets the value of local variable with “short” index <index> with a value from the stack 0x13 <uint8>
stloc <index> Sets the value of local variable with index <index> with a value from the stack 0xFE 0x0E <uint16>

add (ADDition), sub (SUBtraction), mul (MULtiplication), div (DIVision)

Pops two values off of the stack and pushes the result of the specified action onto the stack. How the action is performed and the type returned depends on the types of the values.

Instruction Description Binary Format
add Adds the first value popped off of the stack to the second value popped off of the stack and pushes the result onto the stack 0x58
sub Subtracts the first value popped off of the stack from the second value popped off of the stack and pushes the result onto the stack 0x59
mul Multiplies the second value popped off of the stack by the first value popped off of the stack and pushes the result onto the stack 0x5A
div Divides the second value popped off of the stack by the first value popped off of the stack and pushes the result onto the stack 0x5B

call

Used to call a method based on the argument to the instruction. The method pops its parameters off of the stack, if any, and pushes its return value onto the stack, if it has one.

Instruction Description Binary Format
call <method> Calls the <method> method 0x28 <T>

ret (RETurn)

Returns from a method. Uses the value on the stack as the return value. The stack should be empty except for this value. If the method doesn't return a value then the stack should be completely empty.

Instruction Description Binary Format
ret Returns from a method 0x2A

Next time we will see some of these instructions in action.

Comments: