В качестве простого примера использования указанных команд давайте рассмотрим программу упаковки цифр. Код этой программы для процессоров IA-32 вы видите на рис. 6.4. Два байта ASCII загружаются в регистры AL и BL Команда SHL сдвигает байт в регистре AL на четыре позиции влево, заполняя четыре освободившихся младших бита нулями. Посредством второго операнда этой команды задается количество разрядов, на которое должен быть сдвинут первый операнд. Команда AND очищает четыре старших бита второго байта, записывая в них нули. После этого 4-разрядные значения, представляющие BCD-коды чисел, объединяются командой OR в регистре AL, а затем сохраняются в памяти по адресу PACKED.
Рис. 6.4. Программа для процессоров IA-32, упаковывающая две цифры BCD в один байт
6.5. Другие команды
Мы рассмотрели лишь малую часть набора команд архитектуры IA-32. Еще несколько важных команд будут представлены ниже.
6.5.1. Вычитание
Команда SUB (вычитание), так же как и ADD выполняет вычитание байтов или слов, содержащих двоичные данные. Вычитание осуществляется в компьютере по методу сложения с двоичным дополнением: для второго операнда устанавливаются обратные значения битов и прибавляется 1, а затем происходит сложение с первым операндом. Во всем, кроме первого шага, операции сложения и вычитания идентичны.
Существует пять возможных комбинаций операндов: Примеры:
вычитание регистр – регистр SUB EAX,EBX;
вычитание память – регистр SUB NUMB,EBX;
вычитание регистр – память SUB EAX,NUMB;
вычитание регистр - непосредственное значение SUB EAX,100;
вычитание память - непосредственное значение SUB 100,EBX.
6.5.2. Команды умножения и деления
Кроме команд для сложения и вычитания целых чисел со знаком, описанных в разделе 5.5, в наборе команд IA-32 имеются команды для целочисленного умножения и деления, а также для выполнения арифметических операций над числами с плавающей запятой.
Имеются следующие команды умножения:
MUL – для умножения чисел без знака;
IMUL - для умножения чисел со знаком.
В общем случае в результате умножения двух 32-разрядных чисел получается произведение двойной длины, то есть 64-разрядное значение. Однако для многих приложений достаточно иметь результат одинарной длины, то есть 32-разрядное значение. В подобных ситуациях используются разные команды. Результат одинарной длины генерирует команда
IMUL REG,src(исходный)
помещающая 32-разрядное значение результата в регистр общего назначения REG. Исходный операнд может находиться либо в регистре, либо в памяти.
В случае результата двойной длины команды
IMUL src и MUL src
используют в качестве второго операнда регистр AL, AX или ЕАХ, в зависимости от размера исходного операнда, располагающегося либо в регистре, либо в памяти. Произведение двойной длины помещается в два регистра: старшая половина разрядов результата сохраняется в регистрах DH, DX или EDX, а младшая — в регистрax AL, AX или ЕАХ.
Команда для выполнения целочисленного деления имеет следующий формат:
IDIV src
Выполняет целочисленное деление со знаком AL, АХ или ЕАХ (в зависимости от размера источника) на источник (регистр или переменная) и помещает результат в AL, АХ или ЕАХ, а остаток — в АН, DX или EDX соответственно. Результат всегда округляется в сторону нуля, знак остатка всегда совпадает со знаком делимого, абсолютное значение остатка всегда меньше абсолютного значения делителя.
Числа с плавающей запятой имеют гораздо больший диапазон значений, чем целые числа, и используются в первую очередь для научных вычислений. В архитектуре IA-32 применяется полный набор арифметических операций с такими числами. Их операнды и результаты располагаются в регистрах с плавающей запятой, показанных на рис. 5.12. Поддерживаются два формата чисел: с одинарной (32 разряда) и двойной (64 разряда) точностью.
6.5.3. Команды мультимедийного расширения
Двухмерные графические и видеоизображения можно представить массивом, состоящим из большого количества точек. Цвет и яркость каждой точки, называемой пикселом, могут быть закодированы 8-битовым элементом данных. Обработка таких данных имеет две особенности. Во-первых, при обработке отдельных пикселов часто приходится выполнять очень простые арифметические и логические операции. Во-вторых, для некоторых приложений реального времени требуется исключительно высокая скорость вычислений. Сказанное касается и обработки аудиосигналов и речи, представляемых последовательностью отсчетов непрерывного аналогового сигнала, генерируемых через фиксированные промежутки времени.
Ускорить процесс обработки данных в приложениях обоих типов можно за счет разделения последовательности элементов данных (как правило, байтов или 16-разрядных слов) на маленькие группы, которые можно обрабатывать параллельно. В наборе команд IA-32 имеется множество таких, которые параллельно обрабатывают данные группами по 64 бита, называемыми четверными словами. (Четверное слово содержит восемь байт или четыре 16-разрядных слова.) Эти команды называются ММХ-командами или командами мультимедийного расширения (multimedia extension). Их операнды могут располагаться в памяти или в регистрах с плавающей запятой. Таким образом, эти регистры служат двойной цели:
в них могут храниться числа с плавающей запятой или операнды ММХ-команд. При использовании в командах ММХ регистры обозначаются как ММ0-ММ7.
Для пересылки 64-разрядных ММХ-операндов между памятью и регистрами ММХ используются специальные команды Move.
Команда
PADDB MMi,src
складывает соответствующие байты 8-байтовых операндов и помещает в регистр назначения восемь сумм. Исходный операнд может располагаться в памяти или в регистре ММХ, но операнд назначения обязательно должен находиться в регистре ММХ. Подобные команды имеются как для операций по вычитанию, так и для логических операций.
Типичной операцией, выполняемой в приложениях обработки сигналов, является свертка — умножение короткой последовательности отсчетов входных сигналов на константы, называемые весовыми коэффициентами, и сложение произведений для получения значения выходного сигнала. Подобные операции осуществляются с помощью специальной команды ММХ, объединяющей умножение и сложение. В ней используются 64-разрядные операнды ММХ, содержащие по четыре 16-разрядных элемента данных, представляющих отсчеты сигнала.
6.5.4. Векторные команды
В архитектуре IA-32 определен набор команд, предназначенных для выполнения арифметических операций над маленькими группами чисел с плавающей запятой. Команды SIMD (Single Instruction, Multiple Data — одиночный поток команд и множественный поток данных) полезны для векторных и матричных вычислений в научных приложениях. В терминологии Intel они называются командами потокового расширения SIMD (Streaming SIMD Extension, SSE). Эти команды обрабатывают составные операнды длиной 128 бит, состоящие из четырех 32-разрядных чисел с плавающей запятой. Для хранения этих операндов имеются 128-разрядные регистры (на рис. 5.1 не показаны). Двумя базовыми командами этой группы являются команды сложения и умножения. Они воздействуют на четыре соответствующие пары исходных 32-разрядных значений, которые находятся в составных 128-разрядных операндах, и помещают четыре отдельных результата в 128-разрядный операнд назначения.