Chapter
1.
Assembly
Language
and
Processors
added
to
the stack, it expands into memory locations with lower addresses.
As
items are removed from the
stack, the stack pointer
is
incremented back toward its base address. Nonetheless, the most recent item on the
stack
is
known
as
the 'top
of
the stack.' Stack
is
still a most descriptive term because you can always put
something else on top of the stack.
In
terms of programming, a subroutine can call a subroutine, and
so
on.
The only limitation to the number of items
that
can
be
added
to
the stack
is
the
amount
of
RAM
available for
the stack.
The
amount
of
RAM
allocated
to
the stack
is
important to the programmer.
As
you write your program, you
must be certain
that
the stack
will
not expand into areas reserved for other data. For most applications, this
means
that
you must assign data
that
requires
RAM
to
the lowest
RAM
addresses available. To be more precise,
you must
count
up
all
instructions
that
add data to the stack. Ultimately, your program should remove from
the stack any data it places on the stack.
Therefore, for any instruction
that
adds to the stack, you can sub-
tract any intervening instruction
that
remove, an item from the stack. The most critical factor
is
the maximum
size
of
the stack. Notice
that
you must
be
sure
to
remove data your program adds to the stack. Otherwise, any
left-over items on the stack may cause the stack to grow into portions of
RAM
you intend for other data.
Stack Operations
Stack operations transfer sixteen bits
of
data between memory and a pair
of
processor registers. The two basic
operations are PUSH, which adds data to the stack, and
POP, which removes data from the stack.
A call instruction pushes the contents
of
the program counter (which contains the address
of
the next instruction)
onto
the stack and then transfers control
to
the desired subroutine
by
placing its address
in
the program counter.
A return instruction pops sixteen bits
off
the stack and places them
in
the program counter. This requires the
programmer
to
keep track
of
what
is
in
the ',tack. For example, if you call a subroutine and the subroutine
pushes data
onto
the stack, the subroutine must remove that data before executing a return instruction. Other-
wise, the return instruction pops data from the stack and places
it
in
the program counter. The results are
unpredictable,
of
course,
but
probably not what you want.
Saving Program Status
It
is
likely
that
a subroutine requires the
use
of
one or more of the working registers. However, it
is
equally
likely
that
the main program has data stored
in
the registers that it needs when control returns to the main
program.
As
general rule, a subroutine should
save
the contents
of
a register before using it and then restore
the contents
of
that register before returning control
to
the main program. The subroutine can do this
by
pushing the contents
of
the registers
onto
tre
stack and then popping the data back into the registers before
executing a return. The
following instruction sequence saves and restores
all
the working registers. Notice
that
the
POP
instructions must
be
in
the opposite order of the
PUSH
instructions if the data
is
to
be restored
to
its
original location.
1-13