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++ 变量的未定义引用 [重复]的主要内容,如果未能解决你的问题,请参考以下文章
Travis CI 上的 Boost 中对 `std::__cxx11::basic_string 的未定义引用