I am trying to run assembly code inside C code(on CLion). I defined variable x outside of assembly insert and tried to mov a number into it but compiler says x is undefined. I don't get how to make it see variables. Also I have to use intel syntax.
int main(int argc, char** argv) {
short int x = 0;
__asm__ (
".intel_syntax noprefix\n\t"
"mov eax, 0x02\n\t"
"mov x, eax\n\t"
".att_syntax prefix\n\t"
);
printf("%d", x);
}
And there is error
[ 50%] Building CXX object CMakeFiles/ass_lab_2.dir/main.cpp.o
[100%] Linking CXX executable ass_lab_2
/usr/bin/ld: CMakeFiles/ass_lab_2.dir/main.cpp.o: relocation R_X86_64_32S against undefined symbol `x' can not be used when making a PIE object; recompile with -fPIC
/usr/bin/ld: final link failed: Nonrepresentable section on output
collect2: error: ld returned 1 exit status
...
P.S. I solved problem. This link was extremely helpful. You just need to pass your variables into asm function using it's syntax.
(Editor's note: the first couple pages of that, about using GNU C Basic asm statements to modify global variables, are unsafe (because there's no "memory"
clobber) and only happen to work. The only safe way to modify C variables is with Extended asm with input/output operands; later sections of that article cover that.)
Your main issue is that x
is a local variable. You will have to use extended assembly to modify it (and use -masm=intel
to use Intel syntax):
int main(void)
{
short int x = 0;
__asm__("mov %0, 0x02\n\t" : "=r"(x));
printf("%d", x);
}
Also, you can use AT&T syntax. It will look like this:
int main(void)
{
short int x = 0;
__asm__("mov $0x02, %0\n\t" : "=r"(x));
printf("%d", x);
}
Because I'm using the =r
constraint here, this will be stored in a register; therefore, you don't need to use eax
(which should be ax
, by the way) as an intermediate storage place to store the value.