Команда MOV - основная команда пересылки данных, которая пересылает байт или слово данных из памяти в регистр, из регистра в память, или из регистра в регистр. Команда MOV может также занести число, определенное программистом, в регистр или в память.
В действительности команда MOV - это целое семейство машинных команд микропроцессора 8088. Таблица, в которую сведены варианты всех машинных команд микропроцессора 8088, приведена в приложении А. Беглый просмотр этой таблицы показывает, что существует семь различных вариантов команды MOV, но программист использует каждую из этих команд с помощью единого названия операции MOV. Ассемблер порождает правильную машинную команду, основываясь на типах операндов, которые написал программист; и это одна из причин, по которой ассемблер требует для операндов назначения типов, т.е. ассемблер должен знать, что представляет собой каждый операнд - регистр, байт памяти, слово памяти, сегментный регистр, или что-нибудь еще. Такое назначение типов позволяет ассемблеру построить правильную машинную команду. В случае использования команды MOV ассемблер должен решить, какой из семи вариантов является подходящим, основываясь на операндах, написанных программистом.
На рис.4.1 представлены различные способы, которыми в микропроцессоре 8088 можно переслать данные из одного места в другое. Каждый прямоугольник означает здесь регистр или ячейку памяти. Стрелки показывают пути пересылки данных, которые допускает набор команд микропроцессора 8088. Основной путь - из памяти в регистры и наоборот. С данными, помещенными в регистры, можно работать с большей эффективностью, чем с данными в памяти, так как микропроцессор не делает обращения к памяти всякий раз, когда нужны данные. Кроме того, все команды микропроцессора 8088 могут указать только один операнд памяти. Поэтому, например, команда сложения ADD требует, чтобы по крайней мере один из операндов был в регистре. Микропроцессор 8088 не имеет возможности сложить одну ячейку памяти с другой с помощью одной команды.
В самой команде MOV может содержаться новое содержимое регистра. Такая форма операнда называется непосредственным операндом; данные находятся в самой команде и не требуют вычисления адреса. Вы можете рассматривать эту форму адресации как специальный тип, при котором операнд находится в самой команде, а не где-то в другом месте памяти или в регистре. Кроме команд пересылки, у микропроцессора 8088 есть и команды обработки данных с непосредственным операндом.
Из рис.4.1 также ясно, что команда может переслать непосредственные данные в регистр или ячейку памяти. Записывать информацию в команду бессмысленно, так что поток данных для команды с непосредственным операндом имеет одно направление.
Наконец, команда MOV может записать сегментный регистр в память или регистр. Она может также загрузить сегментный регистр из памяти или из другого регистра. Однако не существует команды загрузки сегментного регистра данными с непосредственным операндом; это означает, что загружать сегментный регистр такими данными непроизводительно. Если в программе необходимо поместить известное значение в сегментный регистр, нужно сначала записать это значение в один из регистров или в ячейку памяти, а затем можно уже пересылать это значение в сегментный регистр. На рис.4.2 показано, как это сделать.
На рис.4.2 изображен листинг ассемблера некоторых возможных вариантов команды MOV. Единственная команда ассемблера MOV порождает несколько различных машинных команд.
Рассматривая рис.4.2, обратите внимание на синтаксис команды MOV. Команда MOV имеет два операнда: источник и результат. В команде они следуют друг за другом, источник следует за результатом. Первая команда на рисунке MOV AX,BX пересылает содержимое регистра BX в регистр AX. Следующая команда обратна предыдущей, содержимое регистра AX пересылается в регистр BX. Команда MOV не меняет источник, т.е. команда
MOV AX,BX
меняет регистр AX, результат, но не меняет регистр BX, источник.
Никакие из команд MOV не меняют флагов состояния. Хотя иногда это кажется неудобным, но является наилучшим способом работы с флагами. Как мы увидим далее, микропроцессор 8088 имеет команды, которые могут эффективно проверить любую ячейку памяти так, что команда пересылки не потребуется. В качестве примера случая, когда установка флагов при пересылке не нужна, рассмотрим арифметику повышенной точности. Когда программа выполняет вычисления повышенной точности, она должна переслать части операндов в регистры, чтобы расположить их там для выполнения операции. Такая пересылка не меняет ни одного флага, а это позволяет флагам обслуживать арифметику повышенной точности.
Как было замечено, существует несколько различных вариантов команд пересылки на машинном языке. Объектный код на рис.4.2 иллюстрирует эти варианты. Если вас интересует структура машинного языка, вы можете сравнить объектный код с описанием машинного языка в приложении А. Такое сравнение поможет выяснить значение отдельных битов в машинном коде. Например, вы сможете увидеть значения данных с непосредственным операндом в командах. К счастью, для того, чтобы писать программы на ассемблере, вам не требуется точно знать, как работает ассемблер.
Если вы хотите достичь наибольшей возможной эффективности программ, вам надо изучить объектный код на рис.4.2. Число байтов команды непосредственно связано с количеством времени, необходимого для выполнения этой команды. Например, команда пересылки, которая берет непосредственное значение и посылает его в память, занимает 6 байт. Набор команд микропроцессора 8088 содержит несколько команд, оптимизированных для работы с аккумулятором AX либо AL. Использование этих команд поможет вам сэкономить время и место в программах, где это важно.
Последние две команды на рис.4.2 показывают, как занести непосредственное значение в сегментный регистр. Любой другой регистр, в примере это регистр AX, может временно содержать непосредственное значение перед его записью в сегментный регистр.
Есть и другие команды, которые переносят данные. Пример на рис.4.3 иллюстрирует эти команды.