External asm file as inline in C

Go To Last Post
9 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I have an external assembly file .s with some .global functions. I call these assembly functions from C, no problem here,

but these assembly functions are fairly small and I would like them to be inline in my C code instead of being called from C.

For example .s

.global ResetBoot

ResetBoot:
    movw r30,r24
    ijmp

then from .c

void ResetBoot(void *addr);

void example(void) {
    ResetBoot((void*)0x7000);
}

I want the assembly from .s to be inline in function example();

Can this be done without using the weird asm directive in C?

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Yes, the asm code can be written in the style

inline asm
{
    //your assembly line code goes in here 
}

in your c code

 

//Ilya

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Suggest you read this page in the user manual...

http://www.nongnu.org/avr-libc/u...

 

However the very specific thing you show here can be achieved with:

typedef void (*fptr_t)(void);

ptr_t reset;

int main(void) {
    reset = (fptr_t) 0x7000;
    reset();
}

That is just plain C - no need for Asm on this occasion. It will become an ICALL not an IJMP but as the boot code almost certainly starts by resetting SP anyway this doesn't matter.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Thank you guys, but you are missing my point.

 

Maybe it was a bit unclear, but all the assembly functions are in an external .s file and called from many different .c files, so I can't put it directly into the .c file where I need it.
the asm directive you both are suggesting are exactly what I wanted to avoid - "Can this be done without using the weird asm directive in C?".

The example code, was just an example of the setup, not an actual problem. Maybe this was a bit unclear too.

 

If you want a C function from another module to be inline there is a trick to put the function as inline static in the header.

I was thinking that it might be a similar trick or directive for the .s file to tell the linker to not call the assembly in .s but to inline it instead. 

 

If there isn't any way of doing this, it's fine, but if I get it confirmed I don't need to spend more time on trying :)

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

So you wanted the compiler to pick the assembled asm function and inline the binary code in the appropriate place while compiling the C part. I don't think that is possible.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

El Tangas wrote:
I don't think that is possible.
+100

 

"inline" means inline. For Asm that means asm(...). As C compilation just involves creating a .s file and then assembling it anyway all asm() really does is say "and at this point insert the following opcodes into the .s you are creating 'verbatim'". That is how you get asm into the middle of C.

 

If you have code in your own separate .S (hope it is .S and not .s) then that is actually a separate "compilation unit". It will be built (with the assembler) to create it's own separate .o file and then linked to fix up any CALLs made to it from the output of other compilation units.

 

I guess what you could do if you want both a callable copy and also inlined is to put the opcodes in a pre-pro macro in a .h file then in C use:

#include "asm-def.h" 

asm(MY_LIST_OF_OPCODES);

and in the .S:

#include "asm-def.h" 

label:
    MY_LIST_OF_OPCODES
    ret

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

When you put it that way, it's kind'a obvious now :)

You are right, the compiler has already wrapped the function calls and the linker just link them.

 

Why would .s be different from .S? Windows see them as the same filename.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

MaxKielland wrote:
Why would .s be different from .S? Windows see them as the same filename.
Two things (both of which maybe only apply in a sensible operating system)

 

1) .s means "already preprocessed" while .S means "proprocess and then assemble". So if you call a file foo.s and pass it to avr-gcc then a real operating system will not pass it to the pre-pro.

 

2) most makefiles have a "clean:" command that is something like "rm -f *.s *.o *.hex" etc. That will erase foo.s but not foo.S

 

Having said all that I think Windows is so stupid that it always converts to .s which I think it is the case that the assembler has to be invoked with "avr-gcc -x assembler-with-preprocessor" or something like that because it converts to .s and avr-gcc would just assume that means no pre-processing otherwise - which ain't good if you are trying to use <avr/io.h> !

 

EDIT: OK so actually the option is "-x assembler-with-cpp" but pretty much the same thing!

 

One day Microsoft will eventually understand the file name thing!

Last Edited: Tue. Mar 14, 2017 - 05:32 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

My recollection is that the Windows file system retains the cases in file names,

but regards upper and lower as equivalent.

You can have a file.S and a fIle.s , but not both in the same directory/folder.

Absent the -x option, what gcc does with file.S depends on what name is used on the command line.

file.S will involve the preprocessor. file.S refers to the same file, but will not involve the preprocessor.

Joy.

International Theophysical Year seems to have been forgotten..
Anyone remember the song Jukebox Band?