From David Goodenough
Newsgroups: alt.lang.asm
Subject: Stack-Frame

> Could someone please explain how a Stack Frame works.

The idea behind a stack frame is that it's a place where a subroutine can
store its local variables. For instance, suppose you have a routine like
this:

.data

mycounter       dw      0

.code

myfunction      proc

        ; stuff

        mov     [mycounter],ax

        ; more stuff

        call    otherfunction

        ; yet more stuff

        mov     ax,[mycounter]

        ; last bit of stuff

        ret

myfunction      endp

Now, consider what will happen if otherfunction calls myfunction
recursively. You're going to stomp on the value in mycounter.

So what do you do to fix it? If you could set up so that mycounter was on
the stack, it'd be safe. The reason for this is that since calling
subroutines is all done with the stack, you get a copy of this stuff every
time the routine is invoked.

To make a stack frame, you add a prefix and suffix to your routine:

mycounter       =       -2

myfunction      proc
        push    bp              ; prefix
        mov     bp,sp           ; prefix
        sub     sp,2            ; prefix

        ; stuff

        mov     [bp + mycounter],ax

        ; more stuff

        call    otherfunction

        ; yet more stuff

        mov     ax,[bp + mycounter]

        ; last bit of stuff

        mov     sp,bp           ; suffix
        pop     bp              ; suffix
        ret

myfunction      endp

Having done that, think what will happen. *EACH* time you enter
myfunction, it's going to go through the prefix, and set up bp as shown.
bp is used because any instruction that references bp uses ss: as the
default segment register. This means that [bp + mycounter] will reference
a variable on the stack. The term applied to bp and the variables
addressed through it is a stack frame.

Note that as you add variables to the stack frame, their offsets get to be
larger and larger negative numbers. To figure the offset for your
variables, start a running count at zero. Then for each variable, subtract
it's size from the running count, and that becomes that variables offset.

So the word in my example above was at offset -2, and if I wanted a far
pointer as well, since it has a size of 4, I'd subtract 4 from -2, and
arrive at -6.

Hope this helps, any further questions, just give me a holler.
     dg

