Clang + iOS + ассемблерный переход: ошибка «неподдерживаемое перемещение по символу» - PullRequest
1 голос
/ 03 ноября 2019

У меня есть ассемблерный код для ARM32, на Android он хорошо компилируется, но для iOS он выдает ошибку «неподдерживаемое перемещение по символу» в инструкции перехода. Для Android64 и iOS64 такая же ситуация.

clang -target armv7m-none-ios-gnueabi "test.c"
void func()
{
    __asm__ volatile
    (
        "eor r0, 0 \n\t" 
        "cmp r0, 0 \n\t"
        "beq .done \n\t" /*!!!*/
        "eor r0, 0 \n\t"
    ".done: \n\t"
        "bx lr \n\t"
    );
}

В то же время в Godbolt проблем не возникает https://godbolt.org/z/lr2bsZ. Я использую компилятор Clang 8.0.0.

1 Ответ

3 голосов
/ 03 ноября 2019

Метка должна быть локальной, т.е. начинаться с заглавной буквы L. Обратите внимание, что это отличается от целей ELF, где локальные метки начинаются с .L.

. Этот код прекрасно скомпилирован для меня:

void func()
{
    __asm__ volatile
    (
        "eor r0, 0 \n\t" 
        "cmp r0, 0 \n\t"
        "beq Ldone \n\t" /*!!!*/
        "eor r0, 0 \n\t"
    "Ldone: \n\t"
        "bx lr \n\t"
    );
}

В качестве примечания, возможно, вы захотитенапишите свою функцию полностью в сборке следующим образом, потому что, насколько мне известно, нет никакой гарантии, что компилятор не вставит код до или после вашей сборки, которая нарушает ваши предположения. Поэтому я бы предложил что-то вроде этого:

__asm__
(
"_func: \n"
    "eor r0, 0 \n" 
    "cmp r0, 0 \n"
    "beq Ldone \n"
    "eor r0, 0 \n"
"Ldone: \n"
    "bx lr \n"
);
...