Форум программистов «Весельчак У»
  *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: [1]   Вниз
  Печать  
Автор Тема: ASM: Вещественные числа и целочисленная ариф&  (Прочитано 22130 раз)
0 Пользователей и 7 Гостей смотрят эту тему.
Yorkio
Гость
« : 22-05-2006 20:39 » new

Здравствуйте! Прошу помощи. Мне необходимо поспешать с курсовым по... назовём это "Ассемблером". Пока только прикидываю, но уже надо делать... Сдача 26, но тянуть могу до 8 июня. Далее трындец.
Задание: написать программу, реализующую:
1. Вывод (в защищённом режиме) графика указанной в задании функции. Пределы вводятся с клавиатуры.
2. Проинтегрировать в заданных пределах эту функцию. Интегрирование произвести два раза: с использованием любой из технологий {FPU, MMX, SSE} и с использованием целочисленной арифметики CPU. Пределы вводятся с клавиатуры. Вывести вычисленные значения.
3. Оценить быстродействие этих двух вычислительных операций не менее чем по двум параметрам.

Моё: Функция вида полином/полином, но подобрана так, что гладкая/без разрывов на интервале (-oo ; + oo). PM на себя возьмёт PMODE. Использовать буду FPU. Думаю обойтись одним сегментом данных, если всегда считать 640 или 800 значений.

Вопросы (знаю, что глупые, но куда деваться...):
1. Как реализовать ввод (да и вывод) дробных чисел?
Допустим, использую короткий формат и у меня
limit_left dd 0.0
Ввожу с клавиатуры:123.456
И что дальше делать? Есть готовый алгоритм?
2. Где почитать о этом самом измерении быстродействия средствами процессора?
3. ГЛАВНОЕ! Как выполнять арифметические операции в целочисленных командах над вещественными числами?
num1 dd 12.34
num2 dd 43.21
result dd 0.0
Как сложить/вычесть/умножить/поделить? Или я сам себя запутал, или это неслабая алгоритмическая задачка. Есть ли уже готовые решения? Где их искать? Лёгкая паника у меня по этому вопросу...
« Последнее редактирование: 06-06-2006 16:58 от Алексей1153 » Записан
RXL
Технический
Администратор

ru
Offline Offline
Пол: Мужской

WWW
« Ответ #1 : 23-05-2006 07:31 » 

Yorkio, объемы у тебя приличные и надеюсь ты большую часть сделал и незнаешь лишь деталей.

1. Различные DOS-расширители (типа DOS32, DOS4GW) предоставляют сервис доступа к реалмод INT 21h - ввод можно так реализовать. Разбор формата не сложно написать самому, а можно поискать в инете.
Формат: [<знак>][<целая часть>][.<дробная часть>][<E|e><знак><экспонента>]
Обязательное условие: целая и дробная часть - хотя бы одна должна существовать.

2. Для процов класса Pentium и выше есть команда чтения счетчика тактов (запамятовал - поищи - начинается на R).
Можно еще замерять значения RTC (аппаратные часы), но имеет низкую точность.

3. Для нецелочисленной арифметики есть библиотеки. Возможно вычисление как в плавающем формате, так и в более оптимизированном для целочисленных вычислений - фиксированном (fixed point). Fixed point библиотеки я встречал в сети - поищи.
Соотв. переведи double в fixed формат и используй либы.
Принципы fixed point очень просты: часть числа _условно_ считается целой, а остальная часть - дробной. Условно обозначают обычно как два числа через точку (напр. 16.16).

Сложение:
mov eax, 00010000h ; 1.0 в формате 16.16
mov edx, 00008000h ; 0.5 в формате 16.16
add eax,edx ; результат в формате 16.16

Умножение:
mov eax, 00010000h ; 1.0 в формате 16.16
mov edx, 00008000h ; 0.5 в формате 16.16
mul eax,edx ; результат в формате 32.32
Далее его можно привести к другому формату сдвигом.

Вычитание аналогично сложению. Деление - более сложно и тут расписывать не буду, но в fixed point оно не отличается от integer.

Ищи! Все это найти можно.
« Последнее редактирование: 23-05-2006 07:41 от RXL » Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
Yorkio
Гость
« Ответ #2 : 24-05-2006 15:00 » 

RXL, спасибо за ответ!
Экстендер не нужен - и так использую PMODE. Очень удобная и аккуратная штука.
Ввод/вывод решился нахождением на programmersheavens замечательной библиотеки AFLOAT, в которой, кроме восхитительного ввода/вывода, полный комплект "целочисленных" функций для работы с вещественными числами одинарной точности. Настоящий подарок из 1988 года...

Ещё есть вопросы:
1. Для вычислений одинарной точности после finit надо ли модифицировать поле управления точностью pc в регистре cwr?
Или оно влияет только на какие-то внутренние механизмы FPU?
2. Не понимаю, что делает fadd, fmul и иже с ними.
fadd= st(1)+st(0) -> st(0)
fmul st(i),st= st(0)*st(i) -> st(0)
А с st(1) и st(i) соответственно что конкретно происходит?
Там мусор? Почему?
3. Надо ли, и если надо, то где и как, использовать wait/fwait?
4. Интересное наблюдение сделал... Кажется, регистры st завёрнуты в кольцо? Это так?
5. 640 точек. Между точками
х(n+1) - x(n)= (abs(левая граница)+abs(правая граница))/640. Какой алгоритм интегрирования разумнее использовать?
Или разницы нет? А то в вычмате я ноль...

Заранее спасибо за ответы, ежели такие появятся.
« Последнее редактирование: 24-05-2006 16:53 от Yorkio » Записан
RXL
Технический
Администратор

ru
Offline Offline
Пол: Мужской

WWW
« Ответ #3 : 24-05-2006 16:35 » 

Ты похоже нашел эмулятор FPU.

1. finit сбрасывает состояние FPU в дефолтовое и, как следствие, переписывает регистр управления.
2. st - условное обозначение регистра стека. st0 - вершина стека. Всего 8 регистров. Почти все команды работают с вершиной стека. Туда же помещается результат вычисления.
3. Нет, не нужно - команда устаревшая. Нужна была для сихронизации CPU и FPU. В современных процессорах происходит автоматически.
4. Угу.
5. Правую часть вычисли сразу. А вообще, залезь на intel.com и скачай programers guide (типа того) на проц.
Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
Yorkio
Гость
« Ответ #4 : 24-05-2006 16:56 » 

Проблема: сопроцессор не хочет работать как надо.
В смысле, загрузка данных в него и обратно происходит нормально, а вот попытка выполнить умножение не на ноль
даёт 5.889780e-39. -39 усугубляет ощущение, что ошибка простая, но я её не вижу... Число "на грани". Что оно может значить? Умножение чего угодно на ноль всё же даёт ноль. Со сложением примерно та же история: складывает только ноль с нулём. Остальное даёт то самое 5.88...Процедура не несёт смысла - тестирую. Вот она:
...
cwr_dump   dw 0
const_640   dd 640.0
const_2   dd 2.0
float32   dd   0.0
...
county PROC NEAR
   finit ; Инициализируем сопроцессор

   ; Меняем точность
   fstcw cwr_dump
   and cwr_dump,0F0FFh
   or cwr_dump,0F0FFh
   fclex
   fldcw cwr_dump
   ; Поменяли

   fld const_2
   fld const_640
   fmul
   fstp float32
   call O_out_float ; Вывод float32 на экран.
   xor ah,ah
           int 16h
   ret
county ENDP
Записан
RXL
Технический
Администратор

ru
Offline Offline
Пол: Мужской

WWW
« Ответ #5 : 24-05-2006 18:00 » 

Yorkio, а ты проверяешь, что на стек загрузил? Я не вижу директивы assign - может ты не то грузишь и не то выводишь...
Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
Yorkio
Гость
« Ответ #6 : 24-05-2006 19:08 » 

 Улыбаюсь)
Разобрался! На стек действительно чёрти-что ложил. Просто я много на себя взял и в вводе и выводе тасовал слова в двойных словах так, как мне казалось правильным. Ключевое слово -"казалось". Всё-таки, эта AFLOAT замечательная вещь!
Теперь спать не лягу, пока не выведу график.
Азартное это занятие... стоило только начать... Уже туплю
Записан
Yorkio
Гость
« Ответ #7 : 27-05-2006 17:48 » 

Дописал. Показал. Вроде все довольны  Отлично
Защищать буду в понедельник. Пока готовлю Р-П записку и шлифую, в силу своих способностей, код.

Вопросы:
1. Инструкцию rdtsc (чтение счётчика тактов) TASM не признаёт даже при ".586p". "Illegal instruction" ругается. Что ему надо для успешной сборки этой инструкции? Пока спасаюсь так:
RDTSC MACRO
   db 0fh
   db 031h
ENDM
2. Вычитаю 64-битные числа. Из EDX:EAX вычитается [edx_tsc_1]:[eax_tsc_1]. Проверьте, правильно ли:
         ; Вычитаем
   clc
   sbb eax,[eax_tsc_1]
   jnc not_borrow
   and edx,0FFFFFFFEh
not_borrow:
   sbb edx,[edx_tsc_1]
   ; Вычли. Результат в EDX:EAX
3. Число тактов, уходящих на интегрирование левыми прямоугольниками средствами FPU и CPU различается в 8-9 раз понятно в чью пользу. Это нормально?

UPD:

4. Число тактов немного колеблется:
FPU = {3737 , 3355 , 3450 , 3350 , ...}
CPU = {24676 , 25211 , 25466 , 24951 , ...}
Это 4 эксперимента над одними и теми же данными и одним и тем же кодом.
Мне очень важно знать, почему число тактов колеблется! Кто знает - ответьте. Что влияет? Что может повлиять?
« Последнее редактирование: 27-05-2006 18:52 от Yorkio » Записан
RXL
Технический
Администратор

ru
Offline Offline
Пол: Мужской

WWW
« Ответ #8 : 27-05-2006 21:58 » 

1. Только так.

2. Используй флаг переноса (CY).
sub eax, [eax_tsc_1]
sbb edx, [edx_tsc_1]

3. Для того FPU и нужен, чтоб считать.

4. Влияют различные факторы: кеширование кода и данных, обработка прерываний. Это нормально. Запускай тест несколько раз и усредняй результаты измерений.
Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
Страниц: [1]   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines