Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Asm: Общие вопросы > Интересно, а как производить арифметические


Автор: Ruterian 5.2.2004, 23:55
Возникла задача вычисления некого параметра на ASM. В частности, определить объем винта в Мб по формуле C*H*S*512/1024/1024:

3462h*0fh*3fh*200h/10000h=6187(DEC). Полученный результат ghtlcnfdbnm с точнотью до единиц Мб. Как наиболее правильно это сделать?

Автор: Ruterian 5.2.2004, 23:56
ghtlcnfdbnm = представить :-)

Автор: acp 6.2.2004, 00:39
Вообщем-то 6187 влезает в word двухбайтный. А div работает отлично и со словами, и с двойными словами.

Автор: Ruterian 6.2.2004, 20:52
acp

я и без такого "ответа" знаю, как работает DIV. Неужели вы думаете, что я тут от безделья спрашиваю, чтоб довольствоваться такими вот отписками??? http://www.graphics.com.ua/files/pauk.html?

Автор: oleg1973 6.2.2004, 21:17
Ruterian
не вижу проблемы
че ты 3 раза умножить и 1 раз поделить не можеш или че?
результат и будет с точностью до еденицы мб

Автор: Chingachguk 6.2.2004, 21:23
Проблема, как я понимаю, в том, что когда-то наступает момент, когда текущих разрядностей не хватает для новых данных ;)

Речь идет о целочисленном делении. Что мы имеем в cpu ?

1. 32-х битное деление dx:ax на [делитель]. Причем целое от деления должно влезть в ax.

2. 64-х битное edx:eax на [делитель 32]. То же самое, но числа гораздо больше. Можно смело использовать в дос с ключом .386

3. Регистры MMX. Сам не работал, но вроде они позволяют оперировать целыми числами разной разрядности до 80 бит. Но это немного сложнооо.

4. Последовательное деление. Пусть есть bx:cx:dx - 48-ми битное число, которое нужно делить на 16-ти битное в ax. Замечаем, что:

число = bx * 2^16 * 2^16 + cx * 2 ^ 16 + dx.

Что же происходит при делении ? Вот что:

число / ax = ( bx * 2^16 * 2^16 + cx * 2 ^ 16 + dx ) / ax =

= ( bx * 2^16 * 2^16 / ax ) + ( cx * 2 ^ 16 + dx ) / ax.

Второе слагаемое можно делить прямо сразу через деление dx:ax на делитель. Первое же можно делить так:

( (bx * 2^16) / ax ) * 2^16.

Ну и так далее. Этот алгоритм очень старый и много где описан. Наверняка.

5. Сопроцессор. Очень легко, возможна погрешность. Пусть есть два целых числа из 8-ми байт:

Number dq 1234567890Ah
Divisor dq 100000h
Res dd ?

Используя сопроцессор (ключ .8087 или .387 или любой старший .386) пишем:

fild qword ptr Number
fidiv qword ptr Divisor
fistp dword ptr Res

Обращаю внимание, что Res имеет размер dword. Это в связи с тем, что при загрузке данных в сопроцессор он их преобразует к одному общему формату 80-ти бит, поэтому можно было записать:

Number dw 1234h
Divisor dq 10h
Res dd ?

fild word ptr Number
fidiv qword ptr Divisor
fistp dword ptr Res

Автор: Serzh 9.2.2004, 01:57
а не проще ли для начала упростить формулу?
имеем - C*H*S*512/1024/1024
упрощаем - C*H*S*/2048
теперь умножаем целиндры на головки и на сектора и делаем сдвиг вправа на 11 бит.
получаем диапазон чисел от 0 до 2 терробайт. и это не пользуясь edx:eax
думаю, что на первое время 2 терробайт хватит! smile.gif

Автор: Ruterian 9.2.2004, 02:30
Serzh

> упрощаем - C*H*S*/2048

На 10000h надо делить %-)

Автор: Serzh 9.2.2004, 15:58
Цитата(Ruterian @ 9.2.2004, 02:30)
Serzh

> упрощаем - C*H*S*/2048

На 10000h надо делить %-)

дык да! но умножать та на 512(200h) еще!
значит делим на 800h = 2048

Автор: Serzh 9.2.2004, 16:00
э!!!
с какого перепуга 10000h?confused.gif??
1024*1024 = 1048576 = 100000h

Автор: Ruterian 9.2.2004, 17:07
ну ощипся маленько, на нолик всего smile.gif

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)