尝试移动到在汇编上方的 C 代码中定义的变量时出现未定义符号错误

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

我正在尝试 运行 C 代码中的汇编代码(在 CLion 上)。我在程序集插入之外定义了变量 x 并试图将一个数字移入其中,但编译器说 x 未定义。我不知道如何让它看到变量。我还必须使用英特尔语法。

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);
}


并且有错误

[ 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。我解决了问题。 link 非常有帮助。您只需要使用它的语法将变量传递给 asm 函数。

(编者注:关于使用 GNU C Basic asm 语句修改全局变量的前几页是不安全的(因为没有 "memory" clobber)并且只是碰巧有效。唯一安全的修改 C 变量的方法是使用带有 input/output 操作数的扩展 asm;该文章的后面部分将介绍它。)

你的主要问题是 x 是一个局部变量。您将必须使用 extended assembly 来修改它(并使用 -masm=intel 来使用 Intel 语法):

int main(void)
{
    short int x = 0;
    __asm__("mov %0, 0x02\n\t" : "=r"(x));
    printf("%d", x);
}

此外,您还可以使用 AT&T 语法。它看起来像这样:

int main(void)
{
    short int x = 0;
    __asm__("mov [=11=]x02, %0\n\t" : "=r"(x));
    printf("%d", x);
}

因为我在这里使用 =r 约束,所以这将存储在寄存器中;因此,您不需要使用 eax(顺便说一句,应该是 ax)作为中间存储位置来存储值。