I have three years experience working full time with .NET (C# and VB). I have a good working knowledge of MSIL and I can use it as a debugging tool.

I don't have much knowledge of the next step of the compilation process i.e. when the Jitter produces the assembly code (displayed in the dissassebly window). Hans Passant posted an answer to a question here: [What is the difference between native code, machine code and assembly code?](https://stackoverflow.com/questions/3434202/what-is-the-difference-between-native-code-machine-code-and-assembly-code). My more experienced colleague said this is a brilliant answer, but I still don't understand the following code:

```
static void Main(string[] args) {
            Console.WriteLine("Hello world");
00000000 55                push        ebp                           ; save stack frame pointer
00000001 8B EC             mov         ebp,esp                       ; setup current frame
00000003 E8 30 BE 03 6F    call        6F03BE38                      ; Console.Out property getter
00000008 8B C8             mov         ecx,eax                       ; setup "this"
0000000a 8B 15 88 20 BD 02 mov         edx,dword ptr ds:[02BD2088h]  ; arg = "Hello world"
00000010 8B 01             mov         eax,dword ptr [ecx]           ; TextWriter reference
00000012 FF 90 D8 00 00 00 call        dword ptr [eax+000000D8h]     ; TextWriter.WriteLine()
00000018 5D                pop         ebp                           ; restore stack frame pointer
        }
00000019 C3                ret                                       ; done, return

```

Can anyone provide more information on what happens on each line and more particularly why each register is chosen e.g. why is eax chosen instead of edx? Alternatively can anyone recommend a book?