![]() |
|
![]() ![]() ![]() |
|
Chrono017 |
|
|||
Новичок Профиль Группа: Участник Сообщений: 22 Регистрация: 20.11.2006 Репутация: нет Всего: нет |
может кто зможет обьяснить как происходит деление двоичных чисел, особено дробей?)..... а то я чет непонимаю(
|
|||
|
||||
JAPH |
|
|||
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 312 Регистрация: 8.1.2007 Где: Ленобласть Репутация: 1 Всего: 23 |
Что конкретно непонятно? Как вручную делить столбиком? Как это делать в программе? Как это делает компьютер?
-------------------- Что непонятно - спрашиваем ![]() |
|||
|
||||
Chrono017 |
|
|||
Новичок Профиль Группа: Участник Сообщений: 22 Регистрация: 20.11.2006 Репутация: нет Всего: нет |
непонятно как это делается програмно)
|
|||
|
||||
JAPH |
|
|||
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 312 Регистрация: 8.1.2007 Где: Ленобласть Репутация: 1 Всего: 23 |
При делении целых делимое имеет размер в два раза больше делителя. Так, если делимое - слово, то делитель - байт. Разберёмся сначала с этим случаем. Перед делением делимое загружается в AX. Затем производится деление командой DIV с операндом-делителем, например, DIV BYTE PTR [BX+SI]. Эта команда рассматривает и делимое, и делитель как беззнаковые целые. Она помещает частное в AL, остаток в AH. При попытке деления на ноль, а также если частное не помещается в AL (т.е. превосходит 255) возникает исключение по вектору 0, которое по умолчанию выводит "Division by zero" и завершает программу. Команда IDIV отличается от DIV лишь тем, что она рассматривает делимое и операнд как знаковые целые, соответственно, частное и остаток у неё тоже знаковые (остаток имеет знак делимого). В случае 16-битного операнда-делителя делимое 32-битное, и размещается оно в регистровой паре DX:AX (старшее слово в DX, младшее в AX). После деления остаток оказывается в DX, а частное в AX. Если же делитель 32-битный, то делимое 64-битное, и оно должно располагаться в паре EDX:EAX. Соответственно, частное будет в EAX, остаток в EDX. Деление дробных чисел производится при помощи математического сопроцессора. Тут всё легко. Команда FDIV:
Команда FDIVP имеет два операнда - стэковых регистра, второй из которых - ST. Она делит первый операнд на второй, сохраняет результат в первом и напоследок выталкивает из стэка второй операнд. Команда FDIVR отличается от FDIV лишь тем, что делит второй операнд на первый (или операнд в памяти на ST). Команда FIDIVR отличается от FIDIV лишь тем, что делит операнд в памяти на ST, но сохраняет результат по-прежнему в ST. Команда FDIVRP отличается от FDIVP тем же - делит второй операнд на первый. Это сообщение отредактировал(а) JAPH - 11.5.2007, 17:40 -------------------- Что непонятно - спрашиваем ![]() |
|||
|
||||
anwe |
|
|||
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 748 Регистрация: 2.9.2006 Репутация: 1 Всего: 23 |
Деление выполняется по подобию, как деление обычных десятичных чисел в стоблик, путем вычитания из делимого делителя.
Пример (первый попавшийся под пальцы в данный момент набор 1 и 0): 111011011 разделить на 1011. Тут даже не надо разделять ни на какие группы (по 4...). Пишем, как при делении в столбик: 111011011|1011 - 1011 ------->1 ------- 11 Как видно, что целых 1011 в числе 1110 одно. Значит первый разряд частного - 1. После первого вычитания остаток равен 11. Далее сносим следующий разряд с делимого, получится 111. Снова вычитаем делитель 1011. Но здесь получим целое 0. Вот оно и пойдет в частное. И далее опять сносится следующий разряд к остатку: 111011011|1011 - 1011 ------->1 ------- 11 сносим разряд: 111 - 1011 ------->0 ------ 111 сносим еще разряд: 1111 - 1011 -------->1 ------ 100 После следующего вычитания остаток получается 100, а целых 1, значит следующим в частное пойдет именно она - 1. Снеся следующий разряд, и который равен 0, к остатку, получим 1000, что меньше 1011. Значит в частное пропишется 0. Еще сносим: 111011011|1011 - 1011 ------->1 ------ 11 111 ------->0 1111 - 1011 ------->1 ------- 100 сносим разряд: 1000 - 1011 ------->0 ------ 1000 сносим еще разряд: 10001 - 1001 ------->1 ------ 110 Ситуация повторилась: целых числе 1 и оно идет следующим разрядом в частное, а к остатку 110 сносим разряд (наконец-то последний). Получим 1101. Но здесь уже достаточно. Снова сносить не надо, так как 1101>1011 и разница между ними даст 10. В частное пойдет 1: 111011011|1011 - 1011 ------->1 ------- 11 111 ------->0 1111 - 1011 ------->1 ------ 100 1000 ------->0 10001 - 1001 ------->1 ------- 110 сносим последний разряд: 1101 - 1011 ------>1 ------ 10 ------>остаток Вот и получили 111011011:1011=101011 и остаток 10. Так и делается: вычитается - к остатку сносится очередной разряд - и снова вычитается... И в машине это выполняется путем вычитания. Только то, что мы на бумаге так сказать прижимали делитель к левому краю при вычитании. машина реализует с помощью сдвигов. То есть из делимого вычитается делитель, сдвинутый на соответствующее количество разрядов влево. Причем вычитание проводится с учет флага переноса (в данном случае заема). По результату вычитания целая часть записывается в соответствующий разряд частного. А сам принцип записи разрядов в частном я показал. Вот почему команды умножения и деления одни из самых длительных. |
|||
|
||||
Chrono017 |
|
|||
Новичок Профиль Группа: Участник Сообщений: 22 Регистрация: 20.11.2006 Репутация: нет Всего: нет |
Спасибо)
|
|||
|
||||
![]() ![]() ![]() |
Правила форума "Asm: Общие вопросы" | |
|
Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, MAKCim. |
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей) | |
0 Пользователей: | |
« Предыдущая тема | Asm: Общие вопросы | Следующая тема » |
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |