15.01.2013 Views

Free-ebooks-library - Bahar Ali Khan

Free-ebooks-library - Bahar Ali Khan

Free-ebooks-library - Bahar Ali Khan

SHOW MORE
SHOW LESS

Create successful ePaper yourself

Turn your PDF publications into a flip-book with our unique Google optimized e-Paper software.

static Dictionary _opcodes = new Dictionary();<br />

static Disassembler()<br />

{<br />

Dictionary opcodes = new Dictionary();<br />

foreach (FieldInfo fi in typeof (OpCodes).GetFields<br />

(BindingFlags.Public | BindingFlags.Static))<br />

if (typeof (OpCode).IsAssignableFrom (fi.FieldType))<br />

{<br />

OpCode code = (OpCode) fi.GetValue (null); // Get field's value<br />

if (code.OpCodeType != OpCodeType.Nternal)<br />

_opcodes.Add (code.Value, code);<br />

}<br />

}<br />

We’ve written it in a static constructor so that it executes just once.<br />

Now we can write DisassembleNextInstruction. Each IL instruction consists of a 1or<br />

2-byte opcode, followed by an operand of zero, one, two, four, or eight bytes. (An<br />

exception is inline switch opcodes, which are followed by a variable number of operands).<br />

So, we read the opcode, then the operand, and then write out the result:<br />

void DisassembleNextInstruction()<br />

{<br />

int opStart = _pos;<br />

OpCode code = ReadOpCode();<br />

string operand = ReadOperand (code);<br />

_output.AppendFormat ("IL_{0:X4}: {1,-12} {2}",<br />

opStart, code.Name, operand);<br />

_output.AppendLine();<br />

}<br />

To read an opcode, we advance one byte and see whether we have a valid instruction.<br />

If not, we advance another byte and look for a 2-byte instruction:<br />

OpCode ReadOpCode()<br />

{<br />

byte byteCode = _il [_pos++];<br />

if (_opcodes.ContainsKey (byteCode)) return _opcodes [byteCode];<br />

if (_pos == _il.Length) throw new Exception ("Unexpected end of IL");<br />

short shortCode = (short) (byteCode * 256 + _il [_pos++]);<br />

if (!_opcodes.ContainsKey (shortCode))<br />

throw new Exception ("Cannot find opcode " + shortCode);<br />

return _opcodes [shortCode];<br />

}<br />

To read an operand, we first must establish its length. We can do this based on the<br />

operand type. Because most are four bytes long, we can filter out the exceptions<br />

fairly easily in a conditional clause.<br />

730 | Chapter 18: Reflection and Metadata

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!