问题
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