|
Теперь приведем два примера, использующих
программу индикации
чисел с плавающей точкой.Первый пример - решение квадратного
уравнения.Найдем
корни уравнения, задаваемого следующей формулой
0 = A*X**2 + B*X + C
Из школьного курса математики известно,
что решение этого
уравнения
X = ( -B +- SQR( B**2 - 4*A*C))/(2*A)
Программа решения этого уравнения очевидна
и показана на
Фиг. 7.26.В
ней предполагается, что все три параметра A, B и C
записаны в виде целых чисел.Конечно, если вы будете использоваь
программу не только как пример, нужно
организовать процедуру ввода
различных коэффициентов.
Microsoft (R) Macro Assembler Version 5.00 1/1/80 04:04:54
Фиг. 7.26 Вычисление корней квадратного уравнения Page1-1
PAGE,132
TITLEФиг. 7.26 Вычисление корней квадратного уравнения
0000STACKSEGMENT STACK
00000040[DW64 DUP (?)
????
]
0080STACKENDS
0000CODESEGMENT
ASSUMECS:CODE,DS:CODE,ES:CODE
EXTRNFLOAT_ASCII:NEAR
00000001ADW1
0002FFFBBDW-5
00040006CDW6
0006????STATUSDW?
00080004FOURDW4
000A0002TWODW2
000C8C AD A8 AC EB A5 20ERROR_MSGDB'Мнимые корни',10,13,'$'
AA AE E0 AD A8 0A 0D
24
001BQUADRATICPROCFAR
001B1EPUSHDS ;
Сохранение адреса возврата
001C2B C0SUBAX,AX
001E50PUSHAX
001F8C C8MOVAX,CS
00218E D8MOVDS,AX
00238E C0MOVES,AX
00259B DB E3FINIT;-----ST(0)-----;-----ST(1)------
00289B DF 06 0002 RFILDB; B; ?
002D9B D8 8E 0000FMULST(0); B**2; ?
00329B DF 06 0000 RFILDA; A; B**2
00379B DE 0E 0008 RFIMULFOUR;
4*A; B**2
003C9B DE 0E 0004 RFIMULC; 4*A*C; B**2
00419B DE E1FSUBRPST(1),ST(0);
D=B**2-4*A*C; ?
00449B D9 E4FTST
00479B DD 3E 0006 RFSTSWSTATUS
004C9BFWAIT
004D8A 26 0007 RMOVAH,BYTE PTR STATUS+1
00519ESAHF
005272 37JBIMAGINARY
00549B D9 FAFSQRT; SQR(D);
Фиг. 7.26 Вычисление корней квадратного уравнения (начало)
00579B D9 C0FLDST(0); SQR(D); SQR(D)
005A9B D9 E0FCHS; -SQR(D); SQR(D)
005D9B DE 06 0002 RFIADDB; B-SQR(D); SQR(D)
00629B D9 E0FCHS; -B+SQR(D); SQR(D)
00659B D9 C9FXCHST(1); SQR(D); -B+SQR(D)
00689B DE 06 0002 RFIADDB; B+SQR(D); -B+SQR(D)
006D9B D9 E0FCHS; N1=-B-SQR(D); N2=-B+SQR(D)
00709B DE 36 0000 RFIDIVA; N1/A;
N2
00759B DE 36 000A RFIDIVTWO;
ROOT1=N1/2*A; N2
007AE8 0000 ECALLFLOAT_ASCII; N2;
?
007D9B DE 36 0000 RFIDIVA; N2/A; ?
00829B DE 36 000A RFIDIVTWO;
ROOT2=N2/2*A; ?
0087E8 0000 ECALLFLOAT_ASCII; ?; ?
008ACBRET
008BIMAGINARY:
008B8D 16 000C RLEADX,ERROR_MSG
008FB4 09MOVAH,9H
0091CD 21INT21H;
Вывод сообщения об ошибке
0093CBRET
0094QUADRATICENDP
0094CODEENDS
ENDQUADRATIC
Фиг. 7.26 Вычисление корней квадратного
уравнения (продолжение)
В примере отсутствует обработка
комплексных чисел, но имеется
проверка дискриминанта (B**2 - 4*A*C) на
отрицательность, и если это
число отрицательно, программа завешается с
сообщением об ошибке.
Можно было бы ввести в программу
комплексную арифметику, тем не
менее, ее нет в данном примере.Необходимо помнить, что
сопроцессор 8087 не обрабатывает
автоматически комплексные или
мнимые числа, и нужно писать программу
раздельной обработки
действительной и мнимой частей
комплексного числа.
Команда FTST проверяет дискриминант на
отрицательность; она
подобна сравнению с встроенным нулевым
операндом источника.
Программа записывает слово состояния в
память, а затем загружает
его в регистр флагов микропроцессора 8088.После этого делается
проверка JB (переход, если меньше),
определяющая, меньше ли нуля
дискриминант.Оставшаяся часть программы проделывает работу по
вычислению двух корней уравнения, и здесь
используется то
преимущество, что коэффициенты находятся в
памяти.Такой подход
минимизирует объем используемого в
сопроцессоре 8087 стека.Но
если вы переделаете эту программу так, что
она будет подпрограммой,
вызываемой из другой программы, вам,
вероятно, захочется передавать
параметры ей с помощью стека сопроцессора
8087.В этом случае
потребуется другой способ для загрузки
подпрограммой некоторых
величин.
|