Page **1** of **1**

### Stack preservation

Posted: **Mon Nov 09, 2020 11:35 pm**

by **hsilop**

I dunno about you guys but I like my programs to be "function-like" and not leave junk on the stack, simple return the result in the X register. Here are some routines that accomplish saving and restoring of the stack and the lastX value, while returning whatever value is in the X register. Call STKPUSH at the start of your program and STKPOP just before returning. You need to call STKINIT once to setup the stack pointer. I use memory below register 19 for the stack pointer and the stack.

Hope someone finds it useful.

Code: Select all

```
LBL "STKINIT"
18.00001
STO 19
RTN
LBL "STKPUSH"
RDN
XEQ "PUSH"
RDN
XEQ "PUSH"
RDN
XEQ "PUSH"
RDN
LASTX
XEQ "PUSH"
RDN
RTN
LBL "STKPOP"
XEQ "POP"
STO L
RDN
XEQ "POP"
XEQ "POP"
XEQ "POP"
R^
RTN
LBL "PUSH"
STO IND 19
DSE 19
RTN
LBL "POP"
ISG 19
ENTER ; Never runs this line!
RCL IND 19
RTN
```

### Re: Stack preservation

Posted: **Tue Nov 10, 2020 1:13 am**

by **pcscote**

Thank you for your nice program.

Alternative implementation used in PPC ROM.

Source code:

Code: Select all

```
01 LBL "SM" // Stack to Memory (P.408)
02 XEQ 04
03 XEQ 04
04 XEQ 04
05 XEQ 04
06 LASTX
07 STO IND 06
08 4
09 ST- 06
10 RTN
11 LBL 04
12 STO IND 06
13 RDN
14 1
15 ST+ 06
16 RDN
17 RTN
18 LBL "MS" // Memory to Stack (P.336)
19 4
20 ST+ 06
21 RCL IND 06
22 SIGN
23 DSE 06
24 RCL IND 06
25 DSE 06
26 RCL IND 06
27 DSE 06
28 RCL IND 06
29 DSE 06
30 RCL IND 06
31 END
```

Example: Init register 06 with stack destination register (here we use the base register 10)

Example: Stack is saved to registers 10 to 14 but stack content is lost in the process.

Code: Select all

```
L: LLL -> R14: LLL
T: TTT -> R13: TTT
Z: ZZZ -> R12: ZZZ
Y: YYY -> R11: YYY
X: XXX -> R10: XXX
```

Example: Recall stack from registers 10 to 14

Code: Select all

```
R14: LLL -> L: LLL
R13: TTT -> T: TTT
R12: ZZZ -> Z: ZZZ
R11: YYY -> Y: YYY
R10: XXX -> X: XXX
```

### Re: Stack preservation

Posted: **Tue Nov 10, 2020 2:10 am**

by **hsilop**

Hey - nice use of DSE, I didn't know that if cc is zero it defaults to one. Very useful. I found ISG a cleaner way to increment the stack pointer, even though it always skips the next instruction. Less overhead than 1, ST+ and all that stack rigmarole.

### Re: Stack preservation

Posted: **Wed Nov 11, 2020 11:35 am**

by **dlachieze**

hsilop wrote: ↑Mon Nov 09, 2020 11:35 pm

I dunno about you guys but I like my programs to be "function-like" and not leave junk on the stack, simple return the result in the X register. Here are some routines that accomplish saving and restoring of the stack and the lastX value, while returning whatever value is in the X register.

So to be "function-like" you need to save X, Y, Z and T at the beginning of your programs and restore Y, Z and T at the end while keeping in X the output of the program, and returning the initial value of X in L. No need to save the lastX value at the beginning of the program.

Here is how I would do it, based on your programs:

Code: Select all

```
01 LBL "STKINIT"
02 18
03 STO 19
04 RTN
05 LBL "STKPUSH"
06 XEQ "PUSH" ;Push X
07 XEQ" PUSH" ;Push Y
08 XEQ "PUSH" ;Push Z
09 XEQ" PUSH" ;Push T
10 RTN
11 LBL "STKPOP"
12 SIGN ; Save X in L
13 XEQ "POP" ; Pop T
14 XEQ" POP" ; Pop Z
15 XEQ "POP" ; Pop Y
16 XEQ" POP" ; Pop LastX
17 X<> L ; Restore X and L
18 RTN
19 LBL "PUSH"
20 STO IND 19
21 DSE 19
22 RDN
23 RTN
24 LBL "POP"
25 ISG 19
26 ENTER
27 RCL IND 19
28 END
```

If you don't want to disturb the stack with STKINIT you can do:

Code: Select all

```
01 LBL "STKINIT"
02 STO 19
03 CLx
04 18
05 X<> 19
06 RTN
```

### Re: Stack preservation

Posted: **Mon Nov 23, 2020 6:57 pm**

by **hth313**

My just released Boost module contains MCODE functions to do this.

`PUSHST` pushes the XYZTL stack onto a dynamic stack that is maintained in a buffer in the free memory area. You can then mess up the stack as you like and leave the result in X. Then just do

`POPFLXL` which pops back the stack (YZT), leaves X alone and moves the old X to L.

A companion routine is

`POPDRXL` which works the same, but as if you function took two arguments (in X and Y), dropping the stack.

So your RPN function may be:

Code: Select all

```
PUSHST
do calculation based on X, mess up the stack
leave result in X
POPFLXL
```

Reference:

https://github.com/hth313/boost41/releases/tag/v0B
(see Buffer stack, page 25)