Главная страница
Библиотека (скачать книги)
Скачать софт
Введение в программирование
Стандарты для C++
Уроки по C#
Уроки по Python
HTML
Веб-дизайн
Ассемблер в среде Windows
ActiveX
Javascript
Общее о Линукс
Линукс - подробно
Линукс - новое
Delphi
Паскаль для начинающих
Турбопаскаль
Новости
Партнеры
Наши предложения
Архив новостей





В этой программе выполняется умножение операндов, находящихся в 32- разрядных переменных ii и i2, а результат помещается в 64-битовую переменную ires, объявленную директивой DQ (учетверенное слово). Поскольку результат операции умножения возвращается в двух регистрах EDX И ЕАХ, ТО для его записи в ires используются команды
mov DWORD PTR ires, EAX ; младшая часть результата
mov DWORD PTR ires+4, EDX ; старшая часть результата

Для преобразования учетверенного слова в строку необходимо вызвать функцию wsprintf с четырьмя параметрами:
push DWORD PTR ires+4
push DWORD PTR ires
push offset lpFmt
push offset charBuf
call wsprintf
add ESP, 16

Напомню, что функция wsprintf может принимать переменное число параметров за счет того, что третий параметр имеет переменную длину. Так как параметры помещаются в стек в виде двойных слов, то для передачи параметра длиной в учетверенное слово потребуется два двойных слова, что и сделано в фрагменте кода. Соответственно, для восстановления стека необходимо удалять 16 байт с помощью команды:
add ESP, 16

В зависимости от результата выполнения команды mul соответствующим образом устанавливаются флаг переноса CF И флаг переполнения OF. ЕСЛИ оба флага равны 0, то значение старшей части результата равно 0. Если флаг переноса установлен в положение 1, то результат размещается в обоих регистрах.
Для умножения чисел со знаком применяется команда imui. Выполняется она аналогично команде mul, единственным отличием является то, что формируется знаковый бит результата. Если флаг переноса и флаг переполнения равны 0, то содержимое старшего регистра результата является расширением знакового бита младшего регистра. Если оба флага устанавливаются в 1, то, в зависимости от разрядности результата, это означает следующее:

- 16-разрядный результат операции расширил знак в регистр АН;
- 32-разрядный результат расширил знак в регистр DX;
- 64-разрядный результат расширил знак в регистр EDX.

Операцией, противоположной умножению, является деление. Как и в случае умножения, существуют две команды деления — div (для двоичных чисел без знака) и idiv (для чисел со знаком). Любая из этих команд деления работает с байтами, словами и двойными словами.

Команда деления div выполняет деление 8-, 16- и 32-разрядных чисел без знака. В зависимости от размера делимого и делителя получаются следующие результаты:
• если делитель — 8-разрядное число, то делимое помещается в регистр АХ, частное — в регистр AL, а остаток — в регистр АН;
• если делимое является 32-разрядным числом, то оно помещается в регистры DX:AX (в DX — старшая часть, в АХ — младшая). Частное помещается в регистр АХ, а остаток — в регистр DX;
• если делитель — 32-разрядное число, то делимое помещается в регистры EDX : ЕАХ, частное — в регистр ЕАХ, остаток — в регистр EDX.

Ни один из флагов состояния не определен после команды деления. Если частное больше, чем может быть помещено в регистр результата, результат будет неправильным. При делении байтов частное должно быть меньше 256, а при операции со словами — меньше 65 535. Процессор не устанавливает никаких флагов, сигнализирующих о такой ошибке, вместо этого выполняется программное прерывание с вектором 0.
Команда деления целых чисел со знаком idiv отличается от команды div только тем, что она учитывает знаки обоих операндов. В случае положительного результата команда аналогична команде div, за исключением того, что максимальное значение частного соответственно равно 127 и 32 767 для байтов и слов. Если результат отрицателен, частное усекается, а остаток имеет тот же знак, что и делимое. Минимальные значения частных для отрицательных результатов — —128 и —32 768 для байтов и слов.
При выполнении деления со знаком возникает проблема в случае, если делимое — байтовый операнд. Когда возникает необходимость разделить байтовое значение на байтовое, команда деления требует, чтобы делимое было 16-разрядным и занимало регистр АХ. Эту проблему можно решить, применив команду преобразования байта в слово cbw. При этом из регистра AL берется число и расширяется его знак в регистр АН. Команда cbw загружает в регистр АХ 16-битовое число, равное значению байта в регистре AL. Команда cwd выполняет аналогичную функцию для преобразования слова в двойное слово, расширяя знак слова из регистра АХ В регистр DX. ЭТИ две команды расширяют операнды до выполнения целого деления со знаком.
Для варианта целого деления без знака при тех же условиях знак не нужен, и его не надо расширять в старшую часть делимого. В этом случае можно просто обнулить регистр АН ИЛИ DX перед делением.


 
 
 

Библиотека программиста. 2009.
Администратор: admin@programmer-lib.ru