- •6. Лекция. Язык программирования ассемблер ia-32 (Intel Architecture -32bit)
- •6. Язык программирования ассемблер ia-32
- •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(исходный)
- •Imul src и mul src
- •Idiv src и div 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. Управление потоком выполнения программы
Существует два способа отклонения программы от «прямолинейного курса». Первый из них (о нем рассказывается в разделе 5.8) — это вызов подпрограммы и возврат из нее. Кроме того, в программе могут выполняться переходы к заданным командам — как условные, так и безусловные. О них мы сейчас и поговорим.
6.3.1. Условные переходы и флаги кодов условий
Представленная на рис. 5.8, команда
JG STARTADD
относится к числу команд условного перехода. Условие «больше нуля» задается в ней суффиксом кода операции G. Это условие касается и результата последней выполненной команды обработки данных, которой в нашем примере была команда
DEC ECX
Признаки результатов, которые генерируются командами типа Decrement и Add, выполняющими арифметические операции и операции сравнения, записываются в четыре флага кодов условий в регистре состояния процессора, показанном на рис. 5.2. В зависимости от результата операции эти флаги, называемые SF (sign — знак), ZF (zero — нуль), OF (overflow — переполнение) и CF (carry — перенос), устанавливаются в 1 или очищаются нулем. Но существует одно исключение. В операции вычитания бит CF устанавливается в 1, если перенос не выполняется, что соответствует сигналу обратного переноса. Состояние этих флагов можно проверить в последующих командах условного перехода, с тем чтобы решить, следует ли осуществлять переход. В нашем примере при выполнении условия [ECX] > 0 управление передается команде, записанной по целевому адресу STARTADD.
В команде условного перехода задается не абсолютное значение целевого адреса перехода, а число со знаком, которое прибавляется к содержимому регистра указателя команды, то есть целевой адрес задается относительно адреса в указателе команды. Значение указателя команды увеличивается сразу после выборки очередной команды, поэтому он всегда определяет следующую выполняемую команду программы. Когда к указателю прибавляется относительный адрес перехода, он начинает указывать на команду, следующую за командой перехода. Предположим, что адрес STARTADD в нашем примере равен 1000. Для кодирования команд ADD, INC, DEC и JG из программы на рис. 5.8, а требуется 7 байт. Обновленное содержимое регистра указателя команды EIP будет равно 1007, то есть адресу последней в программе команды MOV. Таким образом, относительное расстояние до целевой команды перехода составляет -7; именно данное значение и содержится в команде условного перехода. Это маленькое отрицательное число можно представить одним байтом. Поэтому, с учетом байта кода операции, для записи команды условного перехода достаточно 2 байт. Такой размер имеют команды перехода, в которых относительный адрес перехода лежит в диапазоне от -128 до +127. Если же расстояние до целевой команды перехода больше, то используется 4-байтовое смещение.
В этом примере проверяется значение в регистре ЕСХ — нас интересует, больше ли оно нуля. Другие свойства результата можно проверить при помощи иных команд условного перехода. Например, если результат равен нулю, переход выполняется командой JZ (или JE), а если знак результата отрицателен (знаковый бит равен 1) — командой JS.