Планировщик моего mini os написан на сборке, и мне интересно, почему. Я узнал, что инструкция eret
не может быть сгенерирована компилятором C, это что-то, что может быть обобщено на другие платформы, кроме Nios, а также x86 и/или MIPS architechture? Поскольку я считаю, что часть os всегда записывается в сборке, и я ищу, почему системный программист должен знать сборку для написания операционной системы. Есть ли случаи, когда существуют встроенные ограничения компилятора C, которые не могут генерировать определенные инструкции по сборке, такие как eret
, который возвращает программу в то, что было сделано после прерывания?Почему какая-то часть os должна быть записана в сборке?
ответ
Общий ответ для одной из трех причин:
Потому что конкретный тип кода не может быть написан на C. Я думаю, что
eret
является «возврат из исключения» инструкции, так что нет C, эквивалентного этому (поскольку аппаратные исключения, такие как ошибки страницы, деление на ноль или подобное, не являются исключениями стиля C/C++). Другим примером может быть сохранение регистров в стек при переключении задач и сохранение указателя стека в блок управления задачами. Код C не может этого сделать, потому что нет прямого доступа к указателю стека.Потому что компилятор не будет производить как хороший код, как кто-то умный записывающий ассемблер. Некоторые специализированные операции могут быть трудными для записи в C - компилятор может не генерировать очень хороший код, или код очень запутан для достижения чего-то простого в ассемблере.
Запуск кода C должен быть написан на ассемблере, поскольку программа C нуждается в определенных настройках, прежде чем вы сможете запустить фактический код C. Например, настройка указателя стека и некоторых других регистров.
Да, это он. Есть инструкции, которые вы не можете генерировать с использованием языка C. И обычно для одной ОС требуется одна или несколько инструкций, поэтому требуется сборка. Это справедливо для почти любого набора команд, x86, arm, mips и т. Д. C компиляторы позволяют делать встроенную сборку для инструкций по помехам, но сам язык не справляется с нюансами каждого набора команд и пытается учесть их. Некоторые компиляторы добавят специфические для компилятора вещи, например, возвращают функцию, используя обратный эффект прерывания. Намного проще просто писать сборку там, где нужно, чем настраивать язык или компиляторы, поэтому там действительно нет спроса.
Язык C выражает то, что указано, чтобы выразить: основные арифметические операции, назначение значений переменным, а также ветви и вызовы функций. Объекты могут быть выделены с использованием static
, автоматической (локальной) или динамической (malloc) продолжительности хранения. Если вам нужно что-то за пределами этой концептуальной области, вам нужно что-то отличное от чистого C.
Язык C может быть расширен произвольно, и многие платформы определяют синтаксис для таких вещей, как определение функции или переменной по конкретному адресу.
Но аппаратное обеспечение CPU заботится о множестве деталей, таких как значения регистров флага. Часть планировщика, который переключает потоки, должна иметь возможность сохранять все регистры в памяти, прежде чем что-либо делать, потому что перезапись любого регистра потеряет важные данные в прерванном потоке.
Единственный способ написать такую вещь в C, было бы для компилятора предоставить функцию C, которая генерирует тонко настроенную сборку. И тогда вы, по сути, вернулись на квадрат 1, потому что важные детали все еще находятся на уровне кода сборки.
Поставщики с несколькими линейками микроконтроллеров иногда выходят из своего пути, чтобы обеспечить совместимость с исходным кодом C даже на самых низких уровнях, чтобы позволить своим клиентам код порта (или, наоборот, чтобы они не переходили к другому поставщику, когда им нужно для переключения платформ). Но различие между C и сборкой размывается в определенный момент, когда вы вызываете псевдофункции, которые генерируют конкретные инструкции (известные как intrinsics).
Некоторых вещей, которые не могут быть сделаны в C или что, если они могут быть сделаны, лучше сделать в сборке, поскольку они более просты и/или обслуживаемые таким образом включает в себя:
- Выполнение обратного from- инструкции исключения и возврата из прерывания.
- Чтение и запись в специальные регистры процессора (которые управляют состоянием процессора, отображением памяти, конфигурацией кэша, управлением исключениями и т. Д.).
- Выполнение атомных операций чтения и записи на специальные адреса, которые связаны с аппаратными устройствами, а не с памятью.
- Выполните инструкции по загрузке и хранению определенных размеров или характеристик по специальным адресам, как описано выше. (Например, для записи на определенные устройства может потребоваться использовать только инструкцию с 16-битным хранилищем, а не обычную инструкцию с 32-разрядным хранилищем.)
- Выполнение инструкций по барьерам памяти или упорядочению, управлению кешем и очистке карт памяти ,
В целом, C в основном предназначен для выполнения вычислений (чтение входов, вычисления вещей, записи выходов), а не для управления машиной (взаимодействие со всеми элементами управления и устройствами в машине).
- 1. Итак, какая информация вообще должна быть записана в форме «О»?
- 2. Как должна быть записана команда «CDPATH» в файле .bashrc?
- 3. Почему подпрограмма должна быть записана после объявления переменных, используемых в ней?
- 4. Почему мы пишем какую-то часть os в сборке и какую-то часть на языке высокого уровня, например c?
- 5. Левая часть задания должна быть переменной
- 6. Левая часть задания должна быть переменной Ошибка
- 7. Почему переменная должна быть инициализирована?
- 8. Почему структура должна быть в штучной упаковке?
- 9. Почему эта переменная должна быть развернута?
- 10. Как определить, может ли быть записана труба
- 11. Часть текста должна быть выделена жирным шрифтом в jList
- 12. Левая часть задания должна быть переменной ошибкой в eclipse
- 13. какая часть файла ELF должна быть загружена в память?
- 14. В методологии Sprint, когда должна быть выполнена адаптивная часть?
- 15. Передача сложной переменной PHP, которая должна быть записана внешним .js-файлом
- 16. Насколько коротким должна быть функция?
- 17. Почему эта функция должна быть внутри document.ready?
- 18. Почему функция PHP `curl_exec` должна быть отключена?
- 19. Почему веб-архитектура должна быть тесно связана?
- 20. Почему регистрация пользователя должна быть регулярной?
- 21. Почему длина должна быть подтипом индексатора?
- 22. Почему нет NoneType, когда должна быть метка?
- 23. Почему эта функция должна быть статической?
- 24. Почему моя функция __init__ должна быть @classmethod?
- 25. Почему переменная объекта должна быть указателем?
- 26. «CFBundleVersion должна быть строка» из OS X приборной панели
- 27. Почему переменная должна быть общедоступной или частной или защищать, но функция не должна быть в классе
- 28. Java: Левая часть аргумента должна быть переменной charAt error
- 29. Левая часть задания должна быть переменной, свойством или индексом?
- 30. «Левая часть задания должна быть переменной» с charAt
Это не * действительно * правда. Варианты существуют для выполнения целиком на C, но это может быть неудобно. Даже если встроенный модуль ассемблера не поддерживает инструкцию, часто можно использовать исполняемую строку. –