In the Microsoft implementation of the C # compiler and CLR, value types are stored on the stack when this value is a temporary value, a local variable, or a formal parameter, which is neither a private external variable of the anonymous method, nor an iterator block.
Of course, why store things on the stack if you don't need it? Some local variables of type value never hit the stack; they remain in registries for life.
Other value type values ββare stored in heap value types, entered values ββof type of reference type, etc.
Value types, of course, can be stored neither on the stack, nor in the register, nor in the managed heap; they can be stored in unmanaged memory using some completely different memory manager that does not control the CLR.
(And, of course, note that using "the" in a "stack" is a subtle misconception; there can be many stacks in a process. There shouldn't be just one.)
All of these are implementation details and are subject to change without notice.
In addition, it is obvious that information allocated by the stack allocation declaration is allocated on the stack.
For more information about this section, see my articles:
http://blogs.msdn.com/b/ericlippert/archive/2009/04/27/the-stack-is-an-implementation-detail.aspx
http://blogs.msdn.com/b/ericlippert/archive/2009/05/04/the-stack-is-an-implementation-detail-part-two.aspx
Why does it bother you? Runtime manages all of these details for you, so you don't need to worry about it. Are you just curious, or does this lead to a larger question?