2

Let's say I have the following function in C:

void sum(){

      float a,b,ans; 
      a = 1.0; b = 2.0; //I do use scanf for a and b for for simplicity i'll just use random numbers
      ans = a+b;      
      printf("Answer is %.2f",ans);
    }

How can I make the exact same behavior (mathematically operate 2 variables and store the result in another variable) using inline assembly in C? Replacing only the ans = a+b line would be ideal, I'm using gcc or MinGW for windows version of Codeblock compilers if it changes anything.

aep
  • 1,583
  • 10
  • 18
  • They closed this question, but in any case, here follows: you can change the line `ans = a+b` for `asm ( "movss (%0), %%xmm0;" "movss (%1), %%xmm1;" "addss %%xmm0, %%xmm1;" "movss %%xmm1, (%2);" : : "r" (&a), "r" (&b), "r"(&ans) );` – André Caceres Feb 13 '20 at 23:03
  • 1
    @AndréCaceres: that's extremely inefficient in that it forces everything into memory. Much better is to use the registers directly: `asm("addss %2, %0" : "=r"(ans) : "0"(a), "r"(b));` – Chris Dodd Feb 14 '20 at 00:57
  • @Chris Dodd, I just copied the disassembly code from GCC in debug mode. But thank you for point a better alternative! – André Caceres Feb 14 '20 at 01:31
  • @ChrisDodd: `"r"` is a GP-integer register. You want `"x"` for xmm registers. `asm("addss %1, %0" : "+x"(dst) : "x"(src));` – Peter Cordes Feb 14 '20 at 02:30
  • @AndréCaceres: The asm in your first comment isn't even safe. You destroy XMM0 and XMM1 without telling the compiler, and asking for a pointer in a register doesn't tell the compiler that you read or write the pointed-to memory. Also, copying anti-optimized `-O0` asm output is terrible. Write a function that takes two `float` args and returns a `float` so you can compile with optimization and see a stand-alone definition for it. ([How to remove "noise" from GCC/clang assembly output?](//stackoverflow.com/q/38552116)) – Peter Cordes Feb 14 '20 at 02:32
  • @PeterCordes could you elaborate on the part that the XMM0 and XMM1 is destroyed? I did not get it. Sorry. – André Caceres Feb 14 '20 at 02:52
  • The asm code in your template string uses `movss` loads into XMM0 and XMM1, replacing their old value. So you step on the compiler's toes if it was expecting those registers to still hold some value later. https://gcc.gnu.org/onlinedocs/gcc/Extended-Asm.html#Clobbers-and-Scratch-Registers – Peter Cordes Feb 14 '20 at 03:18

0 Answers0