Как вы будете печатать любой символ, строку или значение переменной без библиотечных функций в C?

Если, например, я не должен использовать стандартные библиотечные функции, такие как printf(), putchar(), то как я могу вывести символ на экран?

Есть ли простой способ сделать это. Я мало знаю о системных вызовах, и если мне нужно их использовать, то как мне их использовать? Так может ли кто-нибудь посоветовать простой способ печати без использования библиотечных функций?


person Manoj Doubts    schedule 22.01.2009    source источник
comment
Почему нельзя использовать стандартные библиотечные функции? Они стандартны по какой-то причине, нет?   -  person lc.    schedule 22.01.2009
comment
Почему вы хотите это сделать?   -  person Rolf Anders    schedule 22.01.2009
comment
ну, я хотел попробовать это, чтобы использовать в каком-то синтаксическом анализаторе. Если вы знаете какой-нибудь способ, пожалуйста, посоветуйте......   -  person Manoj Doubts    schedule 22.01.2009
comment
Вау, отличная работа, Хао, ты мне очень помог, первая небольшая программа, которую ты мне предложил, работает хорошо, но ты по ошибке написал src вместо scr, но хорошо, я изменил ее, теперь она работает. поэтому я предполагаю, что этот B8000000L - это адрес, по которому наш выходной символ выходит на экран, это правильно?   -  person Manoj Doubts    schedule 22.01.2009
comment
@Hao, если бы вы дали это как ответ вместо комментария, я бы принял его как ответ. хорошо, до того, сколько раз мы можем увеличить этот scr (B8000000L). Я думаю, что будет какое-то ограничение. пожалуйста, дайте мне знать о любом ресурсе, чтобы узнать больше об этих адресах. В любом случае работа gr8. Спасибо   -  person Manoj Doubts    schedule 22.01.2009


Ответы (4)


В стандартном C вы не можете. Единственный ввод-вывод, определенный в C, осуществляется через стандартные библиотечные функции C.

На данной платформе могут быть способы сделать это:

  • Делайте вызовы ядра напрямую. Для этого вам, вероятно, потребуется написать какой-нибудь встроенный ассемблер. Вы можете сделать вызов write litb напрямую, без использования библиотеки C. Возьмите исходный код вашей библиотеки C, чтобы увидеть, как это делается.
  • Запись непосредственно в буфер кадра. Многопользовательские ОС часто запрещают это (по крайней мере, без каких-либо вызовов библиотеки/ядра).

Если вы не пишете свою собственную библиотеку C, я не уверен, зачем вам это нужно.

person derobert    schedule 22.01.2009
comment
да, спасибо, я хотел сделать что-то похожее на это, большое спасибо, если у вас есть еще ресурсы для этого, пожалуйста, пришлите мне спасибо - person Manoj Doubts; 22.01.2009

В Linux вы можете использовать системный вызов write:

write(1, "hello\n", 6); // write hello\n to stdout

Если вам этого недостаточно, вы можете пойти на один шаг ниже, вызвав системный вызов в общем виде:

syscall(__NR_write, 1, "hello\n", 6);

Стоит знать о strace, который вы можете использовать, чтобы увидеть, какие системные вызовы используются какой-либо конкретной программой во время ее работы. Но обратите внимание, что для «какого-то простого парсера» вряд ли нужно использовать необработанные системные вызовы. Лучше используйте функции библиотеки c.

Кстати, обратите внимание на функции WriteFile и GetStdHandle, если вы хотите сделать то же самое в Windows без использования стандартной библиотеки c. Однако это не будет таким же l33t, как решение для Linux.

person Johannes Schaub - litb    schedule 22.01.2009
comment
Ненавижу вас, это библиотечная функция. Скорее всего, в вашей библиотеке C. - person derobert; 22.01.2009
comment
хорошо, тогда в окнах, если кто-нибудь знает, как это сделать, пожалуйста, помогите. Хорошо для вашего примечания, это не вопрос домашнего задания. Я пытался сделать это для какого-то простого парсера - person Manoj Doubts; 22.01.2009
comment
objdump -T /lib/libc.so.6 | grep syscall сообщает мне, что syscall по-прежнему является библиотечной функцией :-D - person derobert; 22.01.2009

Стандартная библиотека C (см. https://en.wikipedia.org/wiki/C_standard_library) имеет набор процедур ввода и вывода, которые используются для чтения и записи в различные ресурсы ввода и вывода. Стандартная библиотека C обычно строится на системных службах и системных вызовах, предоставляемых целевой операционной системой, хотя в случае встроенных микроконтроллеров, не имеющих операционной системы, используется другой подход.

В дополнение к стандартной библиотеке C часто используются другие библиотеки, такие как библиотека POSIX (см. https://en.wikipedia.org/wiki/C_POSIX_library).

Я использую термин ресурсы, потому что целью запроса ввода или запроса вывода может быть множество различных вещей.

  • файл на диске

  • сетевое соединение

  • консольное устройство

  • последовательный порт связи

  • датчик

  • принтер

  • окно на экране

Модель, принятая стандартной библиотекой C, аналогична модели операционной системы Unix в том смысле, что все различные виды ресурсов рассматриваются как устройство, с которого вы читаете поток символов или байтов и записываете поток символов или байтов. .

В ряде случаев такая абстракция позволяет игнорировать детали физической связности ресурса. Таким образом, вы можете открыть файл на жестком диске SATA, USB-накопителе или сетевом сервере. Вы можете печатать на принтере, независимо от того, подключен ли принтер к последовательному порту связи, USB-порту или сетевому принтеру.

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

Одним из таких консольных устройств был терминал VT100 от DEC (см. https://en.wikipedia.org/wiki/VT100 ), который использовал в выводе специальные escape-коды для выполнения таких действий, как позиционирование курсора на экране. Это было настолько удобно, что окна консоли в Unix, Linux и Windows используют одинаковые escape-коды для выполнения аналогичных действий в окнах консоли или команд (см. make-win32-console-recognize-ansi-vt100-escape-sequences">Как заставить консоль win32 распознавать управляющие последовательности ANSI/VT100?).

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

Однако Стандартная библиотека имеет ограничение на потоки символов как часть модели, которую она использует или представляет программисту. Вот почему существуют другие библиотеки, которые не являются частью стандартной библиотеки C для графических пользовательских интерфейсов и игр, например, от Microsoft, Qt и различных других групп, таких как OpenGL (см. https://en.wikipedia.org/wiki/OpenGL , https://en.wikipedia.org/wiki/DirectX , https://en.wikipedia.org/wiki/Graphical_user_interface и Что такое собственный GUI API Linux? ). См. также Как на самом деле создается графический интерфейс? и Как операционная система рисует окна на экране?

Если вы хотите обойти стандартную библиотеку C и напрямую использовать системные вызовы или службы ввода-вывода операционной системы, вы можете это сделать. Однако в отличие от стандартной библиотеки C, которая является стандартной для компиляторов, отвечающих требованиям стандарта C, службы ввода-вывода операционной системы будут различаться от операционной системы к операционной системе. Некоторые операционные системы могут иметь несколько способов выполнения одного и того же ввода-вывода. Например, в Windows есть несколько различных способов выполнения файлового ввода-вывода (см. https://en.wikipedia.org/wiki/Windows_API).

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

Встроенные приложения на микроконтроллерах часто используют определенные адреса памяти для взаимодействия с датчиками, чтобы подготовить датчик к измерению, а также для считывания данных, таких как температура, с датчика. Датчики имеют ряд различных методов подключения, которые требуют от программиста знаний об электрической настройке и протоколе, который будет использоваться для связи с датчиком, например I2C (см. https://en.wikipedia.org/).wiki/I%C2%B2C ), 1-wire (см. https://en.wikipedia.org/wiki/1-Wire) и другие.

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

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

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

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

person Richard Chambers    schedule 29.06.2020

person    schedule
comment
@Manoj Сомнения: как работает эта программа? В частности, что такое 0xB8000000L и как его получить? - person Lazer; 20.03.2010
comment
@Lazer: в оригинальном IBM PC этот адрес был жестко запрограммирован для буфера дисплея. Очевидно, Windows поддерживает его для обратной совместимости. - person egrunin; 30.07.2012