0

I can't find the way to mix preprocessor and inline assembly, and I can't find any solution on Google.

Imagine you have this constant:

(Dummy code to simplify)

#define SOME_ASM \
    .short 0x0000; \
    .short 0x0000; \
    movw %eax, %ebx; \

In an assembly file, I could do:

SOME_ASM
or      %cx, %cx
jnz     1f
or      %dx, %dx
jnz     1f
mov     %ax, %cx
mov     %bx, %dx

And it worked. But now I'm doing a new and improved version of the ASM code, and I'm doing it in C

How can I do something like this in C without modifying the constant:

asm(
  SOME_ASM
  "or       %cx, %cx\n"
  "jnz      1f\n"
  "or       %dx, %dx\n"
  "jnz      1f\n"
  "mov      %ax, %cx\n"
  "mov      %bx, %dx\n"
);

To avoid replicating code and constants

markmb
  • 852
  • 4
  • 12
  • 32
  • 3
    The asm block is just a string, so use a string macro. Also reconsider if you really need inline asm. – Jester Nov 15 '15 at 20:21
  • Yes, I really need inline asm. And using #define _stringify(S) #S #define stringify(S) _stringify(S), gives: "error: macro "_stringify" passed 2 arguments, but takes just 1" – markmb Nov 15 '15 at 20:28
  • Did you try what you're showing? Did it work, or was there a problem? Just `#define` your `SOME_ASM` to be exactly the strings you want substituted for `SOME_ASM`. – lurker Nov 15 '15 at 20:30
  • But I want to use the same constant for inline assembly and pure assembly, not change the constant. And that doesn't work (but I could understand there's no other way) – markmb Nov 15 '15 at 20:33

1 Answers1

3

The asm block is just a string, so use a string macro. Also reconsider if you really need inline asm.

#define SOME_ASM \
    ".short 0x0000;" \
    ".short 0x0000;" \
    "movw %ax, %bx;"

void foo()
{
asm(
  SOME_ASM
  "or       %cx, %cx\n"
  "jnz      1f\n"
  "or       %dx, %dx\n"
  "jnz      1f\n"
  "mov      %ax, %cx\n"
  "1:\n"
  "mov      %bx, %dx\n"
);
}
Jester
  • 56,577
  • 4
  • 81
  • 125
  • That implies changing the constant. I want to avoid that if possible so the old assembly code continues working. But maybe there's no other option. – markmb Nov 15 '15 at 20:34
  • 1
    This was **your** example. If you want something else, maybe ask that? – Jester Nov 15 '15 at 20:35
  • Ok, maybe my question is not clear enough. I want to know if it's possible to leave the constant as-is and use it in inline asm. And thanks for your answer. – markmb Nov 15 '15 at 20:41
  • So your constant already includes asm code? Sounds like a bad idea. But if it's really just a constant, that could be made to work. It can also work if the macro is a single line only. – Jester Nov 15 '15 at 20:46
  • The constant is like the one I show in the example, pure asm. And is legacy code, and I should leave the old version (all in asm) working next to the new version (C + inline asm), and I don't want to duplicate the constants and helpers. – markmb Nov 15 '15 at 20:50
  • Should probably have \n at the end of each line of assembly in the macro. – user253751 Nov 15 '15 at 21:21
  • So you need to make a function that executes at compile time that takes stringifies SOME_ASM and then adds linefeeds after the semicolone? The first is easy enough but editing the string at compile time will require something like what was done here: http://stackoverflow.com/questions/17783393/how-to-parse-text-for-a-dsl-at-compile-time – Jerry Jeremiah Nov 15 '15 at 22:12
  • Is it an option to preprocess the ASM definitions on the fly via a script to create the inline asm C versions? That is probably the most maintainable solution. – vonbrand Nov 15 '15 at 22:28