Page 1 of 1

linking a subroutine from assembler in C?

Posted: Fri Apr 24, 2009 3:31 am
by moonlightcheese
how do you build a subroutine in assembly (say... ARM assembly) and call it from within C? i've tried this:

load.s

Code: Select all

ENTRY(load)
    stmfd sp!, {r0, r14}
load.h

Code: Select all

extern void load(short address)
i'm basically trying to employ context switching in a very simply way just for proof of concept... i don't need to switch back and forth, just one switch will do, just to get the concept of interrupt vectors and switching processes. i know the physical address of the code i want to execute so i'd like to send an interrupt and send the address to a subroutine in assembly and change the PC to the address sent as an argument in a C function (linked to the subroutine of course)...

Re: linking a subroutine from assembler in C?

Posted: Fri Apr 24, 2009 4:13 am
by skyking
Yes, and what happened?

Re: linking a subroutine from assembler in C?

Posted: Fri Apr 24, 2009 8:56 am
by moonlightcheese
skyking wrote:Yes, and what happened?
it compiles whether or not i compile in the load.s file in the sources... kind of weird.

i'm more or less asking if this syntax is correct and where to get more information on how to call assembly subroutines from C and get return values... as well as how to use interrupts to switch execution context. i've analyzed some code from a small OS but i'm rather lost...

Re: linking a subroutine from assembler in C?

Posted: Fri Apr 24, 2009 9:03 am
by yemista
I think entry is actually used to tell the linker that this will be the first thing to execute in the final code. What you want to do is in the assembly file

global some_func;

some_func:
ret

and in the c file

extern void some_func();

some_func();

There also might be some differences depending on the tools you are using.

Re: linking a subroutine from assembler in C?

Posted: Fri Apr 24, 2009 10:07 am
by skyking
Normally one would expect a link error if load.s is omitted. Are you sure you've not supplied a symbol called load from another source? The ENTRY macro has to be defined correctly if this is to work, expanded in the case of using gnu assembler it would be:

Code: Select all

    .globl load
load:

Re: linking a subroutine from assembler in C?

Posted: Fri Apr 24, 2009 10:37 am
by moonlightcheese
yemista wrote:I think entry is actually used to tell the linker that this will be the first thing to execute in the final code. What you want to do is in the assembly file

global some_func;

some_func:
ret

and in the c file

extern void some_func();

some_func();

There also might be some differences depending on the tools you are using.
ok cool. i was going off examples so i had no idea what to do. everything works except the 'ret', for which i get a compiler error "bad instruction". do i need to define 'ret' myself?

Re: linking a subroutine from assembler in C?

Posted: Fri Apr 24, 2009 10:56 am
by yemista
Im sorry to ask this, but do you know assembly at all? ret is just a return instruction.

Re: linking a subroutine from assembler in C?

Posted: Fri Apr 24, 2009 11:00 am
by skyking
You have to study the ARM reference manual. If you're trying to make a context switch from irq or supervisor mode you must be aware that the user mode sp (and lr) has to be switched as well.

Re: linking a subroutine from assembler in C?

Posted: Fri Apr 24, 2009 11:12 am
by moonlightcheese
yemista wrote:Im sorry to ask this, but do you know assembly at all? ret is just a return instruction.
yes, i've written assembly for SPARC and some for ARM but i'm just learning. i'm familiar with ret but the compiler gives me a bad instruction error... i was a bit confused. i'm using devKitPro (gcc 4.3 eabi for ARM). not sure why it won't compile...

i've looked at the AAPCS (ARM Architecture Procedure Call Standard) and the ARM reference manual but there's no example for implementation and following theory, knowing as little as i do about concepts such as calling subroutines from C and IRQ handling, it's difficult. i'm trying to bridge the gap in knowledge and gain better understanding.

load.s

Code: Select all

.global load

load:
	mov		r0, #5
	ret
load.h

Code: Select all

extern short load(short address);
if i'm understanding the AAPCS correctly, this code should pass the variable 'address' in r0 when the subroutine is called and will return the value held in r0 when ret is called. it just won't compile with the ret instruction... weird.

edit:
without the use of ret, i've tried just copying lr into pc, tried storing lr onto the stack and loading it into pc at the end of the subroutine. both of these just halt execution...

Re: linking a subroutine from assembler in C?

Posted: Fri Apr 24, 2009 12:26 pm
by yemista
If you are calling a function in assembly, you need some kind of return instuction or of course it will just stop right there. Im not familiar with those languages, so maybe they call it something other than ret. The convention depends on the C compiler, so if you are using gcc, then the argument should be stored on the stack, and whatever you plan to return should be stored in the eax register. Again, this is on the x86, so Im not sure how it should be different, but you have to find out how the compiler passes arguments to the function, where it expects the return value to be, and also what registers you need to make sure to preserve within your assembly function

Re: linking a subroutine from assembler in C?

Posted: Fri Apr 24, 2009 12:30 pm
by skyking
Do you have handlers that will report aborts and undefined instructions? Do you mix thumb and arm instruction sets? In that case you should probably use the bx in order to return to the caller.

Re: linking a subroutine from assembler in C?

Posted: Fri Apr 24, 2009 12:33 pm
by moonlightcheese
got an answer on another forum. rather than using 'ret' i just used 'bx lr' and i could at least call the subroutine with no return value and no arguments. going to try arguments and return values next. thanks for your help guys.

Re: linking a subroutine from assembler in C?

Posted: Fri Apr 24, 2009 12:38 pm
by moonlightcheese
skyking wrote:Do you have handlers that will report aborts and undefined instructions? Do you mix thumb and arm instruction sets? In that case you should probably use the bx in order to return to the caller.
yea, that's the same answer i got here:
http://forum.gbadev.org/viewtopic.php?p=168359#168359

i'm learning. sorry for the kind of retarded questions XD