I have no idea how each system operates, and do not inquire since I
usually do not need to know. However it seems rather easy to make an
educated guess, based on whatever experience I have. There are
many variants that exist. For example a program is often
byte code to be interpreted by a virtual machine. It is all very flexible.
Usually, the program will have its own run time environment, for which
some inital space can be allocated at the
bottom of the stack, or anywhere else, since it will not have to move
while the program executes, and also because it will exist in only one
copy for a run of the program (it is not called recursively). But
bottom of stack is probably simpler. Whether you want to consider that
space as a frame or not is probably not very important. However, it
may be simpler for the compiler/interpreter to maintain a structural
consistency with frames at least for that part which may be visible to or
accessed by the rest of the program, so that access is always done consistently.
This is set up by code inserted by the compiler in the compiled code (or linked to it), and is supposed to respect some
standards of communication with the OS (operating system) it is
intended for, so that data can be passed by the OS to the application,
and returned from the application to the OS.
Such standards are usually OS dependant, and must be conformed to by
the language compiler. The standard may simply imply agreement on the
location were the information to be passed is stored, and possibly
ways of specifying its size, upon call to or return from the program.
The stack of frame policy is needed for recursion, and it is possible only as long as you do not have
functions (called also methods, sub-program, procedure ...) that can
return functions as result. The first important recursive language with that
property was Algol 60, and the stack of frames was invented for the
implementation of Algol 60.
The stack of frame was invented to implement recursion. However it is
useful even for allocating space to non-recursive function, as it is a
convenient, simple, fast and easy way to allocate storage for the
function only for the exact duration of that function execution.
Note that the stack policy no longer work as simply if functions can
have functions as result. Then frames may have to be allocated on a
heap (managed with a garbage collector) or occasionally transfered
from the stack to the heap.
The OS does not create an initial frame, whether on stack or anywhere
else. There must be a separation of responsibility. Some languages (at least older ones) do not even use frames, while others do use frames, but not organized as a stack. The role of the OS
is to allocate some space for the program to run, to place the data
to be passed to the program in some predetermined place in that space,
and then to pass control to the program code (if compiled), or to the
interpreter of the program (if interpreted) with a reference to the
program as additional argument.
The code of the application program will then organize the allocated
space, initialize what has to be, possibly move data passed by the OS
in a more convenient location, etc, and then start with the code that
is specific to the application, what you call main method or main
program, thus creating its frame on the stack. This is usually done by a standard piece of code included by
the compiler with proper parameters.
In the case of interpreted code, the program that is actually called
is the interpreter, and the address of the program to be excuted is
passed to it as additional data. The interpreter will organize the
space, and reserve some for its own needs. Then it will start
interpreting your main method/program, thus creating the stack frame
But, as I said, there are many variants.
Does this answer your question? or did I miss a point?