ASM 代码中对 C++ 变量的未定义引用 [重复]

Posted

技术标签:

【中文标题】ASM 代码中对 C++ 变量的未定义引用 [重复]【英文标题】:Undefined reference to C++ variables in ASM code [duplicate] 【发布时间】:2014-07-30 16:05:49 【问题描述】:

我正在尝试在 C++ 文件中编译以下 asm 代码,但它像 GCC 一样找不到 asm 部分中使用的变量。

DWORD d_eaxSave, d_ebxSave, d_ecxSave, d_edxSave, d_esiSave, d_ediSave, d_espSave, d_ebpSave;

#define ASM_UNPREFIXED_INTEL_START ".intel_syntax noprefix\n\t"
#define SAVE_REGISTERS() __asm__ (ASM_UNPREFIXED_INTEL_START    \
                              "mov d_eaxSave, eax\n\t"      \
                              "mov d_ebxSave, ebx\n\t"      \
                              "mov d_ecxSave, ecx\n\t"      \
                              "mov d_edxSave, edx\n\t"      \
                              "mov d_esiSave, esi\n\t"      \
                              "mov d_ediSave, edi\n\t"      \
                              "mov d_espSave, esp\n\t"      \
                              "mov d_ebpSave, ebp");

但是当我尝试编译时,GCC 给了我以下错误:

undefined reference to `d_eaxSave'
undefined reference to `d_ebxSave'
undefined reference to `d_ecxSave'
undefined reference to `d_edxSave'
undefined reference to `d_esiSave'
undefined reference to `d_ediSave'
undefined reference to `d_espSave'
undefined reference to `d_ebpSave'

请问我该怎么做才能消除这些错误?

【问题讨论】:

一般情况下,副本不是很好... 问题是重复的,但另一个问题的答案都是错误的。您应该使用此处给出的 Antti Haapala 回答的输出参数。 我不认为它是重复的。不过关了也没关系,因为安蒂·哈帕拉已经答应了。 嗯,这确实不完全是重复的,因为另一个是关于 C 中的全局变量,而这是关于 C++;因为变量在这里有 C++ 链接,所以那里的任何东西都不能直接在这里工作。 【参考方案1】:

您希望通常使用 AT&T 语法,因为据我所知,如果没有 -masm=intel 命令行开关,GCC 无法发出正确的 intel syntax in inline assembler - 我想您不能包含 any em> 将使用 AT&T 内联汇编的头文件。

因此:

DWORD d_eaxSave, d_ebxSave, d_ecxSave, d_edxSave, d_esiSave, d_ediSave, d_espSave, d_ebpSave;

#define SAVE_REGISTERS() __asm__ __volatile__(         \
     "movl %%eax, %0\n\t"      \
     "movl %%ebx, %1\n\t"      \
     "movl %%ecx, %2\n\t"      \
     "movl %%edx, %3\n\t"      \
     "movl %%esi, %4\n\t"      \
     "movl %%edi, %5\n\t"      \
     "movl %%esp, %6\n\t"      \
     "movl %%ebp, %7":         \
     "=m"(d_eaxSave), "=m"(d_ebxSave), "=m"(d_ecxSave), "=m"(d_edxSave),  \
     "=m"(d_esiSave), "=m"(d_ediSave), "=m"(d_espSave), "=m"(d_ebpSave)   \
)

汇编器可能不存在符号,因此您需要通过输出参数使用它们! 另请注意,通常您会希望使用__volatile__ 来确保汇编程序块没有被优化掉。

【讨论】:

这就是为什么 OP 有一个 .intel_syntax noprefix 指令,但他可能需要在末尾添加一个 .att_syntax prefix 以将其设置回来。但这与使用输出参数无关,输出参数才是问题的真实(和正确)答案。 不,.intel_syntax noprefix 没有让 GCC 发出 Intel 语法输出参数;如果无论如何都需要使用.intel_syntax 编译整个文件,那么更改语法是没有意义的。此外,如果这是在头文件中,如果使用任何其他带有内联汇编程序的文件,则会造成很大的麻烦。 这是要走的路(除了我会省略结尾的分号)。不幸的是,您需要编译器架构方面的博士学位才​​能满怀信心地使用 GCC 内联汇编器。 去掉了分号;我没有博士学位,也没有任何形式的 CS 学位,所以我没有那么大的信心,但我确实用 C++ 和内联 GAS 编写了一个 32 位保护模式内核,而且内核偶尔也可以工作,所以。

以上是关于ASM 代码中对 C++ 变量的未定义引用 [重复]的主要内容,如果未能解决你的问题,请参考以下文章

c 中对“getline”的未定义引用

linux makefile中对函数的未定义引用

Travis CI 上的 Boost 中对 `std::__cxx11::basic_string 的未定义引用

使用 QT 时对构造函数的未定义引用 [重复]

C++ 错误:对“<func name>”的未定义引用和 ld 返回 1 个退出状态 [重复]

gfortran中对`sleep`和`sizeof` instrinsics的未定义引用