- •6.1. Структура программы на языке ассемблер
- •6.2. Директивы языка ассемблера ia-32
- •6.2.1. Псевдокоманды определения переменных
- •6.2.2. Организация программы
- •6.3. Управление потоком выполнения программы
- •6.3.1. Условные переходы и флаги кодов условий
- •6.3.2. Команды сравнения
- •6.3.3. Безусловный переход
- •6.4. Логические команды, команды сдвига и циклического сдвига
- •6.4.1. Логические операции
- •6.4.2. Операции сдвига и циклического сдвига
- •6.4.3. Программа упаковки цифр
- •6.5. Другие команды
- •6.5.1. Вычитание
- •6.5.2. Команды умножения и деления
- •Imul reg,src(исходный)
- •6.5.3. Команды мультимедийного расширения
- •6.5.4. Векторные команды
- •6.6. Подпрограммы
- •6.6.1. Вложенность подпрограмм и стек процессора
- •6.6.2. Организация стека
- •6.6.3. Передача параметров
- •6.7. Примеры программ
- •6.7.1. Программа для вычисления скалярного произведения двух векторов
- •6.7.2. Программа сортировки байтов
- •6.7.3. Подпрограммы для вставки и удаления элементов связного списка
- •6.8. Различия между программами в ехе - и сом - файлах
- •6.8.1. Пример программы типа сом
- •6.8.2. Пример программы типа ехе
6.4.3. Программа упаковки цифр
В качестве простого примера использования указанных команд давайте рассмотрим программу упаковки цифр. Код этой программы для процессоров 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 разряда) точностью.