3

I am trying to reuse some assembly code in my C project. Suppose I have a sequence of instructions, and I would like to organize them as a function:

void foo() {
  __asm__ (
   "mov %eax, %ebx"
   "push %eax"
   ...
   );
}

However, one obstacle is that in the compiled assembly code of function foo, besides the inlined assembly code, compiler would also generate some prologue instructions for this function, and the whole assembly program would become something like:

foo:
   push %ebp          <---- routine code generated by compilers
   mov  %ebp, %esp    <---- routine code generated by compilers
   mov %eax, %ebx
   push %eax

Given my usage scenario, such routine code actually breaks the original semantics of the inlined assembly.

So here is my question, is there any way that I can prevent compiler from generating those function prologue and epilogue instructions, and only include the inlined assembly code?

Michael Petch
  • 46,082
  • 8
  • 107
  • 198
lllllllllllll
  • 8,519
  • 9
  • 45
  • 80
  • 4
    No, you can't use inline assembly that way. Just use normal assembly in your C project, that way no extra instructions are generated. – Ross Ridge Jul 25 '17 at 02:01
  • 1
    It is better to create functions in an assembly file, assemble it separately and then link the assembly object to your _C_ file. With that being said it is possible to do what you are asking. There are a [couple of answers](https://stackoverflow.com/q/43310704/3857942) to a related question about writing interrupt handlers this way. You can do this for any _C_ function that you intend to have entirely written in assembly. I **strongly** recommend the separate assembly file though. – Michael Petch Jul 25 '17 at 02:19
  • 2
    @old_timer: It sometimes in useful to have a naked C function written in assembly code (or at least part of the function). I agree, however, this is nothing a beginner (or someone not RTM) should use and definitively nothing for all code to be written that way.. – too honest for this site Jul 25 '17 at 02:55
  • Looks like an XY-problem if you intend to write multiple functions in assembly. – too honest for this site Jul 25 '17 at 03:01

2 Answers2

5

You mention that you use gcc for compiling. In this case you can use -O2 optimization level. This will cause the compiler to do stack optimization and if your inline assembly is simple, it won't insert the prologue and epilogue. Although, this might not be guaranteed in every case because optimizations keep changing. (My gcc with -O2 does it).

Another option is that you can put the entire function (including the foo:) inside an assembly block as

__asm__ (
    "foo:\n"
    "mov ..."
);

With this option you need to know the name mangling specifications if any. You will also have to add .globl foo before the function start if you want the function to be non static.

Lastly you can check the gcc __attribute__ ((naked)) attribute on the function declaration. But as mentioned by MichaelPetch, this is not available for the X86 target.

Ajay Brahmakshatriya
  • 8,993
  • 3
  • 26
  • 49
  • 5
    `__attribute__((naked))` in _GCC_ doesn't apply to x86 targets. Although this question isn't tagged with x86, the code shown is x86. You should get `warning: 'naked' attribute directive ignored` warning on current versions of _GCC_ – Michael Petch Jul 25 '17 at 04:32
  • @MichaelPetch Thanks, I moved the point to the last and added a hint about it's non availability for X86. – Ajay Brahmakshatriya Jul 25 '17 at 04:40
2

The whole point of inline asm code is to interface with the C compiler's scheduler and register allocator in a sane way, by giving you a way to specify how to hook up the assembly code to the compiler's constraint solving machinery. That's why it rarely makes sense to have inline asm code with specific registers in it; you instead want to use constraints to allocate some registers and have the compiler tell you what they are.

If you really want to write stand-alone asm code that communicates with the rest of you program by the system ABI, write that code in a separate .s (or .S) file that you include in your project, rather than trying to use inline asm code.

Chris Dodd
  • 119,907
  • 13
  • 134
  • 226
  • I'm really not sure if that is a good or a bad answer. There are use-cases to have a single function without pre-/postamble. But of course writing a whole assembly project like this as OP seems to intend is a really bad idea. And if you want the ABI, the pre-/postamble are necessary. – too honest for this site Jul 25 '17 at 02:59
  • @Olaf: then write that single function in a single, small, .s file and link it into the result. There's no need put everything in one or even a just a few source files. – Chris Dodd Jul 26 '17 at 14:46
  • You should be aware if the function is only used in a single compilation unit, this will clutter the global namespace unnecessarily and violate the prociple of locality. This approach is very much disputed, i.e. opinionated. There is no single, simple answer to this. Invoking the impression there is a single, commonly accepted solution without more information is dishonourable. (or maybe you did not notice I tried to differentiate between different use-cases. – too honest for this site Jul 26 '17 at 14:53