c - 尝试移动到在汇编上面的 C 代码中定义的变量时出现 undefined symbol 错误

标签 c assembly x86 clion inline-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
...

附注我解决了问题。这个link非常有帮助。您只需使用它的语法将变量传递到 asm 函数中即可。

(编者注:其中关于使用 GNU C Basic asm 语句修改全局变量的前几页是不安全的(因为没有“内存”破坏)并且只是碰巧起作用。修改 C 变量的唯一安全方法是使用带有输入/输出操作数的扩展汇编语言;该文章的后续部分将对此进行介绍。)

最佳答案

您的主要问题是 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 $0x02, %0\n\t" : "=r"(x));
    printf("%d", x);
}

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

关于c - 尝试移动到在汇编上面的 C 代码中定义的变量时出现 undefined symbol 错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60216271/

相关文章:

c - 关于在 C 中使用扩展符号将 char 转换为 int

assembly - 为什么窥孔优化是针对汇编代码而不是 IR 代码进行的?

assembly - 如何在 assembly 过程中使用缓冲区?

c - 函数指针属于哪个缓存?

assembly - ljmp(64 位模式)被#GP(0) 拒绝。为什么?

C、GLib : Is there a method to get the size - can be applied to text file, 二进制文件、文件夹和符号链接(symbolic link)的共同点?

c - 如何在unix中获取完全限定域名

c - 二维数组中的线性搜索

assembly - NASM 中 TIMES 前缀的计数参数的最大大小?

c# - 如何将两个托管 x86/x64 dll 组合成一个托管 AnyCpu 库?