Используются для работы с адресами (например, для организации массивов). Работают с индексным и базовым регистрами. Содержимое команды в процессе не меняется, изменяется содержимое индексного регистра.
внутренняя индексация (все указывается в самой команде: адрес и модификация)
внешняя индексация (предшествующая команда указывает на код модификации, а следующая - адрес индексного регистра).
загрузка начального значения индексного регистра
изменение индексного регистра (при изменении на произвольную величину требуется непосредственно указать где она находится)
проверка условия и окончание цикла
Язык ассемблера — язык программирования низкого уровня. Язык получил свое название от слова ассемблер (англ. assembler — сборщик) — названия транслятора (компилятора) c языка ассемблера. Язык ассемблера, в некоторых случаях, для краткости, называют «ассемблером» (а что-то связанное с ним — «ассемблерный»), но в общем случае это неправильно. Также, сам ассемблер (программу) никогда не называют «компилятором языка ассемблера» или «компилятором ассемблера» (разве что в редких случаях).
Команды языка ассемблера один в один соответствуют командам процессора и фактически, представляют собой удобную символьную форму записи команд и аргументов. Также, язык ассемблера обеспечивает связывание частей программы и данныx через метки, выполняемое при ассемблировании (для каждой метки высчитывается адрес, после чего каждое вхождение метки заменяется на этот адрес).
Поскольку системы команд микропроцессоров различаются, каждый процессор имеет свой набор команд на языке ассемблера и свои ассемблеры. Данная статья, в основном, касается особенностей языка ассемблера для процессоров Intel семейства x86.
Обычно программы или участки кода пишутся на языке ассемблера в случаях, когда разработчику критически важно оптимизировать такие параметры, как быстродействие (например, при создании драйверов) и размер кода (загрузочные сектора, программное обеспечение для микроконтроллеров и процессоров с ограниченными ресурсами, вирусы, навесные защиты).
Большинство современных компиляторов позволяют комбинировать в одной программе, код написанный на разных языках программирования. Это позволяет быстро писать сложные программы используя высокоуровневый язык, не теряя быстродействия в критических ко времени задачах, используя для них части написанные на языке ассемблера. Комбинирование достигается несколькими приемами:
Вставка фрагментов на языке ассемблера в текст программы (специальными директивами языка) или написание процедур на языке ассемблера. Способ хороший для несложных преобразований данных, но полноценного ассемблерного кода — с данными и подпрограммами, включая подпрограммы с множеством входов и выходов, не поддерживаемых высокоуровневыми языками, с помощью него сделать нельзя.
Модульная компиляция. Большинство современных компиляторов работают в два этапа. На первом этапе каждый файл программы компилируется в объектный модуль. А на втором объектные модули линкуются (связываются) в готовую программу.
Объектные файлы представляют собой блоки машинного кода и данных, с неопределенными адресами ссылок на данные и процедуры в других объектных модулях, а также список своих процедур и данных. Линкер собирает код и данные каждого объектного модуля в итоговую программу, вычисляет и заполняет адреса перекрестных ссылок между модулями. Также в процессе линковки происходит связывание программы со статическими и динамическими библиотеками (являющихся архивами объектных файлов).
Прелесть модульной компиляции состоит в том что каждый объектный модуль будущей программы может быть полноценно написан на своем языке программирования и скомпилирован своим компилятором (ассемблером).
Достоинства языка ассемблера
Максимально оптимальное использование средств процессора, использование меньшего количества команд и обращений в память, и как следствие — большая скорость и меньший размер программы
Использование расширенных наборов инструкций процессора (ММХ, SSE, SSE2, SSE3)
Доступ к портам ввода-вывода и особым регистрам процессора (в большинстве ОС эта возможность доступна только на уровне модулей ядра и драйверов)
Возможность использования самомодифицирующегося (в том числе перемещаемого) кода (под многими платформами эта возможность недоступна, так как запись в страницы кода запрещена, в том числе и аппаратно, однако в большинстве общедоступных систем из-за их врожденных недостатков имеется возможность исполнения кода содержащегося в сегменте (секции) данных, куда запись разрешена)