Inline assembly multiplication “undefined reference” on inputs

风流意气都作罢 提交于 2021-02-17 07:15:08

问题


Trying to multiply 400 by 2 with inline assembly, using the fact imul implicity multiplies by eax. However, i'm getting "undefined reference" compile errors to $1 and $2

 int c;
 int a = 400;
 int b = 2;

 __asm__(
  ".intel_syntax;"
  "mov eax, $1;"
  "mov ebx, $2;"
  "imul %0, ebx;"
  ".att_syntax;"
  : "=r"(c)
  : "r" (a), "r" (b)
  : "eax");

std::cout << c << std::endl;

回答1:


Do not use fixed registers in inline asm, especially if you have not listed them as clobbers and have not made sure inputs or outputs don't overlap them. (This part is basically a duplicate of segmentation fault(core dumped) error while using inline assembly)

Do not switch syntax in inline assembly as the compiler will substitute wrong syntax. Use -masm=intel if you want intel syntax.

To reference arguments in an asm template string use % not $ prefix. There's nothing special about $1; it gets treated as a symbol name just like if you'd used my_extern_int_var. When linking, the linker doesn't find a definition for a $1 symbol.

Do not mov stuff around unnecessarily. Also remember that just because something seems to work in a certain environment, that doesn't guarantee it's correct and will work everywhere every time. Doubly so for inline asm. You have to be careful. Anyway, a fixed version could look like:

__asm__(
  "imul %0, %1"
  : "=r"(c)
  : "r" (a), "0" (b)
  : );

Has to be compiled using -masm=intel. Notice b has been put into the same register as c.


using the fact imul implicity multiplies by eax

That's not true for the normal 2-operand form of imul. It works the same as other instructions, doing dst *= src so you can use any register, and not waste uops writing the high half anywhere if you don't even want it.



来源:https://stackoverflow.com/questions/60252065/inline-assembly-multiplication-undefined-reference-on-inputs

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!