 |
forums.ps2dev.org Homebrew PS2, PSP & PS3 Development Discussions
|
| View previous topic :: View next topic |
| Author |
Message |
Inline
Joined: 19 Jan 2008 Posts: 3
|
Posted: Sat Jan 19, 2008 8:01 pm Post subject: Inline ASM |
|
|
Hi !
I'm playing with a C program which I want to move some parts to inline ASM.
I'm trying to call C functions from ASM, I've tried something like this :
| Code: |
void doSomeStuff()
{
//.......;
}
void test()
{
void (*pFunction)() = NULL;
pFunction = &doSomeStuff;
asm __volatile__ (
"jal %0 ;\n"
:
:"e"(pFunction)
);
}
|
First of all, why it's not working (it may be really stupid sorry), and how can I make it works ?
In a second time I would like to use arguments and return value.
I found the r31 register for the return value, but how can I manage arguments ?
Thanks in advance.
Last edited by Inline on Sat Jan 19, 2008 8:32 pm; edited 1 time in total |
|
| Back to top |
|
 |
hlide
Joined: 10 Sep 2006 Posts: 750
|
Posted: Sat Jan 19, 2008 8:24 pm Post subject: |
|
|
pFunction is a variable, not an constant immediate.
So it should be something like :
| Code: |
int ra;
asm __volatile__ (
"jalr %1 ;\n"
"move %0, $ra ;\n"
"move $ra,%0 ;\n"
:"=r"(ra)
:"r"(pFunction)
:"v0", "v1", // a call can change them so clobber them!
"a0", "a1", "a2", "a3",
"t0", "t1", "t2", "t3", "t5", "t6", "t7", "t8", "t9",
"memory"
);
|
but i would say : never do this way as it is cumbersome whereas doing "pFunction();" would be more efficient.
NOTE: jal or jalr move on ra register the return address and in C/C++ you must first save ra register before calling a target address |
|
| Back to top |
|
 |
Inline
Joined: 19 Jan 2008 Posts: 3
|
Posted: Sat Jan 19, 2008 11:36 pm Post subject: |
|
|
Thank you for the answer hlide.
I now succeed to call my functions.
Do you have a idea for arguments ?
I looked at the disassembly (compiled with gcc). It seems random registers are used to pass arguments. |
|
| Back to top |
|
 |
hlide
Joined: 10 Sep 2006 Posts: 750
|
Posted: Sun Jan 20, 2008 12:28 am Post subject: |
|
|
use of "branch and link" (that is, call to function) in an assembly line code should really avoided at all cost since you prevent gcc to be aware of it and let gcc generate broken code.
But to answer your question :
- if you function returns a 32-bit word, $v0 contains this return value
- if you function returns a 64-bit word, $v1-$v0 contains this return value (lower value is in $v0)
- if your function accepts one or several arguments, $a0 would be the first, $a1 the next one, up to 8 registers in this order : $a0, $a1, $a2, $a3, $t0, $t1, $t2, $t3
int f(int x, int y) should be called this way :
| Code: |
int ra, res;
asm __volatile__ (
"move $a0,%3" "\n" // unoptimal if %3 == $a0
"move $a1,%4" "\n" // unoptimal if %4 == $a0
"jalr %2" "\n"
"move %0, $ra" "\n"
"move $ra,%0" "\n"
"move %1,$v0" "\n" // unoptimal if %1 == $v0
:"+r"(ra), "=r"(res)
:"r"(pFunction), "r"(x), "r"(y)
:"v0", "v1", // a call can change them so clobber them!
"a0", "a1", "a2", "a3",
"t0", "t1", "t2", "t3", "t5", "t6", "t7", "t8", "t9",
"memory"
);
|
but still this is very unoptimal this way.
instead of asking how to call a C function in inline asm function, why not just output your inline asm function which calls, so we can give you the best way to do so ? |
|
| Back to top |
|
 |
Inline
Joined: 19 Jan 2008 Posts: 3
|
Posted: Sun Jan 20, 2008 10:43 am Post subject: |
|
|
Thank you very much hlide,
It works as I want.(With just moving the "move %0, $ra" up to the "jal")
In fact it's just for learning and fun, a temporary situation, time for me to translate everything to ASM. I want be able to test before moving everything.
Thanks again for your advices. |
|
| Back to top |
|
 |
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|