Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/assembly/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
试图移动到程序集上方C代码中定义的变量时出现未定义符号错误_C_Assembly_X86_Clion_Inline Assembly - Fatal编程技术网

试图移动到程序集上方C代码中定义的变量时出现未定义符号错误

试图移动到程序集上方C代码中定义的变量时出现未定义符号错误,c,assembly,x86,clion,inline-assembly,C,Assembly,X86,Clion,Inline Assembly,我试图在C代码中运行汇编代码(在CLion上)。我在assembly insert外部定义了变量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"

我试图在C代码中运行汇编代码(在CLion上)。我在assembly insert外部定义了变量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
...
我解决了这个问题。这非常有帮助。您只需要使用函数的语法将变量传递到asm函数中


(编者按:前几页关于使用GNU C Basic asm语句修改全局变量的内容是不安全的(因为没有
“内存”
clobber),而且只能正常工作。修改C变量的唯一安全方法是使用带有输入/输出操作数的扩展asm;该文章后面的部分将介绍这一点。)您的主要问题是
x
是一个局部变量。您必须使用来修改它(并使用
-masm=intel
来使用英特尔语法):

此外,还可以使用AT&T语法。它将如下所示:

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

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

是链接器无法解析
x
。你试过它的建议了吗?“用-fPIC重新编译”你编译的是什么编译器和体系结构?我真蠢,我没有试过这个。但是现在在阅读了一些关于使用-fPIC重新编译的文章之后,我不知道如何做到这一点。我稍后会尝试告诉你它是否正常。
x
被定义为
short
,这与
mov x不一致,eax
我只是在Ubuntu18.04上用CLion编译它。请注意,切换到Intel语法并返回内联asm是一个令人讨厌的黑客行为,只要你想让编译器在诸如调试模式下用dword ptr[rbp-4]之类的寻址模式替换
“=rm”(x)
,它就会崩溃。它仍将替换
-4(%rbp)
。我认为,如果clang在英特尔语法模式下拒绝
%eax
(额外的装饰),它将在寄存器方面实现收支平衡。GCC的正确方法是使用
-masm=intel
构建。很抱歉,对于叮当声没有完全的解决办法。
int main(void)
{
    short int x = 0;
    __asm__("mov $0x02, %0\n\t" : "=r"(x));
    printf("%d", x);
}