Неопределенная символьная ошибка при попытке переместиться в переменную, которая определена в C коде выше сборки - PullRequest
2 голосов
/ 13 февраля 2020

Я пытаюсь запустить ассемблерный код внутри C кода (на CLion). Я определил переменную x за пределами вставки сборки и попытался переместить в нее число, но компилятор говорит, что x не определен. Я не понимаю, как заставить его видеть переменные. Также я должен использовать синтаксис Intel.

int main(int argc, char** argv) {
short int x = 0;
__asm__ (
".intel_syntax noprefix\n\t"
"mov eax, 0x02\n\t"
"mov x, eax\n\t"
".att_syntax prefix\n\t"
);
printf("%d", x);
}

И есть ошибка

[ 50%] Building CXX object CMakeFiles/ass_lab_2.dir/main.cpp.o
[100%] Linking CXX executable ass_lab_2
/usr/bin/ld: CMakeFiles/ass_lab_2.dir/main.cpp.o: relocation R_X86_64_32S against undefined symbol `x' can not be used when making a PIE object; recompile with -fPIC
/usr/bin/ld: final link failed: Nonrepresentable section on output
collect2: error: ld returned 1 exit status
...

PS Я решил проблему. Эта ссылка была чрезвычайно полезной. Вам просто нужно передать переменные в функцию asm , используя ее синтаксис.

(Примечание редактора: первые пару страниц об использовании GNU C Basi c asm-операторов в изменяют глобальные переменные, небезопасны (потому что нет "memory" clobber) и только работают. Единственный безопасный способ изменить C переменные - это Extended asm с операндами ввода / вывода; более поздние разделы этой статьи освещают это.)

1 Ответ

3 голосов
/ 14 февраля 2020

Ваша главная проблема в том, что x является локальной переменной. Вам придется использовать расширенную сборку для ее изменения (и использовать -masm=intel для использования синтаксиса Intel):

int main(void)
{
    short int x = 0;
    __asm__("mov %0, 0x02\n\t" : "=r"(x));
    printf("%d", x);
}

Также вы можете использовать синтаксис AT & T. Это будет выглядеть так:

int main(void)
{
    short int x = 0;
    __asm__("mov $0x02, %0\n\t" : "=r"(x));
    printf("%d", x);
}

Поскольку я использую здесь ограничение =r, оно будет сохранено в регистре; следовательно, вам не нужно использовать eax (кстати, ax) в качестве промежуточного хранилища для хранения значения.

...