linking a subroutine from assembler in C?

Programming, for all ages and all languages.
Post Reply
moonlightcheese
Posts: 17
Joined: Tue Jan 20, 2009 7:03 pm

linking a subroutine from assembler in C?

Post 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)...
skyking
Member
Member
Posts: 174
Joined: Sun Jan 06, 2008 8:41 am

Re: linking a subroutine from assembler in C?

Post by skyking »

Yes, and what happened?
moonlightcheese
Posts: 17
Joined: Tue Jan 20, 2009 7:03 pm

Re: linking a subroutine from assembler in C?

Post 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...
User avatar
yemista
Member
Member
Posts: 299
Joined: Fri Dec 26, 2008 12:31 pm
Location: Boston
Contact:

Re: linking a subroutine from assembler in C?

Post 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.
skyking
Member
Member
Posts: 174
Joined: Sun Jan 06, 2008 8:41 am

Re: linking a subroutine from assembler in C?

Post 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:
moonlightcheese
Posts: 17
Joined: Tue Jan 20, 2009 7:03 pm

Re: linking a subroutine from assembler in C?

Post 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?
User avatar
yemista
Member
Member
Posts: 299
Joined: Fri Dec 26, 2008 12:31 pm
Location: Boston
Contact:

Re: linking a subroutine from assembler in C?

Post by yemista »

Im sorry to ask this, but do you know assembly at all? ret is just a return instruction.
skyking
Member
Member
Posts: 174
Joined: Sun Jan 06, 2008 8:41 am

Re: linking a subroutine from assembler in C?

Post 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.
moonlightcheese
Posts: 17
Joined: Tue Jan 20, 2009 7:03 pm

Re: linking a subroutine from assembler in C?

Post 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...
User avatar
yemista
Member
Member
Posts: 299
Joined: Fri Dec 26, 2008 12:31 pm
Location: Boston
Contact:

Re: linking a subroutine from assembler in C?

Post 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
skyking
Member
Member
Posts: 174
Joined: Sun Jan 06, 2008 8:41 am

Re: linking a subroutine from assembler in C?

Post 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.
moonlightcheese
Posts: 17
Joined: Tue Jan 20, 2009 7:03 pm

Re: linking a subroutine from assembler in C?

Post 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.
moonlightcheese
Posts: 17
Joined: Tue Jan 20, 2009 7:03 pm

Re: linking a subroutine from assembler in C?

Post 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
Post Reply