ben*_*wad 2 c++ assembly gnu-assembler llvm clang
我在Xcode(4.5.2)中有一个使用Debug配置构建的项目.但是,现在我已经切换到构建Release配置,我遇到了一个问题:我的一个内联汇编函数正在收到错误Invalid symbol redefinition.谷歌搜索该错误消息发现我有一些人有编译器错误,但没有关于它意味着什么的信息.这是函数,带有注释的错误行:
inline int MulDivAdd(int nNumber,
int nNumerator,
int nDenominator,
int nToAdd)
{
int nRet;
__asm__ __volatile__ (
"mov %4, %%ecx \n"
"mov %1, %%eax \n"
"mull %2 \n"
"cmp $0, %%ecx \n"
"jl __sub \n"
"addl %%ecx, %%eax \n"
"adc $0, %%edx \n"
"jmp __div \n"
"__sub: \n" // "Invalid symbol redefinition"
"neg %%ecx \n"
"subl %%ecx, %%eax \n"
"sbb $0, %%edx \n"
"__div: \n" // "Invalid symbol redefinition"
"divl %3 \n"
"mov %%eax, %0 \n"
: "=m" (nRet)
: "m" (nNumber),
"m" (nNumerator),
"m" (nDenominator),
"m" (nToAdd)
: "eax", "ecx", "edx"
);
return nRet;
}
Run Code Online (Sandbox Code Playgroud)
我试着更换__sub用__sbt,因为我觉得__sub可能是一个受保护的名字,但事实并非如此.我不明白为什么这只发生在Release中 - 可能是由于优化?
Mat*_*son 11
使用本地标签,例如1:和2:,和.jxx 1f或jxx 1b.需要跳跃的方向(f向前或b向后).所以你的代码应该是这样的:
__asm__ __volatile__ (
"mov %4, %%ecx \n"
"mov %1, %%eax \n"
"mull %2 \n"
"cmp $0, %%ecx \n"
"jl 1f \n"
"addl %%ecx, %%eax \n"
"adc $0, %%edx \n"
"jmp 2f \n"
"1: \n"
"neg %%ecx \n"
"subl %%ecx, %%eax \n"
"sbb $0, %%edx \n"
"2: \n"
"divl %3 \n"
"mov %%eax, %0 \n"
)
Run Code Online (Sandbox Code Playgroud)
纯粹由数字组成的符号是"函数的本地".由于"内联"意味着代码在物理上是重复的,因此获得多个符号定义的原因是您的符号确实以"全局"方式多次定义.
当然,如果你有一个调试版本,它通常意味着"没有内联",所以内联函数没有内联,符号只声明一次,它"工作".
[我对这个效率与编译器本身的效率有点怀疑 - 我已经想过至少考虑使用寄存器进行某些输入可以提高效率].