@Bean, STACK issues
Bean,
I was trying to use manual banking to access stack variables.
The attached program tries to calculate signed division using
2 FUNC's with local variables.
The declaration of locals is straight forward.
The list output shows
So the addresses of the declared locals are outside the stackbank (which·is at $20).
So I thought, lets use bank @__STACK to gain access to the stackbank.
That works, except that imAccuB_MSB has the same address as imSign,
so when imUDIV16 is called, imSign gets overwritten.
Then I remembered that we need to calculate the true addresses, using
· w = @imLocal
· fsr = w
This selects the stackbank.
However, calling UDIV16, imAccuB_MSB still overwrite imSign.
Now, how can we prevent that from happening while imAccuB_MSB and imSign
have the identical offset to their local top of stack.
regards peter
I was trying to use manual banking to access stack variables.
The attached program tries to calculate signed division using
2 FUNC's with local variables.
FUNC imSDIV16 imLocal var byte (1) imSign var byte @imLocal(0) bank @imLocal 'use #__STACK and the stackbank is accessed, imSign @$2F imSign = __param2 XOR __param4 __wparam12 = abs __wparam12 'make values positive __wparam34 = abs __wparam34 imUDIV16 __param1,__param2,__param3,__param4 bank @imLocal 'use #__STACK and the stackbank is accessed if imSign.7 = 1 then __wparam12 = - __wparam12 __wparam34 = - __wparam34 endif bank __DEFAULT return 'prevents warning ENDFUNC
FUNC imUDIV16 imLocal var byte (4) imAccuA var word @imLocal(0) imAccuB var word @imLocal(2) bank @imLocal 'use #__STACK and the stackbank is accessed, imAccuB_MSB at $2F imAccuB = __wparam34 imAccuA = __wparam12 / imAccuB __wparam34 = __wremainder 'save the remainder __wparam12 = imAccuA bank __DEFAULT return 'prevents warning ENDFUNC
The declaration of locals is straight forward.
The list output shows
198 =0000003B imSDIV16: ;FUNC imSDIV16 199 200 =0000001F imLocal = __STACK-$01 ; imLocal var byte (1) 201 003B 0C01 ADD __STACKPTR,#1 003C 01EF 202 203 =0000001F imSign = imLocal+0 ; imSign var byte @imLocal(0) 204
260 =0000006B imUDIV16: ;FUNC imUDIV16 261 262 =0000001C imLocal = __STACK-$04 ; imLocal var byte (4) 263 006B 0C04 ADD __STACKPTR,#4 006C 01EF 264 265 =0000001C imAccuA = imLocal+0 ; imAccuA var word @imLocal(0) 266 =0000001C imAccuA_LSB = imAccuA 267 =0000001D imAccuA_MSB = imAccuA+1 268 269 =0000001E imAccuB = imLocal+2 ; imAccuB var word @imLocal(2) 270 =0000001E imAccuB_LSB = imAccuB 271 =0000001F imAccuB_MSB = imAccuB+1 272
So the addresses of the declared locals are outside the stackbank (which·is at $20).
So I thought, lets use bank @__STACK to gain access to the stackbank.
That works, except that imAccuB_MSB has the same address as imSign,
so when imUDIV16 is called, imSign gets overwritten.
Then I remembered that we need to calculate the true addresses, using
· w = @imLocal
· fsr = w
This selects the stackbank.
However, calling UDIV16, imAccuB_MSB still overwrite imSign.
Now, how can we prevent that from happening while imAccuB_MSB and imSign
have the identical offset to their local top of stack.
regards peter
Comments
is by declaring skipbytes like this
which skips the amount of bytes already allocated from stack
when entering imUDIV16. In this case the number is 1,
but in general, the number must be equal to the deepest
level at which imUDIV16 is called (it may also be called from
another sub that uses 3 localbytes, in which the skipbytes must be set to 3).
That really is not a workable solution because one has to trace the calls.
Besides that, it makes us run out of locals much quicker.
regards peter
but then accessing the locals takes quite more code,
so that's why I tried to use manual banking, but it looks
impossible to make that happen.
regards peter
and inserted it as asm, removing unnecessary instructions.
It turns out·imAccuB is not required when directly using asm.
This looks the best I can get.
regards peter