Понятие о низкоуровневых языках программирования
Программирование всегда является компромиссом между пониманием принципов работы компьютера и формулированием задачи, которую предполагается выполнить с помощью вычислительной техники. Если уделять основное внимание выполняемой задаче, то можно, отвлекшись от знания компьютерной архитектуры, заложить в вычислительное устройство алгоритм, который оно не в состоянии будет выполнить. И, напротив, если принципы управления компьютером всецело учитываются, но слишком сложны, то формулирование задач для него становится чрезмерно трудоемким.
Управление процессором компьютера производится с помощью бинарных последовательностей, представляющих собой с точки зрения человеческого мышления числа, которыми пронумерованы команды процессора и ячейки памяти, в которых хранятся обрабатываемые данные. Команды процессора и способы обращения к ним хорошо документированы производителями чипов, но, поскольку команд довольно много, их запоминание и составление из них алгоритмов может оказаться затруднительным для специалистов, не прошедших длительную подготовку. Поэтому уже на ранних этапах развития компьютерной техники возникла необходимость в оптимизации процесса программирования.
Низкоуровневые языки программирования (ЯП) представляют собой формализованные синтаксисы, призванные облегчить запоминание машинных кодов, применяемых для управления компьютерными процессорами.
Характеристики и назначение низкоуровневых языков
Программист, создающий алгоритм для компьютера на языке низкого уровня, обращаются непосредственно к ресурсам компьютера: процессору, памяти, периферийным устройствам. Это обеспечивает высокую скорость работы программ, поскольку, в отличие от высокоуровневых, в низкоуровневых языках отсутствуют скрытые фрагменты кода, добавляемые автоматически компилятором во время преобразования исходного текста в бинарный код.
Высокий уровень абстракции, позволяющий писать программы на высокоуровневых языках, не задумываясь об архитектуре компьютера, достигается за счет дополнительных накладных расходов: скрытых от программиста проверок и "обвязок", помогающих не задумываться, например, о выделении памяти под переменные и возвращении ее в доступное пространство после использования.
Низкоуровневые языки, напротив, предполагают, что ответственность за все внутрикомпьютерные ресурсы (время загрузки процессора, объемы выделяемой памяти и т.п.) программист берет на себя. По этой причине языки низкого уровня относятся к "небезопасным": при написании с их помощью более-менее обширных программ, в коде появляется больше ошибок, чем при написании на языках высокого уровня. Низкоуровневое программирование применяется в основном для создания компактного ПО, например, для программирования систем реального времени (когда недопустимы задержки в работе), встраиваемых систем (микроконтроллеров), а также драйверов, управляющих внешними устройствами:
- принтерами,
- сканерами,
- камерами и т.п.
ассемблере. Автор24 — интернет-биржа студенческих работ" />
Рисунок 1. Прошивка микроконтроллера программой на ассемблере. Автор24 — интернет-биржа студенческих работ
Язык ассемблера
За понятием "ассемблер" кроется не язык программирования с четко формализованным синтаксисом, а скорее принципы создания синтаксисов для управления процессорами разных архитектур. Процессоры, выпускаемые современной промышленностью, обладают различными архитектурами, различными наборами команд, поэтому и языки ассемблера для них различаются. Более того, для одного и того же процессора может быть разработано несколько видов языка ассемблера (например, для работы в различных операционных системах). Однако создаются ассемблеры на основе одних и тех же принципов: громоздкие машинные коды заменяются более удобными для запоминания синтаксическими конструкциями, удобными для запоминания благодаря тому, что они напоминают слова обычного языка. Поскольку большая часть вычислительной техники разрабатывается в США и Европе, слова в ассемблерах обычно используются английские. Например, команда ADD означает сложение регистров процессора и соответствует английскому глаголу to add - складывать.
Программирование на ассемблере сводится к занесению в регистры компьютера данных из памяти (к которой с точки зрения процессора относятся и подключенные к компьютеру устройства), выполнению операций над ними и записи результата в память. За регистрами процессора закреплены буквенные обозначения, номенклатура которых зависит от типа процессора (Intel x86, ARM и др).
Рисунок 2. Регистры процессора. Автор24 — интернет-биржа студенческих работ
Особый регистр-указатель команд (EIP) отвечает за последовательность выполнения команд. Его изменение недоступно программисту. Управление регистром-указателем производятся командами условных и безусловных переходов, циклов, вызова процедур и возврата из них.
Несмотря на сложный синтаксис, на ассемблере можно писать довольно сложные приложения, в том числе приложения с графическим интерфейсом. Для облегчения работы используются макросы, внешние подключаемые библиотеки, а также возможности операционной системы, предоставляемые разработчикам в задокументированном виде (API).
Рисунок 3. Программа на ассемблере. Автор24 — интернет-биржа студенческих работ
Язык программирования Си обычно относят к высокоуровневым, но он располагает возможностями и для низкоуровневого программирования: написанные на нем программы способны непосредственно обращаться к набору процессорных команд, выделять и освобождать память в произвольном порядке и т.п. Программы на Си также могут содержать в себе ассемблерные вставки.