C без stdio, что можно?

Я давно интересовался программированием операционной системы. Копаясь на нескольких разных сайтах, я наткнулся на интересную концепцию (перефразируя): если вы начинаете писать свой загрузчик с #include, вы уже совершили фатальную ошибку.

Я прошел K&R, и вся книга включает его в каждый урок. Используя его во время изучения C, я не знаю, что из того, что я узнал, использует stdio, а что нет. Что вы можете сделать на C без stdio?


person Matticus    schedule 30.06.2011    source источник
comment
Нет #include, что означает, что загрузчик не должен использовать какие-либо функции из стандартной библиотеки C? Вместо этого вы должны катить свои собственные? Я бы сказал, что это верный способ сделать ваш загрузчик глючным.   -  person Praetorian    schedule 30.06.2011
comment
«stdio» — вы имели в виду «библиотеку времени выполнения C»?   -  person Andrey Sidorov    schedule 30.06.2011
comment
@Praetorian - я считаю, что проблема в том, что многие функции в stdio реализованы с точки зрения системных вызовов к ОС. Любая такая функция самоуничтожится, если будет вызвана в такой среде, как загрузчик, в которой нет ОС, обеспечивающей API системного вызова для вызова. Либо загрузчик должен предоставить этот API сам, либо он должен избегать вызова любых таких функций до тех пор, пока он не загрузит ОС, которая это делает. Так что в этом смысле, да, вы должны сворачивать свои собственные, если они вам нужны.   -  person aroth    schedule 30.06.2011
comment
@aroth, да, но есть много библиотек, подходящих для встроенных сред (то есть без ОС). См. uclibc и newlib для ведущих кандидатов с открытым исходным кодом.   -  person djs    schedule 30.06.2011


Ответы (5)


Стандарт C (ISO/IEC 9899:1999) признает два типа реализации (§4 Соответствие, §6):

  • Автономный - где реализация (компилятор плюс библиотека) предоставляет только семь заголовков:

    <float.h>
    <iso646.h>
    <limits.h>
    <stdarg.h>
    <stdbool.h>
    <stddef.h>
    <stdint.h>
    

    Они предоставляют базовые возможности языка и не объявляют никаких функций (возможности в <stdarg.h> явно определены как макросы в стандарте). Обратите внимание, что он не включает комплексные числа.

  • Хостинг — где реализация предоставляет полную библиотеку, определенную стандартом.

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

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

person Jonathan Leffler    schedule 30.06.2011
comment
На практике вы, скорее всего, получите полную реализацию стандартной библиотеки C (а не минимальное подмножество, определенное для автономных сред) с различными хуками, определенными для реализации требуемой низкоуровневой функциональности. Это позволяет вам реализовать любое необходимое вам подмножество стандартной библиотеки. - person djs; 30.06.2011
comment
Это не совсем точно, эти заголовки являются необходимым минимумом для реализации автономного компилятора. На самом деле, большинство автономных компиляторов будут реализовывать весь ISO C. Проблемы возникают, когда вы берете компилятор для размещенной системы и пытаетесь написать программы для автономной системы, поскольку внутри библиотек могут быть вызовы API. - person Lundin; 30.06.2011

Любой загрузчик почти наверняка будет иметь директивы #include, если только он не плохо спроектирован. Я не знаю, откуда вы взяли эту цитату, но, возможно, вы ее неправильно поняли. Загрузчик всегда запускается с фрагментом чистого ассемблерного кода для начальной низкоуровневой инициализации процессора и для инициализации среды выполнения C. Этот код просто невозможно написать на C. Но остальной код может быть настолько сложным, насколько это необходимо, в рамках ограничений среды (память и т.д.).

stdio — это просто набор файловых потоков, подключенных к какому-либо устройству, которое может получать ввод и вывод. Вы можете реализовать stdin, stdout, stderr или любое их подмножество. Вы также можете реализовать файловую систему, для которой вы можете открывать произвольные файловые потоки. В современной ОС это обычно заканчивается подключением к какому-то терминалу, который включает довольно много промежуточных слоев, потому что это виртуальный терминал, который отображается на вашем мониторе и, следовательно, требует графического драйвера и так далее. В примитивной встроенной системе stdio может быть подключен к последовательному порту или светодиодному дисплею.

stdio реализован с помощью функций read() и write(). Если они не реализованы, вы просто не сможете использовать функции stdio, такие как printf(), fprintf(), fgets() и т. д. Это не значит, что вы не можете писать на свой графический дисплей, последовательный порт или что-то еще. Это просто означает, что у вас нет стандартного средства для этого, и вам нужно будет вызывать пользовательские функции.

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

person djs    schedule 30.06.2011

stdio означает стандартный ввод/вывод. Как следует из названия, он содержит вещи, связанные со стандартным вводом-выводом. Статья Википедии о stdio.h перечисляет содержимое stdio.h. Вам понадобится stdio.h, если вы их используете. Также вы можете проверить справочную страницу stdio.h, чтобы получить дополнительную информацию.

Что касается ОС, написание ОС — это гораздо больше, чем простое программирование, даже если оно академическое. Прежде чем перейти к этому, вы должны изучить структуры данных, алгоритмы, теории ОС и многое другое. Дизайн операционной системы UNIX — это очень хорошая книга для изучения ОС. Nachos — академическая программа моделирования ОС. Вы тоже можете это проверить. А если вы фанатик ОС, то вам следует прочитать автобиографию Линуса Торвальдса Просто для развлечения. Ну, это не техническая книга, но вы почувствуете, что значит писать ОС.

person taskinoor    schedule 30.06.2011
comment
Обязательно возьму книгу, спасибо за отзыв. - person Matticus; 01.07.2011

Другие ответы о минимальных средах C хороши, но вот еще один более абстрактный угол.

Стандарт C определяет два типа «наблюдаемых побочных эффектов», которые в основном означают то, что делает ваша программа, что не может быть оптимизировано или иным образом изменено компилятором. Это, во-первых, вызовы функций ввода-вывода, а во-вторых, чтение и запись volatile объектов.

Если у вас нет доступа к stdio или другим частям вашей реализации C, которые зависят от присутствия ОС, вы не можете использовать функции ввода-вывода. Это оставляет чтение и запись в объекты volatile как единственные вещи, которые ваша программа будет фактически "делать". На практике вам может понадобиться или не понадобиться фактически помечать все volatile, поскольку ваша реализация C, вероятно, предоставляет гарантии, выходящие за рамки стандарта. Если есть инструкция ЦП, которая издает звуковой сигнал, ваш компилятор будет рассматривать ее (и встроенный ассемблер в целом) как функцию ввода-вывода, даже если на самом деле это не функция, и так далее.

Другими словами, вам придется использовать низкоуровневый аппаратный доступ для достижения того, чего должен достичь ваш загрузчик (что означает: отображение сообщения на экране, установка некоторых ресурсов, необходимых ОС для запуска, загрузка ее и запустить его). Этот доступ, конечно, полностью зависит от реализации - поставщики оборудования могут предоставить библиотеки, чтобы помочь вам, они просто не будут стандартными заголовками C.

person Steve Jessop    schedule 30.06.2011

Как отмечает Taskinoor, в Википедии есть отличная ссылка на то, что включено в stdio.h.

Что касается того, что возможно без stdio.h, почти все, что возможно с ним, хотя для некоторых вещей вам придется потрудиться намного усерднее. Например, если вы хотите использовать файлы, вам придется определить собственную абстракцию файла и собственный интерфейс для работы с ним. Если вы хотите прочитать ввод с клавиатуры, вместо вызова scanf() вам придется использовать ассемблерный код для вызова прерывания BIOS.

Такова природа программирования ОС. Ни одна из этих высокоуровневых конструкций не существует, пока вы не определите их и API для работы с ними. Вам нужно начать с самых маленьких базовых функциональных возможностей и начать группировать их вместе, чтобы создавать все более полезные и сложные конструкции.

person aroth    schedule 30.06.2011