- •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.3.2. Команды сравнения
Условный переход в программах часто осуществляется в соответствии с результатом сравнения двух чисел. Команда Compare
CMP dst,src
выполняет операцию
[dst] - [src]
и на основе полученного результата устанавливает флаги кодов условий. При этом ни один из операндов не изменяется и первый операнд всегда сравнивается со вторым. Например, переход по условию «больше» выполняется в том случае, если операнд назначения dst больше исходного операнда src.
6.3.3. Безусловный переход
Команда безусловного перехода JMP всегда вызывает переход к команде по целевому адресу. В ней может быть задано короткое (1 байт) или длинное (4 байта) относительное смещение со знаком. Кроме того, как и в командах условного перехода, могут использоваться другие режимы адресации. Такая гибкость определения целевого адреса перехода может быть очень полезной. В каждой точке программы выполняется только одно из альтернативных вычислений. Предположим, что в специальной таблице в памяти начиная с адреса JUMPTABLE хранятся 4-байтовые адреса первой команды каждой из подпрограмм, представляющих возможные ветви программы. Если последовательно пронумеровать эти ветви как 0, 1, 2... и загрузить индекс выполняемой подпрограммы в регистр ESI, то переход к выбранной ветви может быть выполнен посредством такой команды с использованием индексной адресации со смещением:
JMP [JUMPTABLE + ESI*4]
6.4. Логические команды, команды сдвига и циклического сдвига
6.4.1. Логические операции
В архитектуре IA-32 имеются команды, выполняющие логические операции И, ИЛИ и Исключающее ИЛИ (END, OR, XOR). Это поразрядные операции с двумя операндами и записью результата по адресу назначения. Предположим, что в регистре ЕАХ содержится шестнадцатеричное значение 0000FFFF, а в регистре ЕВХ — значение 02FA62CA. Команда
AND EBX,EAX
очистит левую половину регистра ЕВХ, заполнив ее нулями, а правую его часть оставит без изменений. В результате в ЕВХ окажется значение 000062СА.
Кроме того, в архитектуре IA-32 имеется команда NOT, генерирующая логическое дополнение всех битов операнда, то есть заменяющая все единицы нулями, а все нули единицами.
6.4.2. Операции сдвига и циклического сдвига
При помощи операции логического или арифметического сдвига операнд может быть смещен влево или вправо на заданное количество разрядов. Формат команды сдвига таков:
КодОперации dst,count
где сдвигаемый операнд dst задается при помощи одного из стандартных адресных режимов, а количество разрядов сдвига count представляется 8-разрядным значением, либо задаваемым непосредственно в команде, либо содержащимся в 8-разрядном регистре CL. Существует четыре команды сдвига:
- SHL — логический сдвиг влево;
- SHR — логический сдвиг вправо;
- SAL — арифметический сдвиг влево (то же, что SHL);
- SAR — арифметический сдвиг вправо.
При внимательном рассмотрении представления двоичного числа, понятно, что сдвиг числа на один разряд влево эквивалентен его умножению на 2, а сдвиг на один разряд вправо — его делению на 2. Конечно, при сдвиге влево может произойти переполнение, а при сдвиге вправо может потеряться конец числа. Освобождающиеся в результате сдвига разряды устанавливаются в 0, а сдвигаемые за границу операнда разряды отмечаются с помощью флага переноса С, а затем удаляются. Устанавливать флаг С особенно удобно при выполнении арифметических операций с большими числами, занимающими больше одного слова. На рис. 6.2, а показан пример сдвига содержимого регистра R0 влево на два разряда. Команда логического сдвига вправо работает точно так же (рис. 6.2,6).
Еще одно важное наблюдение заключается в том, что при сдвиге вправо в освободившемся разряде должен быть повторен знаковый бит. Этим арифметический сдвиг вправо отличается от логического, в котором освобождающиеся разряды всегда заполняются нулями. Пример арифметического сдвига вправо (SAR) приведен на рис. 6.2, в. Арифметический сдвиг влево ничем не отличается от логического.
а
б
в
Рис. 6.2. Команды логического и арифметического сдвига: логический сдвиг влево, SHL R0,2 (а); логический сдвиг вправо, SHR R0,2 (б); арифметический сдвиг вправо, SAR R0,2 (в)
Существует также четыре команды циклического сдвига:
ROL - циклический сдвиг влево;
ROR - циклический сдвиг вправо;
RCL - циклический сдвиг влево с установкой флага CF;
RCR - циклический сдвиг вправо с установкой флага CF.
Компьютер поддерживает две версии циклического сдвига вправо и две версии циклического сдвига влево. В первой версии разряды операнда просто циклически сдвигаются, а во второй в сдвиге участвует еще и флаг CF. Примеры всех четырех операций циклического сдвига приведены на рис. 6.3.
Рис. 6.3. Команды циклического сдвига: влево без переноса, ROL R0,2 (a); влево с пере-носом, RLC R0,2 (б); вправо без переноса, ROR R0,2 (a); вправо с переносом, RRC R0,2 (г)