#177891 - Bond697 - Sun Apr 21, 2013 1:34 am
Hello,
I've been programming on the DS for awhile and I'm able to call ASM functions in my C and C++ source files no problem, but lately I've been trying to call in the other direction, calling C functions from ASM. Is this possible? I can't seem to figure out exactly how to do it, if so.
#177892 - Dwedit - Sun Apr 21, 2013 3:04 am
Store the return address into lr, and use bx to jump to the C code.
Here's an example:
add lr,pc,#4
ldr r12,=FunctionName
bx r12
@code executes here after the function returns
r0,r1,r2,r3 are the first 4 arguments to the function, r0 is the return value after it finishes. If you want two return values, you can also do that by returning a single int64.
For C++ classes, the "this" pointer is the first argument to the class method.
If you have more than 4 arguments, or if you're passing or returning a struct, check the ARM Procedure Call Standard for more information.
On the NDS9, you can use "BLX FunctionName" instead of the 3 instructions above, but then you lose compatibility with the ARM7TDMI.
_________________
"We are merely sprites that dance at the beck and call of our button pressing overlord."
#177893 - Bond697 - Sun Apr 21, 2013 3:56 am
Dwedit wrote: |
Store the return address into lr, and use bx to jump to the C code.
Here's an example:
add lr,pc,#4
ldr r12,=FunctionName
bx r12
@code executes here after the function returns
r0,r1,r2,r3 are the first 4 arguments to the function, r0 is the return value after it finishes. If you want two return values, you can also do that by returning a single int64.
For C++ classes, the "this" pointer is the first argument to the class method.
If you have more than 4 arguments, or if you're passing or returning a struct, check the ARM Procedure Call Standard for more information.
On the NDS9, you can use "BLX FunctionName" instead of the 3 instructions above, but then you lose compatibility with the ARM7TDMI. |
ok, this is what i'm getting for an error:
c:/users/mat/projects/mydsprojects/16bit_color_bmp/source/Mem_int.s:34: undefined reference to `mat_test_func'
mat_test_func is just a throwaway test thing in my main.c file. i'm using it in another asm function that is just this:
push {r14}
blx mat_test_func
pop {r15}
the file that it's in has other asm functions that i'm using with no issue in my main.c file. am i maybe doing something wrong there and not realizing it?
#177894 - Dwedit - Sun Apr 21, 2013 4:49 am
If it's c++ code, it must be declared as extern "C", otherwise it will have a mangled name.
Function must not be declared as static, otherwise it won't be exported.
Linker must see both object code files, but since it's successfully calling ASM code from C, that doesn't seem to be an issue.
In other assemblers, you need to use things like IMPORT to get it to use an external symbol in an ASM file, but in Gnu Assembler, you don't need to do anything, it will just assume any unrecognized label is external.
Maybe try the three instruction method to see if it needed all 32 bits to store the address?
_________________
"We are merely sprites that dance at the beck and call of our button pressing overlord."
#177895 - Bond697 - Sun Apr 21, 2013 4:53 am
Dwedit wrote: |
If it's c++ code, it must be declared as extern "C", otherwise it will have a mangled name.
Function must not be declared as static, otherwise it won't be exported.
Linker must see both object code files, but since it's successfully calling ASM code from C, that doesn't seem to be an issue.
In other assemblers, you need to use things like IMPORT to get it to use an external symbol in an ASM file, but in Gnu Assembler, you don't need to do anything, it will just assume any unrecognized label is external.
Maybe try the three instruction method to see if it needed all 32 bits to store the address? |
throwing it in a header file with "extern C" took care of it, actually. it was just a junk, throwaway function i was using for testing other things before this, so it never occurred to me that i might need to declare it in a header and not just in the main file where it was used. don't i feel stupid. :)
thanks a lot.