共通中間言語

以前にJavaVMに使用されているオプコードに関して読んだからマイクロソフトのドットネットに使われているCILに興味がありました。
Like the Java intermediate language (often referred to as byte code), the Comman Language Infrastructure's Common Intermediate Language relies on an evaluation stack within each method. This is used to store inputs and outputs to other methods invoked. I have several questions about CIL:
1. Why must the stack be empty upon a method's return? If I do not exit main with an empty stack, I receive an "invalid program error". This is probably because I declared my main to return void, and ret tries to return whatever is on the stack.
2. in describing a type obtained from an external library, you must note it as either class or value type. Does the assembler need to know this to determine whether the address of the data is from the stack or heap?
3. Each call to an object reference's method pops that object reference from the stack? Is this necessary?
4. How closely does CIL mirror native assembly? It seems much more high level, as there is no need to set up parameters in the stack or registers prior to method calls. Also, method calls can be made without jumping to a label.
5. The difference between "call instance void Object::ctor()" and "newobj instance void Object::ctor()" is what? It seems that the latter places a new reference to an object on the stack, while the former is an instance method call of an object on the stack already (i.e. the child object) and does not place any return value on the stack.
6. Does ret do nothing but jump to an address? It seems it also does something with any data left on the stack, per the return type in the method's signature.
7. Exceptions at runtime do not seem to include line numbers, but I did not specify these in my source. If I had included lines like IL_0007, would the exception information have included a line number?
8. How much logic is required to translate CIL into native code? Is this less difficult than converting C# to the x86 instruction set?