КАТЕГОРИИ: Архитектура-(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
Команды копируют содержимое CR в приемник (16-битная переменяя). Команда FSTCW, в отличие от FNSTCW, проверяет наличие произошедших и необработанных исключений и обрабатывает их до выполнения.
Копирует содержимое источника (16-битная переменная) в регистр CR.
Пример 3: Сложить два числа (В+С), используя сопроцессор. (real2.asm)
.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)
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) сопроцессора.
Дата добавления: 2014-01-07; Просмотров: 1242; Нарушение авторских прав?; Мы поможем в написании вашей работы! Нам важно ваше мнение! Был ли полезен опубликованный материал? Да | Нет |