Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Магда Юрий - Ассемблер для процессоров Intel Pe...rtf
Скачиваний:
44
Добавлен:
01.07.2025
Размер:
565 Кб
Скачать
☆

3.3. Программная модель процессора Intel Pentium

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

– 8 регистров общего назначения, служащих для хранения данных и указателей;

– регистры сегментов – они хранят 6 селекторов сегментов;

– регистр управления и контроля EFLAGS, который позволяет управлять состоянием выполнения программы и состоянием (на уровне приложения) процессора;

– регистр‑указатель EIP выполняемой следующей инструкции процессора;

– система команд (инструкций) процессора;

– режимы адресации данных в командах процессора.

Начнем с описания базовых регистров процессора Intel Pentium.

Базовые регистры процессора Intel Pentium являются основой для разработки программ и позволяют решать основные задачи по обработке данных. Все они показаны на рис. 3.6.

Рис. 3.6. Базовые регистры процессора Intel Pentium

Среди базового набора регистров выделим отдельные группы и рассмотрим их назначение. Начнем с 32‑разрядных регистров общего назначения (ЕАХ, ЕВХ, ЕСХ, EDX, ESI, EDI, EBP, ESP), которые могут использоваться в качестве:

– операндов в арифметических и логических операциях;

– операндов при вычислении адресов операндов;

– указателей на переменные в памяти.

Несмотря на то что любой из этих регистров можно использовать для вышеперечисленных операций, необходимо учитывать специфику применения регистра ESP – он служит для хранения указателя стека, поэтому задействовать его для других целей не рекомендуется. Во многих программах требуется хранить в регистрах определенные значения операндов в процессе выполнения каких‑либо операций. Для этого подходят регистры ЕСХ, ESI и EDI. Если при этом используется отдельный сегмент данных, то некоторые команды ассемблера предполагают, что переменная, адресуемая одним из этих регистров, находится в сегменте данных, определяемом регистром DS.

Во многих случаях регистры общего назначения используются для предопределенных целей:

– ЕАХ выполняет функцию аккумулятора при работе с операндами и хранит результат операции;

– ЕВХ – указатель на данные, находящиеся в сегменте данных, адресуемом регистром DS;

– ЕСХ – счетчик циклов и элементов при строковых операциях;

– EDX – указатель на порты устройств ввода‑вывода;

– ESI – указатель на данные, находящиеся в сегменте, адресуемом регистром DS (при выполнении строковых операций содержит смещение строки‑источника);

– EDI – указатель на данные, находящиеся в сегменте, адресуемом регистром ES (при выполнении строковых операций содержит смещение строки‑приемника);

– ESP содержит указатель стека в сегменте стека, адресуемом регистром SS;

– ЕВР содержит указатель на данные, находящиеся в стеке, адресуемом регистром SS.

Младшие 16 бит 32‑разрядных регистров общего назначения могут адресоваться так же, как и 16‑разрядные регистры в процессорах 8086 с именами АХ, ВХ, СХ, DX, ВР, s1 , DI, SP. В свою очередь, 16‑разрядные регистры АХ, ВХ, СХ и DX позволяют обращаться отдельно как к старшим 8‑разрядным регистрам (АН, ВН, СН, DH), так и к младшим (AL, BL, CL, DL). Это проиллюстрировано рис. 3.7.

Сегментные регистры (CS, DS, SS, ES, FS и GS) содержат 16‑разрядные селекторы сегментов. Селектор представляет собой специальный указатель, который идентифицирует данный сегмент в памяти. Более подробно мы остановимся на использовании сегментных регистров в главе 4.

Рис. 3.7. Использование регистров общего назначения

Помимо регистров общего назначения и сегментных регистров, как мы знаем, в базовой архитектуре имеется еще два регистра: регистр управления/состояния EFLAGS и регистр‑указатель адреса следующей инструкции El Р. Рассмотрим их более подробно.

Регистр EFLAFS, часто именуемый регистром флагов, имеет 32 разряда и содержит группу битов или, как их чаще называют, флагов состояния, управляющий флаг и группу системных флагов. На рис. 3.8 показана структура регистра флагов и приводится расшифровка наиболее часто используемых флагов.

Рис. З.8. Регистр управления/состояния процессора

Указанные на рис. 3.8 флаги наиболее часто используются в прикладных программах и сигнализируют о следующих событиях:

– OF (флаг переполнения) фиксирует ситуацию переполнения, то есть выход результата арифметической операции за пределы допустимого диапазона значений;

– DF (флаг направления) используется командами обработки строк. Если DF = 0, строка обрабатывается в прямом направлении, от меньших адресов к большим. Если DF = 1, обработка строк ведется в обратном направлении;

– SF (флаг знака) показывает знак результата операции, при отрицательном результате SF = 1;

– ZF (флаг нуля) устанавливается в 1, если результат операции равен 0;

– AF (флаг вспомогательного переноса) используется в операциях над упакованными двоично‑десятичными числами. Этот флаг служит индикатором переноса или заема из старшей тетрады (бит 3);

– PF (флаг четности) устанавливается в 1, если результат операции содержит четное число двоичных единиц;

– CF (флаг переноса) показывает, был ли перенос или заем при выполнении арифметических операций.

Из всех этих флагов только флаг переноса CF может устанавливаться или сбрасываться непосредственно при помощи команд ассемблера stc, cl с и стс. Кроме того, в этот флаг может быть скопирован бит, определенный командами bt, bts, btr и btc.

Флаги состояния также используются при анализе операций, результатами которых являются беззнаковые целые числа, целые числа со знаком и упакованные (BCD) целые числа. Если результатом операции является беззнаковое целое число, то установка флага переноса CF в 1 (перенос или заем) свидетельствует о выходе за пределы допустимого диапазона. Если результатом операции является целое число со знаком (двоичное дополнение числа), то об этом свидетельствует установка в 1 флага переполнения OF.

В случае если результат операции интерпретируется как число в формате BCD, то установка флага AF свидетельствует о возникновении переноса или заема. Флаг SF указывает на знак результата, являющегося знаковым числом. Флаг ZF указывает на равенство нулю знакового или беззнакового числа.

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

Флаги состояния используются командами условного перехода jCC (CC – код условия: eq, le, It, ne и т. д.), командами setСС, ТоорСС и cmovCC.

Флаги состояния процессора могут быть помещены в стек и извлечены из стека командами pushf, pushfd, popf, popfd. Кроме того, флаги могут быть загружены в старшую половину регистра АХ или извлечены из старшей половины при помощи команды lahf или sahf.

Перейдем к описанию регистра EIP – он содержит смещение в программном сегменте следующей выполняемой команды. Если в программе встречаются команды jCC, call, ret или iret, то содержимое регистра EIP может измениться произвольным образом – смещение следующей команды может быть как положительным, так и отрицательным. Содержимое регистра‑указателя следующей команды не может быть изменено какой‑либо инструкцией напрямую, хотя можно получить его содержимое, если выполнить команду call, а затем прочитать указатель на следующую команду, находящийся в стеке.

Регистр EIP можно модифицировать, опять‑таки не прямо, а через стек, заменив адрес следующей команды. Естественно, перед этим следует выполнить команду call.

Прежде чем приступить к анализу команд ассемблера и способов обработки данных, нам необходимо рассмотреть модели памяти, с которыми может работать процессор. Модель памяти определяет способ организации программ и данных в памяти компьютера. В 32‑разрядной архитектуре процессора Intel Pentium используются три модели памяти:

– плоская, или линейная, модель памяти (flat memory model) – память представляет собой непрерывное пространство адресов. Такое пространство адресов называется линейным. Программный код, данные, область стека располагаются в этом пространстве адресов. Адресное пространство в этой модели адресуется побайтно, а диапазон адресов равен 232. Схематично эта модель памяти показана на рис. 3.9;

Рис. 3.9. Линейная модель памяти

– сегментированная модель памяти (segmented memory model) – память состоит из трех отдельных пространств адресов, которые называются сегментами. При этом программный код, данные и стек размещаются в отдельных сегментах памяти. Для того чтобы обратиться к байту в памяти, программа формирует логический адрес, состоящий из адреса сегмента (селектора сегмента) и смещения. Программы, выполняющиеся в 32‑разрядном режиме, могут использовать до 16 383 сегментов разного размера, каждый из которых может иметь размер 232 байт. Схема адресации для сегментированной модели памяти показана на рис. 3.10.

Рис. 3.10. Сегментированная модель памяти

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

– модель реального режима адресации (real‑address mode memory model) – это модель памяти, используемая в процессорах 8086. Данная модель памяти поддерживается для того, чтобы обеспечить совместимость с ранее разработанными 16‑разрядными приложениями. В этой модели применяется механизм сегментации, причем максимальный размер сегмента не превышает 64 Кбайт. Максимальный размер линейного адресного пространства, доступного в этом режиме, равен 220 байт.

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

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

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

Для четкого понимания того, как осуществляется адресация данных, проанализируем способ образования адреса операнда. Адрес операнда формируется по схеме сегментхмещение. В зависимости от используемой модели памяти адрес переменной в памяти может формироваться как 16 : 16 или 16 : 32. Смещение операнда называется его эффективным или исполнительным адресом (Effective Address, EA).

Селектор сегмента можно указать явным или неявным образом. Обычно селектор сегмента загружается в сегментный регистр, а сам регистр выбирается в зависимости от типа выполняемой операции, как показано в табл. 3.2.

Таблица 3.2. Критерии выбора сегментного регистра

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

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

mov ES:[ЕВХ]. ЕАХ

Обратите внимание на то, что после имени сегмента указывается символ двоеточия.

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

– для сегмента программного кода – все команды используют исключительно сегментный регистр CS;

– при выполнении строковых операций строка‑приемник адресуется только регистром ES;

– операции помещения в стек и извлечения из стека всегда используют регистр SS.

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

mov DS. BX

Здесь селектор сегмента, находящийся в регистре ВХ, помещается в сегментный регистр DS. В некоторых случаях селектор сегмента может определяться через 48‑разрядный указатель, находящийся в памяти. При этом младшее двойное слово содержит 32‑разрядное смещение, а старшее слово – 16‑разрядный селектор сегмента.

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

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

– смещения, представляющего собой 8‑, 16– и 32‑разрядное значение;

– базы, представляющей собой содержимое одного из регистров общего назначения;

– индекса, представляющего собой содержимое одного из регистров общего назначения;

– масштабного множителя, равного 2, 4 или 8.

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

Рис. 3.11. Схема вычисления эффективного адреса (ЕА)

Существуют определенные ограничения, касающиеся применения регистров общего назначения в качестве базовых или индексных при формировании эффективного адреса:

– регистр ESP нельзя использовать в качестве индексного регистра;

– если в качестве базового используется регистр ESP или ЕВР, то сегментным регистром будет SS. Во всех остальных случаях сегментным регистром по умолчанию является DS.

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

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

mov AX. menu

Здесь meml – операнд в памяти. Как операнд‑источник, так и операнд‑приемник должны иметь одинаковый размер, иначе в процессе компиляции будет выдана ошибка. Так, в нашем примере подразумевается, что переменная meml определена как слово. Если, например, операнд в памяти является двойным словом, то в команде нужно явным образом указать старшую или младшую часть с помощью оператора PTR:

mov AX. word ptr meml

Предположим, что переменная meml определена как двойное слово. Тогда показанная ранее команда поместит в регистр АХ значение lD7Fh (рис. 3.12).

Рис. 3.12. Размещение переменной meml в памяти

Если нужно сохранить в регистре АХ значение старшего слова переменной meml, то следует применить команду

mov AX, word ptr meml+2

В этом случае в регистр АХ помещаются старшие два байта переменной meml (см. рис. 3.12), после чего АХ будет содержать значение 0EC34h (обратите внимание на порядок расположения байтов!).

Остановимся более подробно на операторе PTR. В общем случае этот оператор можно представить в виде

тип PTR выражение

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

Таблица 3.3. Атрибуты оператора PTR

Выражение может включать в себя любые операнды. Типы BYTE, WORD, DWORD, QWORD и TWORD могут быть использованы только с операндами памяти, а типы NEAR и FAR – только с метками. Если PTR не используется, то ассемблер подразумевает умалчиваемый тип ссылки. Кроме того, оператор PTR служит для организации доступа к объекту, который при другом способе привел бы к ошибке компиляции (например, для доступа к старшему байту переменной размера WORD).

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

Рассмотрим пример программного кода

lea BX. meml

mov AX. [BX]

В этом примере meml – переменная в памяти размером в слово. Первая команда загружает адрес переменной в регистр BX, a вторая помещает в регистр АХ значение, содержащееся по адресу, который находится в ВХ. Работу этого фрагмента кода иллюстрирует рис. 3.13.

Рис. 3.13. Схема косвенной адресации

Предположим, что переменная meml размером в слово имеет значение 1A9Fh и занимает два байта в памяти с адресами 1CD6h (младший байт) и 1CD7 (старший байт). После выполнения первой команды в регистре ВХ будет находиться адрес переменной meml, являющийся одновременно и адресом первого элемента. Вторая команда помещает в регистры АХ значение переменной meml.

Вариант 3. Для формирования эффективного адреса операнда используется содержимое базового регистра плюс смещение («база + смещение»). Такой вариант адресации удобен в двух случаях:

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

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

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

[база + смещение]

[база][смещение]

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

. . .

s1 DB «String 1»

. . .

lea EBX. s1

mov AL. byte ptr [EBX][5]

. . .

Здесь первая команда (lea EBX, sl) помещает в регистр EBX адрес строки, который одновременно является и адресом первого элемента (имеющего индекс 0). Во время выполнения второй команды к содержимому регистра ЕВХ прибавляется значение 5, указывая на 6‑й по порядку элемент строки s1 (это символ g), после чего значение этого символа помещается в регистр AL. Таким образом, после выполнения второй команды регистр a1 будет содержать символ д. Алгоритм выполнения этого фрагмента программного кода показан на рис. 3.14.

Рис. 3.14. Схема базовой адресации

Вариант 4. В следующем режиме эффективный адрес формируется по принципу «индекс + смещение». Смещение при таком способе адресации указывает на начало массива чисел или строки, а индексный регистр содержит номер элемента данных. Например, в показанном ниже фрагменте программного кода в регистр a1 помещается элемент строки s1 с индексом 10 (11‑й элемент строки, символ +):

. . .

s1 DB «!@#$Г&*()+][»

. . .

mov EBX. 10

mov AL. byte ptr s1 [EBX]

. . .

Вариант 5. В следующем режиме эффективный адрес формируется по принципу «(индекс х множитель) + смещение». Множитель обычно используется для доступа к элементам, имеющим размер, кратный 2, например к словам, двойным словам и т. д. Смещение при таком способе адресации указывает на начало массива чисел или строки, а индексный регистр содержит номер элемента данных. Далее показан пример, который демонстрирует этот способ адресации:

. . .

s1 DB «0123456789ABCDEF»

. . .

mov EBX. 7

mov AL. byte ptr s1 [EBX*2]

. . .

При указанном значении регистра ЕВХ в регистр a1 будет помещен символ Е, поскольку он находится по смещению 14 (7 х 2) в строке si.

Вариант 6. В следующем режиме эффективный адрес формируется по принципу «база + индекс + смещение». Такой способ адресации обычно используется для адресации элементов в двухмерных массивах данных или для доступа к отдельным элементам в массивах, содержащих записи. Проанализируем фрагмент программного кода, в котором применяется данный способ адресации:

. . .

s1 DB «ABCD EFGH IJKLM»

s2 DB «abcd efgh ijklm»

s3 DB «0123 4567 89»

sarray label dword

DD s1

DD s2

DD s3

. . .

mov EBX, sarray+4

mov ESI. 10

mov AL. byte ptr [EBX][ESI][2]

. . .

Здесь в сегменте данных определен массив строк sarray, содержащий адреса строк s1 – s3. В каждой строке определены группы элементов, разделенные символом пробела. Предположим, нужно получить доступ к символу к, находящемуся в строке s2. Будем использовать регистр ЕВХ как базовый, а регистр ESI как индексный. Поместим в ЕВХ адрес строки s2, где находится искомый элемент (команда mov ЕВХ, sarray+4), а в регистр ESI – смещение группы элементов, в которой находится символ к (величина смещения в данном случае равна 10). Для этого выполним команду

mov ESI. 10

Символ к находится по смещению 2 относительно группы элементов ijklm, поэтому последняя команда помещает символ в регистр AL:

mov AL. byte ptr [EBX][ESI][2]

Вариант 7. В последнем режиме эффективный адрес формируется по принципу «база + (индекс х множитель) + смещение». Такой способ адресации обычно требуется для адресации элементов в двухмерных массивах данных, когда нужно получить доступ к словам, двойным словам или учетверенным словам. Проанализируем фрагмент программного кода, в котором применяется данный способ адресации:

. . .

al DD 45, ‑87, 23, ‑11, 83, ‑442, 56, ‑340

а2 DD 92, ‑31, 9, ‑598, 361, 406, ‑172, 7

аЗ DD 234, 8, ‑177, 921, 380, ‑12, 0, ‑51

iarray label dword

DD a1

DD a2

DD a3

. . .

mov EBX. iarray+8

mov ESI. 4

mov EAX. [EBX][ESI*2][8]

Здесь определены три массива целых чисел (a1 – аЗ), состоящих из двухсловных элементов. Предположим, требуется поместить число 380 (выделенное жирным шрифтом) в регистр ЕАХ. Для этого воспользуемся несколько искусственной схемой, которая поможет понять суть этого метода адресации.

В регистр ЕВХ поместим адрес массива аЗ (команда mov EBX, iarray+8), в котором находится искомое число. Таким образом, регистр ЕВХ будет использоваться как базовый. Регистр ESI будет выступать в качестве индексного, куда мы поместим значение 4 (размер двойного слова в байтах) с помощью команды

mov ESI. 4

Наконец, последняя команда загружает искомый элемент массива аЗ (380) в регистр ЕАХ:

mov EAX. [EBX][ESI*2][8]

В этой команде выражение [ESI*2], равное 8, указывает на элемент массива аЗ с индексом 2 (то есть число ‑177), а выражение [8] определяет смещение на 8. В результате суммирования всех значений (ЕВХ, ESI, 8) получаем эффективный адрес (ЕА) искомого элемента.

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

Хочу сделать важное замечание: все семь рассмотренных вариантов адресации проверены на компиляторе MASM версии 7.10 из пакета Windows XP DDK.

Рассмотрим еще один способ адресации данных в памяти, который используется в ряде случаев и называется непосредственной адресацией. При этом способе адресации операнд задается непосредственно в инструкции. Например, следующая команда вычитает значение 20 из регистра ЕАХ:

sub ЕАХ, 20

Все арифметические команды, за исключением команд dпv и idiv, допускают непосредственную адресацию. Максимальное значение непосредственного операнда варьируется для разных команд, однако в любом случае не может превышать значения, которое может принимать операнд размером в двойное слово без знака (232).

Последний способ адресации, который мы проанализируем, – регистровая адресация. При регистровой адресации операнд находится в регистре общего назначения, а в некоторых случаях – в сегментном регистре. Если команда имеет два операнда, то в большинстве случаев они могут быть регистрами. Вот примеры регистровой адресации:

mov EAX. EDX

add EAX. ECX

Оба операнда должны иметь одинаковую размерность. Следующая команда вызовет ошибку:

mov EAX. BL

Здесь оба операнда – регистры ЕАХ и BL – имеют разную размерность, поэтому компилятор выдаст ошибку при трансляции этой команды.

Рассмотрим вкратце команды общего назначения процессора Intel Pentium. Более детальный анализ всех групп команд мы будем проводить в следующих главах, когда будут рассматриваться практические аспекты применения языка ассемблера. Команды общего назначения (general‑purpose instructions) по функциональному признаку можно разделить на несколько групп:

– команды перемещения (пересылки, передачи) данных;

– команды целочисленной арифметики (сложения, вычитания, умножения и деления);

– команды логических операций;

– команды передачи управления (условных и безусловных переходов, вызовов процедур);

– команды строковых операций (иногда встречается название «строковые, или цепочечные, команды»).

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

Большинство команд работают с операндами в памяти, адресуемыми одним из способов, рассмотренных ранее, а также с регистрами общего назначения (ЕАХ, ЕВХ, ECX, EDX, ESI, EDI, EBP, ESP) и с регистрами сегментов (CS, DS, SS, ES, FS, GS).

Макроассемблер MASM версии 6.14 и выше поддерживает все основные команды процессора Intel Pentium, а также специальные группы команд ММХ‑, SSE– и SSЕ2‑расширений, которые подробно рассматриваются в последующих главах. Перечень всех команд процессора приводится в приложениях А и Б.