Writing a Simple Operating System — from Scratch

(Jeff_L) #1

CHAPTER 5. WRITING, BUILDING, AND LOADING YOUR


KERNEL 44


from left to right, show the file offsets of the instructions, the machine code, and the
equivalent assembly instructions. Although our function does a very simple thing, there
is some addtional code in there that seems to be manipulating the stack’s base and top
registers,ebpandesp. C makes heavy use of the stack for storing variables that are
local to a function (i.e. variables that are no-longer needed when the function returns),
so upon entering a function, the stack’s base pointer (ebp) is increased to the current
top of the stack (mov ebp, esp), effectively creating a local, initially empty stack above
the stack of the function that called our function. This process is often referred to as
the function setting up itsstack frame, in which it will allocate any local variables.
However, if prior to returning from our function we failed to restore the stack frame to
that originally set up by our caller, the calling function would get in a real mess when
trying to access its local variables; so before updating the base pointer for our stack
frame, we must store it, and there is no better place to store it than the top of the stack
(push ebp).
After preparing our stack frame, which, sadly, doesn’t actually get used in our simple
function, we see how the compiler handles the linereturn 0xbaba;: the value0xbabais
stored in the 32-bit registereax, which is where the calling function (if there were one)
would expect to find the returned value, similarly to how we had our own convention of
using certain registers to pass arguments to our earlier assembly routines, for example:
ourprintstringroutine expected to find the address of the string to be printed in the
registerbx.
Finally, before issuingretto return to the caller, the function pops the original stack
base pointer off the stack (pop ebp), so the calling function will be unaware that its own
stack frame was ever changed by the called function. Note that we didn’t actuall change
the top of the stack (esp), since in this case our stack frame was used to store nothing,
so the untouchedespregister did not require restoring.
Now we have a good idea about how C code translates into assembly, so let’s prod
the compiler a little further until we have sufficient understanding to write a simple
kernel in C.
[?]


5.1.2 Local Variables


Now write the code in Figure XXX into a file calledlocalvar.cand compile, link, and
disassemble it as before.


// Declare a local variable.
int my_function () {
int my_var = 0xbaba;
return my_var;
}

Now the compiler generates the assembly code in Figure XXX.
Free download pdf