Встроенная сборка GCC в Linux bootc.c: сообщения ассемблера: ошибка: мусор 'int 0x10h' после выражения - PullRequest
0 голосов
/ 10 сентября 2018

Я пытаюсь скомпилировать c файл через gcc и получаю Ошибка

gcc -m32 -c bootc.c -o bootc.o
bootc.c: Assembler messages:
bootc.c:5: Error: junk `int 0x10h' after expression   

код

void kmain(void){
    asm(
        "mov %al, 'H'"
        "int 0x10h"
    );
}

1 Ответ

0 голосов
/ 10 сентября 2018

Встроенная сборка в GCC - это обычные литеральные строки, соответствующие нормальным правилам таких в C или C ++ (что бы вы ни программировали).

Это означает, что смежные литеральные строки без пробела или комментариев между ними будут объединены в одну строку.

Что вы думаете

asm(
    "mov %al, 'H'"
    "int 0x10h"
);

действительно с точки зрения компиляторов

asm(
    "mov %al, 'H' int 0x10h"
);

Указанное выше не является действительной инструкцией.

Вот почему, если вы посмотрите на множество примеров встроенной сборки GCC, после каждой строки сборки должны быть новые строки. Как в

// also converted to Extended Asm syntax to fix other problems
asm(
    "mov $'H', %%al\n"  // Note newline here at the end
    "int $0x10"        // gas doesn't understand trailing-h suffix, only 0x for hex
    : // no outputs
    : // no inputs
    : "ax"  // tell the compiler we clobber AX
     // FIXME: also tell the compiler about any other registers this uses
);

Литеральные строки будут по-прежнему объединяться, но теперь между инструкциями ассемблера для их различения есть новая строка. Обычно используется \n\t, поэтому выходные данные компилятора asm читаются и имеют отступы.


В связанной заметке вы действительно должны больше узнать о синтаксисе сборки AT & T / GAS , поскольку в вашем коде есть другие проблемы. Например, числовые литералы в ассемблерном коде должны иметь префикс $; И здесь нет шестнадцатеричного суффикса для шестнадцатеричных чисел, только простой префикс 0x (использование префикса и суффикса h является избыточным).

Также обратите внимание, что синтаксис AT & T имеет место назначения последним, поэтому перемещение непосредственного значения 'H' в AL выполняется с помощью mov $'H', %al.

Не забудьте установить AH для кода функции в соответствии с https://en.wikipedia.org/wiki/INT_10H. Компилятор может делать все что угодно с AH.

...