2013-08-11 2 views
6

Планировщик моего mini os написан на сборке, и мне интересно, почему. Я узнал, что инструкция eret не может быть сгенерирована компилятором C, это что-то, что может быть обобщено на другие платформы, кроме Nios, а также x86 и/или MIPS architechture? Поскольку я считаю, что часть os всегда записывается в сборке, и я ищу, почему системный программист должен знать сборку для написания операционной системы. Есть ли случаи, когда существуют встроенные ограничения компилятора C, которые не могут генерировать определенные инструкции по сборке, такие как eret, который возвращает программу в то, что было сделано после прерывания?Почему какая-то часть os должна быть записана в сборке?

+1

Это не * действительно * правда. Варианты существуют для выполнения целиком на C, но это может быть неудобно. Даже если встроенный модуль ассемблера не поддерживает инструкцию, часто можно использовать исполняемую строку. –

ответ

3

Общий ответ для одной из трех причин:

  1. Потому что конкретный тип кода не может быть написан на C. Я думаю, что eret является «возврат из исключения» инструкции, так что нет C, эквивалентного этому (поскольку аппаратные исключения, такие как ошибки страницы, деление на ноль или подобное, не являются исключениями стиля C/C++). Другим примером может быть сохранение регистров в стек при переключении задач и сохранение указателя стека в блок управления задачами. Код C не может этого сделать, потому что нет прямого доступа к указателю стека.

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

  3. Запуск кода C должен быть написан на ассемблере, поскольку программа C нуждается в определенных настройках, прежде чем вы сможете запустить фактический код C. Например, настройка указателя стека и некоторых других регистров.

3

Да, это он. Есть инструкции, которые вы не можете генерировать с использованием языка C. И обычно для одной ОС требуется одна или несколько инструкций, поэтому требуется сборка. Это справедливо для почти любого набора команд, x86, arm, mips и т. Д. C компиляторы позволяют делать встроенную сборку для инструкций по помехам, но сам язык не справляется с нюансами каждого набора команд и пытается учесть их. Некоторые компиляторы добавят специфические для компилятора вещи, например, возвращают функцию, используя обратный эффект прерывания. Намного проще просто писать сборку там, где нужно, чем настраивать язык или компиляторы, поэтому там действительно нет спроса.

3

Язык C выражает то, что указано, чтобы выразить: основные арифметические операции, назначение значений переменным, а также ветви и вызовы функций. Объекты могут быть выделены с использованием static, автоматической (локальной) или динамической (malloc) продолжительности хранения. Если вам нужно что-то за пределами этой концептуальной области, вам нужно что-то отличное от чистого C.

Язык C может быть расширен произвольно, и многие платформы определяют синтаксис для таких вещей, как определение функции или переменной по конкретному адресу.

Но аппаратное обеспечение CPU заботится о множестве деталей, таких как значения регистров флага. Часть планировщика, который переключает потоки, должна иметь возможность сохранять все регистры в памяти, прежде чем что-либо делать, потому что перезапись любого регистра потеряет важные данные в прерванном потоке.

Единственный способ написать такую ​​вещь в C, было бы для компилятора предоставить функцию C, которая генерирует тонко настроенную сборку. И тогда вы, по сути, вернулись на квадрат 1, потому что важные детали все еще находятся на уровне кода сборки.

Поставщики с несколькими линейками микроконтроллеров иногда выходят из своего пути, чтобы обеспечить совместимость с исходным кодом C даже на самых низких уровнях, чтобы позволить своим клиентам код порта (или, наоборот, чтобы они не переходили к другому поставщику, когда им нужно для переключения платформ). Но различие между C и сборкой размывается в определенный момент, когда вы вызываете псевдофункции, которые генерируют конкретные инструкции (известные как intrinsics).

1

Некоторых вещей, которые не могут быть сделаны в C или что, если они могут быть сделаны, лучше сделать в сборке, поскольку они более просты и/или обслуживаемые таким образом включает в себя:

  • Выполнение обратного from- инструкции исключения и возврата из прерывания.
  • Чтение и запись в специальные регистры процессора (которые управляют состоянием процессора, отображением памяти, конфигурацией кэша, управлением исключениями и т. Д.).
  • Выполнение атомных операций чтения и записи на специальные адреса, которые связаны с аппаратными устройствами, а не с памятью.
  • Выполните инструкции по загрузке и хранению определенных размеров или характеристик по специальным адресам, как описано выше. (Например, для записи на определенные устройства может потребоваться использовать только инструкцию с 16-битным хранилищем, а не обычную инструкцию с 32-разрядным хранилищем.)
  • Выполнение инструкций по барьерам памяти или упорядочению, управлению кешем и очистке карт памяти ,

В целом, C в основном предназначен для выполнения вычислений (чтение входов, вычисления вещей, записи выходов), а не для управления машиной (взаимодействие со всеми элементами управления и устройствами в машине).

Смежные вопросы