Основные группы команд и их краткая характеристика

 

Для упрощения процесса программирования на языке ассемблера используется мнемоническая запись команд микропроцессора (обычно в виде сокращений английских слов, описывающих действия в этой команде, например, команда jcxzявляется сокращением от словJump if СХ is Zero). Понятно, что запомнить такую мнемонику проще, чем байт Е3, соответствующий коду этой команды в программе. Формирование двоичных байтов, соответствующих тем или иным командам и данным, используемых в программе, осуществляется с помощью программы ассемблера.

Все команды микропроцессоров семейства i80х86 можно разбить на следующие группы:

1. Команды пересылки данных.

2. Арифметические команды.

3. Команды сдвига.

4. Логические команды.

5. Команды передачи управления.

6. Команды ввода/вывода.

7. Команды работы со строками.

8. Дополнительные команды.

Команды пересылки данных наиболее широко применяются в микропроцессорах и позволяют пересылать данные из/в регистры микропроцессора/ячейки памяти.

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

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

Логические команды так же рассматривают свои операнды в качестве набора битов и позволяют выполнять над ними различные логические (булевы) операции.

С помощью команд передачи управления можно изменять порядок выполнения команд в программе для организации ветвлений в программе, циклов, вызова подпрограмм и т.д.

Команды ввода/вывода осуществляют обмен информацией между программой и внешними устройствами.

Команды работы со строками могут выполнять ряд элементарных действий (пересылка, сравнение и т.п.) с массивами данных..

Способы адресации в архитектуре i80x86

 

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

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

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

 

Регистровая адресация

В качестве операндов (как приемников, так и источников) можно использовать внутренние регистры микропроцессора, как 8ми разрядные (АН, AL, ВН, BL, СН, CL, DH, DL), так и 16ти разрядные (АХ, ВХ, СХ, DX, SP, ВР, SI, DI). Кроме них в операциях пересылки можно использовать и сегментные регистры CS, SS, DS, ES.

 

Непосредственная адресация

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

 

Адресация ячеек памяти

Кроме регистров и констант в командах можно использовать ячейки памяти. Естественно, что они могут использоваться и как источник и как приемник данных.

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

 

Прямая адресация

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

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

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

 

Косвенная адресация

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

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

Для того, чтобы отличить косвенную адресацию от регистровой мнемоническое обозначение регистра заключается в квадратные скобки (например, использование записи ВХ обозначает использование соответствующего регистра в качестве операнда; запись [ВХ] – использование содержимого регистра в качестве смещения при вычислении адреса операнда).

При косвенной адресации использование того или иного регистра данных или индексного регистра неявно определяет соответствующий сегмент, однако сегментный регистр можно явно переопределить. В качестве регистра косвенной адресации для микропроцессора i8086 (и, естественно, всех остальных микропроцессоров этого семейства) можно использовать только регистры [ВХ], [SI], [DI], [ВР]. Для первых трех регистров их содержимое является смещением по отношению к сегменту данных (т.е. текущее значение сегментного регистра DS определяет вторую составляющую адреса). Для [ВР] используется сегмент стека (текущее содержимое сегментного регистра SS) при вычислении адреса.

 

Косвенная адресация по базе

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

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

В микропроцессорах i8086 в качестве базовых регистров используются только [ВХ] и [ВР]. При использовании регистра [ВХ] по умолчанию используется сегмент данных (сегментный регистр DX), а для [ВР] – сегмент стека (сегментный регистр SS). Размерность добавляемой константы может быть или байтом, или словом.