We give labels to the three parameters, but the assignments given to the
labels are absolute addresses which can be combined with indexed, X (X =
TSX) to address the location directly.
The instruction LDA PARAM2,X or LDA $0102,X will get the value for PARAM 2
from the Stack, offset from SP = 2.
65816
We give labels to the three parameters, but the assignments given to the
labels are offsets from SP.
The instruction LDA PARAM2,S or LDA 3,S will get the value for PARAM 2 from
the Stack, offset from SP = 3.
Our reference point is always the value of the Stack Pointer, so we must be careful when making any more changes (such as local variables) to the Stack Layout. For example, adding 32 bytes of local variable storage will add a
new offset to our labels, called "LV".
ADDING LOCAL VARIABLES TO A STACK FRAME
8-Bit 6502 16-Bit 65816
PARAM1 = $0101 PARAM1 = 1
PARAM2 = $0102 PARAM2 = 3
PARAM3 = $0103 PARAM3 = 5
LV = 32 LV = 32
LOCAL00 = 1
LV corresponds to 32 bytes local storage
Stack Data Placement After Pushing Three Parameters to "dummy"
Stack Data Placement After Adding 32 Bytes Local Data Storage
8-Bit 6502
Addr SP Data Addressed As
$01FF $FF PARAM 3 PARAM3+LV,X
or $0103+LV,x
$01FE $FE PARAM 2 PARAM2+LV,X
or $0102+LV,x
$01FD $FD PARAM 1 PARAM1+LV,X
or $0101+LV,x
$01DD- 32 BYTES LOCAL31,X
$01FC LOCAL or $0120,x
STORAGE LOCAL00
or $0101,X
$01DC $DC NEW SP $0100,X
$01DB $DB ... ...
$01DA $DA ... ...
16-Bit 65816
Addr SP Data Addressed As
$01FF $01FF PARAM 3 HI 6+LV,S
(PARAM3+LV+1,S)
$01FE $01FE PARAM 3 LO 5+LV,S
(PARAM3+LV,S)
$01FD $01FD PARAM 2 HI 4+LV,S
(PARAM2+LV+1,S)
$01FC $01FC PARAM 2 LO 3+LV,S
(PARAM2+LV,S)
$01FB $01FB PARAM 1 HI 2+LV,S
(PARAM1+LV+1,S)
$01FA $01FA PARAM 1 LO 1+LV,S
(PARAM1+LV,S)
$01DA- 32 BYTES LOCAL00+31,S
$01F9 LOCAL or 32,S
STORAGE ...
LOCAL00,S
or 1,S
$01D9 $01D9 NEW SP 0,S ($01D9)
$01D8 $01D8 ... ...
$01D7 $01D7 ... ...
As can be seen from the tables, regardless of processor, adding local
variables only changes the offset from SP. So when a 32-byte local
variable chunk is placed on the Stack, it is a simple matter to add +32 to
the offset value when addressing any of the older data you see in the
charts. You, the programmer, must pay attention to which level, or "frame"
you are addressing at all times.
SETTING UP DATA TABLES AND OTHER MEMORY MANAGEMENT
Let's have a first look at our Function Address Table (8/16-bit):
Entry # Offset Entry ID
Offset
$0000 $0000 # of Table entries
$0002 Not used
$0001 $0004 Entry 1 ID#
$0006 Entry 1 Address offset
$0002 $0008 Entry 2 ID#
$000A Entry 2 Address offset
$0003 $000C Entry 3 ID#
$000E Entry 3 Address offset
We'll set up some data for the table.
* = $C000
; LOCATOR CODE GOES HERE
FAT =*
.word 4 ;# of entries (+1) in table
.word 0 ;unused
ENTRY1 =*
.word $1000 ;ID# for first function
.word Func1 ;offset to Func1 Code
ENTRY1 =*
.word $1234 ;ID# for second function
.word Func2 ;offset to Func2 Code
ENTRY1 =*
.word $1500 ;ID# for third function
.word Func3 ;offset to Func3 Code
;-----------------------------------
Func1 =* ;Func1 code goes here
rts
Func2 =* ;Func2 code goes here
rts
Func3 =* ;Func3 code goes here
rts
IN CONCLUSION
First, please accept my apology if today's article seemed long-winded or convoluted. As I wrote this, it became apparent that our subject matter is worthy of many words, split into chapters. How does one fix that on the
spot?
Today introduced the springboard, a section of code used for calling
functions located in tables. We showed the impact of pushing function parameters (and later - local variables) on the Stack, and how to address
stack variables - regardless of where they are. The primary difference in memory between 8-bit and 16-bit is that 16-bit variables need twice as much space. So, by adding 32 bytes of local storage we only gained 16 16-bit variables, as each variable is two bytes in size.
We also started to flesh out our memory needs. The Function Address Table follows right after Locator in memory, so everything is
Unfortunately, subject Stack is a biggie. This article ended up too long,
so let's just pick this up later? Next time we can... build a function library and fill it with exactly one function - a tester named "dummy." Mr. tester will have a recurring role as our guinea pig while we develop smart things. We will construct a basic parameter-passing system which will
execute functions such as "dummy." "dummy" is the perfect vehicle for us to
see how "local" stack variables work, and what a Prologue or Epilogue is.
We'll probably talk a little about other ways all this could be
accomplished.
Next time we will add more to our project. Today was mostly justsetting
things up. We will initialize and make use of our local variables, and we
will show how to destroy the local variables when we're done with them.
The springboard will have some important code added to it, and everything
will hopefully become clearer next time out with Part Three of this primer about the Stack. Good stuff, I promise. So, until our next meeting, take
'er easy, and I'll see you next time right here... at the corner where Art meets Science.
TIP OF THE DAY
Today's Tip is an easy one. I would like for you to check out what a guy
named Shaun Bebbington writes. He can be found at -->
yearofcodes.tumblr.com or on Facebook -->
www.facebook.com/retrocomputermart.
Please send errors, omissions, or suggestions to
bert@winc64.com or on
Lemon64, username satpro, or at www.melon64.com, username satpro.
--- MBSE BBS v1.0.01 (GNU/Linux-i386)
* Origin: Dragon's Lair ---:- bbs.vk3heg.net -:--- (39:901/280)