& quot; Неверное переопределение символа & quot; встроенный ASM на LLVM

У меня есть проект в Xcode (4.5.2), который прекрасно работает с использованием конфигурации Debug. Однако теперь, когда я перешел на сборку конфигурации выпуска, у меня возникает проблема: одна из моих встроенных функций сборки получает ошибку 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;
}

Я пытался заменить __sub с __sbt потому что я думал __sub может быть защищенным именем, но это не так. Я не понимаю, почему это происходит только в Release — может ли это быть из-за оптимизации?

2

Решение

использование местные лейблы, такие как 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")

Символы, состоящие исключительно из чисел, «локальны для функции». Поскольку «встроенный» означает, что код физически дублируется, причина, по которой вы получаете несколько определений символов, заключается в том, что ваши символы действительно определяются несколько раз «глобальным» способом.

Конечно, если у вас есть отладочная сборка, это обычно означает «нет встроенного», поэтому встроенная функция не является встроенной, символы объявляются только один раз, и она «работает».

[Я немного сомневаюсь в эффективности этого по сравнению с тем, что компилятор сделает сам — я бы подумал, по крайней мере, рассмотрение использования регистров для некоторых входных данных сделало бы его более эффективным].

11

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]