gbadev.org forum archive

This is a read-only mirror of the content originally found on forum.gbadev.org (now offline), salvaged from Wayback machine copies. A new forum can be found here.

ASM > Calling and returning from externally linked asm routines

#18835 - gbawiz - Tue Apr 06, 2004 10:47 pm

Hello,
I have recently tried to create a program which uses ASM as well as C source.
It works on its own but when I incorporate it into some of my other programs then it has errors.
Although Im not exactly sure what the problem is, I have a suspicion with regards to the contents of the registers before the functions are called and after they finish.

Should the registers be preserved at the start of the asm routines and then reinstated after the asm?
if so then how do i preserve?
Thanks

#18836 - DekuTree64 - Tue Apr 06, 2004 11:00 pm

r0-r3 are used for arguments, so they're free to do what you want with. r12 is also free, so no need to preserve it. r14 is the link register, so you need to make sure you keep its value somewhere so you can return to where you were called from. Other than that it's free for use. r12 is the stack, so of course it needs to be preserved. You can store it to a pc-relative address if you're really cramped for registers, but beware if your interrupts switch to the user stack for extra space. Generally it's best to keep the stack intact at all times.
r4-r11 need to be preserved, and r15 is the program counter, so of course you can't use it for anything else.
Most of the time you just push any regs you need to preserve onto the stack, which is done with a stmfd instruction in ARM, or a push instruction in THUMB. Then to load them back at the end, use ldmfd or pop for their respective CPU modes.

So something like this:
Code:
.global thing
.align
.arm
thing:
stmfd r13!, {r4-r11, r14}
@do stuff involving all those registers
ldmfd r13!, {r4-r11, r14}
bx r14   @return to caller

_________________
___________
The best optimization is to do nothing at all.
Therefore a fully optimized program doesn't exist.
-Deku

#18918 - Cearn - Thu Apr 08, 2004 9:05 am

DekuTree64 wrote:
r0-r3 are used for arguments, so they're free to do what you want with.

Yeah, but is this true even when the function has less than 4 arguments? Say your function is
Code:
foo(int x, int y)

I know that x and y are put in r0 and r1 by the calling function, but what happens to the contents of r2 and r3; are they still free as well?

#18930 - batblaster - Thu Apr 08, 2004 1:05 pm

Yes are free, you can use but don't forget to save all the others...
_________________
Batblaster / 7 Raven Studios Co. Ltd
------------------------------------------

#18931 - Cearn - Thu Apr 08, 2004 1:08 pm

oki. Thanks for clearing that up.

#19022 - gbawiz - Sat Apr 10, 2004 12:27 pm

Hello all,
I have a question with regards to ISR interrupt routines.
In my app, I am using two timers, each with the ability to call the interrupt routine.
timer 1 deals with the general game timers such as the animation frame rate, counting, etc.. and the other deals with the audio.

The question I have is: what happens when the ISR is currently servcing the interrupt from timer 1 and then timer 2 generates and interrupt?

Is timer2 ignored?
or does the CPU wait till it finishes timer1 servicing then move onto 2
or does the interrupt for timer 1 get interrupted by timer 2 with timer 2 being serviced?

Thanks
GbaWIZ

#19024 - poslundc - Sat Apr 10, 2004 1:05 pm

I am responding to this in a different topic... I don't know why you would put it as a reply to this one.

Dan.

#19029 - gbawiz - Sat Apr 10, 2004 1:31 pm

http://forum.gbadev.org/viewtopic.php?p=19026&highlight=#19026