Joel said:
Thanks a lot, that was very insightful.
mov eax,[esp+4]
or
add eax,[ebp+12]
... are instructions that are using locals and arguments.
In other words, are you saying IL instructions like ldc and ldarg
translate
into the above?
Yes (specifically ldloc and ldarg), but not usually that directly, not
that simply. The IL instructions are source code for another compiler,
the CLR JIT compiler, which will reconstitute a simple expression graph
from the IL and use that with more traditional compiler algorithms to
generate optimized code.
Can you please rephrase the above statement in simpler terms.
This is to do with the x86 CPU architecture. You can get specification
documents from Intel's site which fully describe the hardware and the
instruction set. It's drifting away from .NET, but I'll write some brief
info.
ESP is a 32-bit register whose value is an address in memory. x86 stack
operations like PUSH and POP modify ESP as they store and retrieve
values from the stack. By the stack growing downwards, I mean that ESP
gets smaller every time you push, and gets larger every time you pop. In
picture terms and very simplified, imagine memory, broken into dwords
here (32-bit values), addresses on the left, values on the right (but
I've used small numbers here for simplicity):
118 50
114 42
110 10
10C 90
108 90
(Memory is usually visualized with low addresses at the bottom, high
addresses at the top.)
If ESP had the value 110, that means that 10 is the value on top of the
stack. If the CPU next executed 'POP EAX', it would be equivalent to
saying 'MOV EAX, [ESP]; ADD ESP, 4'. That is, popping from the x86 stack
has increased the value of ESP, and after popping it will have the value
114, and now 42 is on top of the stack. That is, the stack grows
downwards in the picture, and shrinks upwards.
The x86 stack is different from the VES stack though. The two are
similar but different. For example, the VES stack is per-activation
record while the x86 stack helps implement subroutine calling. When the
x86 'CALL' instruction is executed, it pushes the address of the next
instruction after the CALL instruction onto the stack, and similarly a
RET instruction pops the return value into EIP (the instruction pointer
register) and continues where it left off. (There can be more to it than
that, see the Intel docs for more info.) There is no equivalent in the
VES model.
EBP has to do with the x86 calling conventions and setting up a stack
frame. You can find more info about this by (e.g.) Googling "x86 stack
frame", without the quotes it will get lots more info.
-- Barry