Иллюстрированный самоучитель по Assembler

Использование средств 32-разрядных процессоров в программировании

Рассмотрим некоторые детали приведенного примера.

Три ячейки для хранения заданного времени (часов, минут и секунд) объявлены оператором dd, как двойные слова для упрощения программы и ускорения загрузки этих значений в расширенный регистр ЕАХ. Если бы мы, экономя память, отводимую по данные, объявили бы эти ячейки как байты, то загрузка, например, числа часов в регистр ЕАХ выглядела бы следующим образом:

xor EAX,EAX
mov AL,hour

Для преобразования часов в секунды мы должны число часов умножить на 3600. Оба сомножителя (3600 и максимум 23) представляют собой небольшие числа, которые поместились бы в 16-разрядный регистр. Однако результат может достигнуть величины 82800, которая в регистр АХ уже не поместится. Если бы мы выполнили умножение двух 16-разрядных регистров, например, АХ на ВХ, то результат (по правилам выполнения команды mul) оказался бы в паре регистров DX:AX, и нам пришлось бы эти два числа объединять в одно несколькими операциями переноса и сдвига:

push AX; Сохраняем на время АХ
mov AX,DX; Старшая половина произведения
sal ЕАХ,16; Сдвигаем в старшую половину ЕАХ
pop AX; Младшая половина произведения

Выполняя умножение с использованием 32-разрядных регистров, мы получаем результат опять же в паре регистров EDX:EAX, но поскольку в нашем случае произведение никогда не превысит 4 Г, все оно целиком будет находиться в одном регистре ЕАХ, и мы избавляемся от приведенной выше процедуры. Результат умножения сохраняется во вспомогательной ячейке temp.

Аналогичным образом выполняется перевод числа минут в секунды; полученный результат прибавляется к содержимому ячейки temp.

Число секунд преобразовывать не надо, оно просто прибавляется к содержимому temp.

Полученное число секунд умножается на 18, и результат помещается в ячейку time, которая затем будет опрашиваться в обработчике прерываний.

К полученному числу тактов таймера надо прибавить еще две корректирующих величины – результаты деления числа секунд на 5 и на 154. При использовании в операции деления 32-разрядных регистров делимое помещается в пару регистров EDX:EAX. В нашем случае делимое целиком помещается в ЕАХ, и регистр EDX необходимо обнулить. Для этого можно было выполнить команду: mov ЕАХ,0 но более эффективна операция: хоr ЕАХ,ЕАХ которая при любом содержимом ЕАХ оставляет в нем 0.

При делении EDX:EAX на ЕВХ частное помещается в ЕАХ, остаток в EDX. Остаток нас не интересует, а частное (первая корректирующая величина) прибавляется к содержимому ячейки temp.

Аналогичным образом то же число секунд из ячейки tmp делится на 154, и результат прибавляется к содержимому time.

Преобразование закончено.

В заключение рассмотрим пример упорядочивания массива 32-разрядных чисел в убывающем порядке методом пузырьковой сортировки. В приведенном алгоритме используются расширенные возможности адресации 32-разрядных процессоров.

Если Вы заметили ошибку, выделите, пожалуйста, необходимый текст и нажмите CTRL + Enter, чтобы сообщить об этом редактору.