[futurebasic] Re: [FB] robert purves to the rescue I hope

Message: < previous - next > : Reply : Subscribe : Cleanse
Home   : June 2000 : Group Archive : Group : All Groups

From: Robert Purves <robert.purves@...>
Date: Sat, 10 Jun 2000 16:24:33 +1200
>I suspect only Robert Purves can answer this, but everyone can benefit if
>I ask here instead of privately.

>How would I call this and return from it correctly:
>"test"
> 'some random gibberish code to do something
>return

The actual call to "test" is dead simple:
`   bl   test
Returning safely from the journey depends on what you do while you are
away. The demo below shows two methods.

The code for "TestBlr" is short, sweet and correct, but you are limited in
what you can do inside the routine. Many FB^3 statements overwrite the
return address in the link register, with dire results.

The code for "TestReturn" saves a return address on the stack. This gives
scope for more elaborate code within the routine. I hesitate to recommend
the method whole-heartedly, because in PPC you are not supposed to fiddle
with the stack pointer like this. That is to say, RETURN plays
ducks-and-drakes with the stack in a way that does not follow PPC
conventions; it also looks for the address in a strange place. A called
function is supposed to store the return address in the caller's stack
frame at 8(sp), then set up another stack frame. Instead, I wrote a little
prolog to put the address where RETURN would find it, and this does seem to
work in spite of its political incorrectness...

Robert P.

// How to call labelled code routines from PPC assembler
dim gVar1 as long, gVar2 as long
end globals

goto "SkipTestReturn"

"TestBlr"
// Can do FB^3 calculations with globals in here, but
// can't make _any_ runtime calls, or the return
// address will get lost.
gVar1 = 3
gVar2 = 33333 * gVar1
` blr ; back to caller


"TestReturn"
` mfspr   r0,lr ; get return address
` addi    sp,sp,-4 ; adjust the stack pointer
` stw     r0,32(sp) ; save address for later RETURN
// Can do FB^3 calculations with globals in here, including
// calculations that call runtime routines. Surprisingly,
// we can even PRINT stuff.
print "In TestReturn"
gVar1 = sqr(1000)
print "gVar1 = " gVar1
print "Leaving TestReturn"
return

"SkipTestReturn"

window 1
` bl TestBlr
print "After TestBlr, gVar2 = " gVar2
` bl TestReturn
do
until fn button