Машинный код как язык программирования. Язык ассемблера

Язык сборки (или ассемблера) представляет собой низкоуровневый язык программирования для компьютера или иного программируемого оборудования, в котором существует корреляция между языком и инструкцией машинного кода архитектуры. Каждый машинно-ориентированный язык (в профессиональной терминологии — «сборщик») относится к конкретной компьютерной архитектуре. Напротив, большинство высокоуровневых языков программирования кроссплатформенны, но требуют интерпретации или компиляции.

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

машинный код

Использование

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

Историческая перспектива

Первый ассемблерный язык был разработан в 1947 году Кэтлин Бут для ARC2 в Биркбекском лондонском университете в процессе работы с Джоном фон Нейманом и Германом Голдстином в Институте перспективных исследований. SOAP (Symbolic Optimal Assembly Program) была языком ассемблера для ПК IBM 650, созданного Стэном Поули в 1955 году.

Исторически многие программные решения были написаны только на ассемблере. ОС писались исключительно на этом языке до введения Burroughs MCP (1961 г.), который был написан на языке Executive Systems Problem Oriented Language (ESPOL). Многие коммерческие приложения были написаны на машинно-ориентированном языке, в том числе большое количество программного обеспечения мэйнфреймов IBM, созданного ИТ-гигантами. COBOL и FORTRAN в конечном итоге вытеснили большую часть наработок, хотя многие крупные организации сохранили ассемблерные прикладные инфраструктуры в 1990-х годах.

что такое двоичный код

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

Область применения

Языки сборки устраняют большую часть проблемного, утомительного и трудоемкого программирования на ассемблерах первого поколения, необходимого на самых ранних компьютерах. Это освобождает программистов от рутины в виде запоминания числовых кодов и вычисления адресов. На начальных этапах «сборщики» широко использовались для всех разновидностей программирования. Однако к концу 1980-х гг. их применение в значительной степени было вытеснено языками более высокого уровня в поисках повышения производительности программирования. Сегодня язык ассемблера по-прежнему используется для прямой аппаратной манипуляции, доступа к специализированным инструкциям процессора или для решения критических проблем с производительностью. Типичной областью применения являются драйверы устройств, низкоуровневые встроенные системы и параметры реального времени.

Образцы применения

Типичными примерами крупных программ на языке ассемблера являются операционные системы IBM PC DOS, компилятор Turbo Pascal и ранние приложения, такие как программа электронных таблиц Lotus 1-2-3.

коды операций

Машинно-ориентированный язык — основной язык разработки для многих востребованных домашних ПК 1980-х и 1990-х годов (таких как MSX, Sinclair ZX Spectrum, Commodore 64, Commodore Amiga и Atari ST). Это обусловлено тем, что интерпретированные диалоги BASIC на этих системах обеспечивали низкую скорость выполнения, а также ограниченные возможности для полного использования имеющегося оборудования. Некоторые системы даже имеют интегрированную среду разработки (IDE) с высокоразвитыми средствами отладки и макрообъектов. Некоторые компиляторы, доступные для Radio Shack TRS-80 и его преемников, имели возможность комбинировать встроенный источник сборки с программами высокого уровня. После компиляции встроенный ассемблер создал встроенный двоичный код.

Машинный код для чайников. Терминология

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

Машинные коды команд ассемблера также могут выполнять некоторые простые типы оптимизации, зависящей от набора команд. Одним из конкретных примеров этого могут быть популярные «сборщики» x86 от разных поставщиков. Большинство из них могут выполнять замены команд перехода в любом количестве проходов, по запросу. Также способны выполнять простую перегруппировку или вставку инструкций, таких как некоторые сборщики для архитектур RISC, которые могут помочь оптимизировать разумное планирование команд, чтобы максимально эффективно использовать конвейер CPU.

Подобно ранним языкам программирования, таким как Fortran, Algol, Cobol и Lisp, сборщики были доступны с 1950-х годов, как и первые поколения текстовых компьютерных интерфейсов. Однако сначала появились сборщики, поскольку их намного проще писать, чем компиляторы для высокоуровневых языков. Это связано с тем, что каждая мнемоника, а также режимы адресации и операнды инструкций транслируются в числовые представления каждой конкретной инструкции без большого контекста или анализа. Также был ряд классов переводчиков и полуавтоматических генераторов кода со свойствами, аналогичными как сборкам, так и языкам высокого уровня, причем скоростной код, возможно, является одним из наиболее известных примеров.

Количество проходов

Существует два вида программирования на ассемблере, основанные на количестве проходов через источник (по количеству попыток прочтения) для создания объектного файла.

машинный язык
Однопроходные ассемблеры проходят через исходный код один раз. Любой символ, используемый до его определения, потребует errata в конце объектного кода.
Многопроходные ассемблеры создают таблицы со всеми символами и их значениями в первых проходах, а затем применяют таблицу в последующих проходах для генерации кода.

Первоначальной причиной использования однопроходных сборщиков была скорость сборки — часто второй проход требовал перемотки и перечитывания источника программы на ленту. Более поздние компьютеры с гораздо большими объемами памяти (особенно для хранения дисков) имели пространство для выполнения всей необходимой обработки без повторного чтения. Преимущество многопроходного ассемблера заключается в том, что отсутствие ошибок приводит к тому, что процесс связывания (или загрузка программы, если ассемблер непосредственно создает исполняемый код) проходит быстрее.

Что такое двоичный код?

Программа, написанная на языке ассемблера, состоит из ряда мнемонических команд процессора и мета-операторов (известных как директивы, псевдо-инструкции и псевдооперации), комментарии и данные. Инструкции по языку ассемблера обычно состоят из мнемоники кода операции. За ней следует список данных, аргументов или параметров. Они переводятся ассемблером в инструкции машинного языка, которые загружаются в память и выполняются.

Например, приведенная ниже инструкция сообщает процессору x86/IA-32 переместить 8-битное значение в регистр. Двоичный код для этой команды — 10110, за которым следует 3-битный идентификатор, для которого используется регистр. Идентификатором AL является 000, поэтому следующий код загружает регистр AL с данными 01100001.

Возникает вопрос: что такое двоичный код? Это система кодирования с использованием двоичных цифр «0» и «1» для представления буквы, цифры или другого символа на компьютере или другом электронном устройстве.

Пример машинного кода: 10110000 01100001.

Технические особенности

Преобразование языка сборки в машинный код — это задание ассемблера. Обратный процесс выполняется с помощью дизассемблера. В отличие от языков высокого уровня существует взаимно однозначное соответствие между множеством простых операторов сборки и инструкциями машинного языка. Однако в некоторых случаях ассемблер может предоставлять псевдоинструкции (макросы). Они распространяются на несколько инструкций машинного языка для обеспечения обычно необходимой функциональности. Большинство полнофункциональных ассемблеров также предоставляют богатый макроязык, который используется поставщиками и программистами для генерации более сложных кодов и последовательностей данных.

программирование на ассемблере

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

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

Язык дизайна

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

  • мнемоника опкода;
  • определения данных;
  • директивы сборщика.

Мнемоника опкода и расширенная мнемоника

Инструкции, написанные на языке ассемблера, элементарны, в отличие от высокоуровневых языков. Как правило, мнемоника (произвольные символы) является символьным обозначением для одной исполняемой инструкции кода. Каждая команда обычно состоит из кода операции плюс ноль или более операндов. Большинство команд относятся к одному или двум значениям.

Расширенная мнемоника зачастую применяется для специализированной эксплуатации инструкций — для целей, не очевидных из названия мануала. Например, многие процессоры не имеют явной инструкции NOP, но имеют встроенные алгоритмы, которые используются для этой цели.

платформенно ориентированный код

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

Директивы данных

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

Директивы сборки

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

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

система команд

Самодокументирующийся код

Символьные ассемблеры позволяют программистам связывать произвольные имена (метки или символы) с ячейками памяти и разными константами. Зачастую каждой постоянной величине и переменной присваивается собственное имя, поэтому инструкции могут ссылаться на эти местоположения по имени, тем самым способствуя самодокументирующему коду. В исполняемом коде имя любой подпрограммы соотносится с ее точкой входа, поэтому любые вызовы подпрограммы могут использовать ее имя. Внутри подпрограмм назначаются метки GOTO. Многие сборщики поддерживают локальные символы, которые лексически отличаются от обычных символов.

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

Языки ассемблера, как и большинство других языков компьютера, позволяют добавлять комментарии к исходному коду программы, которые будут игнорироваться во время процесса сборки. Судебное комментирование имеет важное значение в программах ассемблерного языка, поскольку определение и назначение последовательности двоичных машинных команд трудно определить. «Необработанный» (без комментирования) язык ассемблера, созданный компиляторами или дизассемблерами, довольно сложно прочитать, когда необходимо внести изменения.

Статья закончилась. Вопросы остались?
Комментариев 1
Подписаться
Я хочу получать
Правила публикации
-1
Иди нахуй
Копировать ссылку
Редактирование комментария возможно в течении пяти минут после его создания, либо до момента появления ответа на данный комментарий.