Search code examples
cassemblyx86clioninline-assembly

Undefined symbol error when trying to mov into variable which defined in C code above assembly


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.)


Solution

  • 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.