Студопедия

КАТЕГОРИИ:


Архитектура-(3434)Астрономия-(809)Биология-(7483)Биотехнологии-(1457)Военное дело-(14632)Высокие технологии-(1363)География-(913)Геология-(1438)Государство-(451)Демография-(1065)Дом-(47672)Журналистика и СМИ-(912)Изобретательство-(14524)Иностранные языки-(4268)Информатика-(17799)Искусство-(1338)История-(13644)Компьютеры-(11121)Косметика-(55)Кулинария-(373)Культура-(8427)Лингвистика-(374)Литература-(1642)Маркетинг-(23702)Математика-(16968)Машиностроение-(1700)Медицина-(12668)Менеджмент-(24684)Механика-(15423)Науковедение-(506)Образование-(11852)Охрана труда-(3308)Педагогика-(5571)Полиграфия-(1312)Политика-(7869)Право-(5454)Приборостроение-(1369)Программирование-(2801)Производство-(97182)Промышленность-(8706)Психология-(18388)Религия-(3217)Связь-(10668)Сельское хозяйство-(299)Социология-(6455)Спорт-(42831)Строительство-(4793)Торговля-(5050)Транспорт-(2929)Туризм-(1568)Физика-(3942)Философия-(17015)Финансы-(26596)Химия-(22929)Экология-(12095)Экономика-(9961)Электроника-(8441)Электротехника-(4623)Энергетика-(12629)Юриспруденция-(1492)Ядерная техника-(1748)

Лекция №9. Работа с FPU. Массивы

Команды управления FPU

 Команда: FSTCW приемник
 Назначение: Сохранить регистр CR
 Команда: FNSTCW приемник
 Назначение: Сохранить регистр CR без ожидания

Команды копируют содержимое CR в приемник (16-битная переменяя). Команда FSTCW, в отличие от FNSTCW, проверяет наличие произошедших и необработанных исключений и обрабатывает их до выполнения.

 

 Команда: FLDCW источник
 Назначение: Загрузить регистр CR
 Процессор:  

Копирует содержимое источника (16-битная переменная) в регистр CR.

 


Пример 3: Сложить два числа (В+С), используя сопроцессор. (real2.asm)

tasm32 /m3 /ml real2.asm pause tlink32 /Tpe /aa /c real2.obj /o import32.lib pause real2.exe pause td32 real2.exe
.386

.model flat, stdcall

includelib import32.lib

extrn ExitProcess:PROC

extrn MessageBoxA:PROC

.data

Ttl db "Arifmeticheskoe viragenie",0h

Msg db 10 dup(' '),0h

db 0h

B DW 10

C DW 3

Y dd?

.code

start:

finit

FILD B

FILD C

FADD

fist Y

mov eax,Y

 

xor edi,edi

xor esi,esi

mov si,10

mov edi,9

lp2: xor edx,edx

div esi

xchg eax,edx

add al,'0'

mov byte ptr [Msg+edi],al

xchg eax,edx

dec edi

or eax,eax

jne lp2

 

push 0h

push offset Ttl

push offset Msg

push 0h

call MessageBoxA

push 0h

call ExitProcess

end start

 


Пример 4. Вычислить 10х =y, x=3. (real4.asm)

1)

2) Величину log210 – можно задать как константу с помощью команды FLDL2T.

3) Команда F2XM1 возводит 2 в степень X, но только если X меньше или равен 1/2, то есть команда возводит 2 в степень, равную ST(0), и вычитает 1. Результат сохраняется в ST(0). Значение ST(0) должно лежать в пределах от -0,5 до 0.5, иначе результат не определен.

ST(0)=2ST(0) -1; -0,5<ST(0)<0,5

4) Команда FSCALE умножает ST(0) на два в степени ST(1) и записывает результат в ST(0). Значение ST(1) предварительно округляется в сторону нуля до целого числа.

ST(0)= ST(0)*2ST(1).

5) если х=3, то:

 

.386

.model flat, stdcall

includelib import32.lib

extrn ExitProcess:PROC

extrn MessageBoxA:PROC

.data

Ttl db "Arifmeticheskoe viragenie",0h

Msg db 10 dup(' '),0h

db 0h

X Dd 3

Y dd?

OLD_CW DW?

NEW_CW DW?

 

.code

start:

finit

FILD X; загрузить степень в стек ST(0)

FLDL2T;загрузить константу log2(10) в ST(0)

FMULP ST(1),ST(0); умножение с выталкиванием из стека 3*log210=9.965784284662087

FNSTCW OLD_CW; сохранить регистр CR без ожидания

FWAIT; ожидание готовности FPU

MOV AX,OLD_CW; значения регистра управления сохраняем в АХ

AND AX,NOT 0C00H; ax not 0000 1100 0000 0000=>ax and 1111 0011 1111 1111

OR AX,0400H; ax or 0000 0100 0000 0000

MOV NEW_CW,AX

FLDCW NEW_CW; загрузить регистр CR из NEW_CW

FLD1; загрузить вещественное число 1,0 в стек

FCHS; изменяет знак ST(0), превращая положительное число в

; отрицательное, и наоборот.

FLD ST(1); загрузить вещественное число (x*log2(10)) в стек

FRNDINT; Округляет значение ST(0) до целого числа в соответствии с

; режимом округления, заданным битами RC.

; INT(9.965784284662087)=9

FLDCW OLD_CW; Загрузить регистр CR из OLD_CW

FXCH ST(2); Обмен местами содержимого регистра ST(0) и

; источника ST(2). Если операнд не указан,

; обменивается содержимое ST(0) и ST(1).

FSUB ST(0),ST(2); Вычитание вещественных чисел 9,965784285-9=0.965784285

FSCALE; умножает содержимое ST(0) на 2 в степени,

; содержащейся в ST(1)= -1.

; (1/2=2^(-1))=>0.965784284662087/2

F2XM1; возводит 2 в степень, равную ST(0), и вычитает 1.

; Результат сохраняется в ST(0). Значение ST(0) должно

; лежать в пределах от -0,5 до +0,5, иначе результат не

; определен.

FSUBRP ST(1),ST(0); выполняют вычитание приемника из источника, а не

; источника из приемника.=>0.39754248593736856+1

FMUL ST(0),ST(0); умножение источника ST(0) на приёмник ST(0);

; 2^(0.482892142)*2^(0.482892142)

FSCALE; Умножает ST(0) на два в степени ST(1) и записывает

; результат в ST(0).

FIST Y

mov eax,Y

xor edi,edi

xor esi,esi

mov si,10

mov edi,9

lp2: xor edx,edx

div esi

xchg eax,edx

add al,'0'

mov byte ptr [Msg+edi],al

xchg eax,edx

dec edi

or eax,eax

jne lp2

push 0h

push offset Ttl

push offset Msg

push 0h

call MessageBoxA

push 0h

call ExitProcess

end start


Блок-схема подсчета выражения: y=10x

 


Пример №2. Вывести на экран вещественное число, находящееся в регистре сопроцессора ST(0). Порядок числа должен быть только положительным. (real5.asm)

FYL2X – Вычисление у*log2(x), то есть ST(1)*log2(ST(0)), помещает результат в ST(1) и выталкивает ST(0) из стека, так что после этой операции результат оказывается в ST(0). Первоначальное значение ST(0) должно быть неотрицательным. Если регистр ST(0) содержал ноль, результат (если ZM = 1) будет равен бесконечности со знаком, обратным ST(1). Например: 855963.36786=8,55963367Е+5;

Для определения порядка:

.386

.model flat, stdcall

includelib import32.lib

extrn ExitProcess:PROC

extrn MessageBoxA:PROC

.data

Ttl db "Veshestvebboe chiclo",0h

Msg db 23 dup(' '),0h

db 0h

X Dd 855963.36786; 8,55963367Е+5

OLD_CW DW?

NEW_CW DW?

Poryadok DW?

TEN8 DD 100000000

BCD_Mantisa DT?

BCD_Celaya dt?

BCD_Poryadok DT?

.code

start:

finit

FLD X; загрузить вещественное число в стек

FLD1

FXCH ST(1)

FYL2X; ST(1)=1*log2(X)

FLDL2T; поместить в стек log2(10)

Определяем порядок числа Х:  
FXCH

FDIV ST(0),ST(1)

FNSTCW OLD_CW

FWAIT

MOV AX,OLD_CW

AND AX,NOT 0C00H

OR AX,0400H

MOV NEW_CW,AX

FLDCW NEW_CW

FRNDINT; = Poryadok

FLDCW OLD_CW

FIST Poryadok

_________________________________________________________________________

; Блок возведения числа 10 в степень Poryadok. 10Poryadok

FLDL2T; поместить в стек log2(10)

FMULP ST(1),ST(0); 5*log2(10) = 16,60964047

FNSTCW OLD_CW

FWAIT

MOV AX,OLD_CW

AND AX,NOT 0C00H

OR AX,0400H

MOV NEW_CW,AX

FLDCW NEW_CW

FLD1

FCHS

FLD ST(1)

FRNDINT; ST(0)=16

FLDCW OLD_CW

FXCH ST(2)

FSUB ST(0),ST(2)

FSCALE; ST(0)= 1/2*0.60964047

F2XM1; ST(0)=2(1/2*0.60964047) -1;

FSUBRP ST(1),ST(0); ST(0)= 2(1/2*0.60964047)

FMUL ST(0),ST(0); ST(0)= 2(1/2*0.60964047)*2(1/2*0.60964047)

FSCALE; ST(0)= 2(1/2*0.60964047)*2(1/2*0.60964047)*216.

 

__________________________________________________________________________

FLD X; X=855963.36786

FDIV ST(0),ST(1); делим исходное число Х на 10 в степени Poryadok (10Poryadok).

; 855963.36786/105=8,5596336786

FLD ST(0)

 

FNSTCW OLD_CW

FWAIT

MOV AX,OLD_CW

AND AX,NOT 0C00H

OR AX,0400H

MOV NEW_CW,AX

FLDCW NEW_CW;

 

FRNDINT; Округляем для получения целой части 8

FLDCW OLD_CW

FSUB ST(1),ST(0); Выполняем вычитание 8,5596336786-8 =0,5596336786 для

; получения мантиссы.

FXCH

FIMUL TEN8; Умножаем мантиссу на 100000000

; =>0,5596336786*100000000=55963367,86. Получаем

; мантиссу как целое число.

FBSTP BCD_Mantisa; Записываем мантиссу как ВСD число в переменную

; BCD_Mantisa

FBSTP BCD_Celaya; Записываем целую часть числа как ВСD число в переменную

; BCD_Celaya

FILD Poryadok; записываем из памяти в стек ST(0) порядок

FBSTP BCD_Poryadok; записываем из стека порядок как BCD число в переменную

; BCD_Poryadok

; __________________________________________________________________________

; Блок вывода на экран значения. Вывод осуществляется справа налево: сначала порядок,

; потом «+», потом Е, потом мантисса, потом «,», потом целая часть.

mov eax,dword ptr [BCD_Poryadok]

xor edi,edi

mov edi,22

lp2: xor edx,edx

mov edx,eax

and edx,0000000Fh; 0000 0101 and 0000 1111 => dl=0000 0101

add dl,'0'

mov byte ptr [Msg+edi],dl

shr eax,4

dec edi

or eax,eax

jne lp2

 

mov byte ptr [Msg+edi],'+'

dec edi

 

mov byte ptr [Msg+edi],'E'

dec edi

 

mov eax,dword ptr [BCD_Mantisa]

lp3: xor edx,edx

mov edx,eax

and edx,0000000Fh

add dl,'0'

mov byte ptr [Msg+edi],dl

shr eax,4

dec edi

or eax,eax

jne lp3

 

mov byte ptr [Msg+edi],','

dec edi

 

mov eax,dword ptr [BCD_Celaya]

lp4: xor edx,edx

mov edx,eax

and edx,0000000Fh

add dl,'0'

mov byte ptr [Msg+edi],dl

shr eax,4

dec edi

or eax,eax

jne lp4

push 0h

push offset Ttl

push offset Msg

push 0h

call MessageBoxA

push 0h

call ExitProcess

end start

 


Блок-схема вывода на экран вещественного числа, которое хранится в регистре ST(0) сопроцессора.

 

<== предыдущая лекция | следующая лекция ==>
Константы FPU | Описание и инициализация массива в программе
Поделиться с друзьями:


Дата добавления: 2014-01-07; Просмотров: 1183; Нарушение авторских прав?; Мы поможем в написании вашей работы!


Нам важно ваше мнение! Был ли полезен опубликованный материал? Да | Нет



studopedia.su - Студопедия (2013 - 2024) год. Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав! Последнее добавление




Генерация страницы за: 0.008 сек.