На главную Назад
Добро пожаловать, уважаемый посетитель!

Следующая подпрограмма берет число из вершины стека и

преобразует его в печатную строку символов.Фактически,

подпрограмма извлекает число с вершины стека и посылает его на

дисплей.Далее эта подпрограмма будет использована в двух примерах

для вывода их результатов.Исходный текст программы показан на

Фиг. 7.25.

 

Эта подпрограмма достаточно просто строит выводимую символьную

строку.Если исходное число NAN, либо бесконечность, или другое

специальное число сопроцессора 8087, результат будет показан

неверно.Первая часть программы - удобное место для использования

команды FXAM, которая определила бы тип числа в вершине стека.Но

в данном примере эта команда не используется, так как

предполагается, что исходное число имеет нужный тип.

 

Эта программа не приспособлена для оформления формата

выводимого числа.Результат всегда содержит знак (либо пробел,

либо знак "-") и целую часть, состоящую из одной цифры.После

десятичной точки расположены восемь десятичных позиций, а затем

буква E и три позиции цифр для степени 10.Результат работы этой

программы не так хорош, как можно было желать, но он позволяет

видеть результат работы программы в читабельной форме.Более

красивое преобразование числа потребовало бы значительно больше

команд, и лишь малая часть из них помогла бы пониманию работы

сопроцессора 8087.

 

Программа преобразования работает следующим образом.Сначала

она определяет порядок числа.Например, число 1234 имеет порядок

3; это означает, что оно находится между значениями 103 и 104.

Найдя правильный порядок числа, программа сохраняет его значение

(показатель степени результата) и делит исходное число на 10 в этой

степени.Теперь число находится в интервале от 1 до 10.Затем

программа умножает число на 108.Запись этого числа в десятичной

форме дает девять десятичных цифр; старшая цифра - целая часть,

младшие восемь цифр - дробные разряды.

Microsoft (R) Macro Assembler Version 5.001/1/80 04:04:46

Фиг. 7.25 Преобразование плавающего формата в текстовыйPage1-1

 

PAGE,132

TITLEФиг. 7.25 Преобразование плавающего формата в текстовый

0000CODESEGMENT PUBLIC

ASSUMECS:CODE,DS:CODE,ES:CODE

EXTRNTEN_TO_X:NEAR

0000????OLD_CWDW?

0002????NEW_CWDW?

0004????EXPONENTDW?

0006???????????????????BCD_RESULTDT?

?

0010???????????????????BCD_EXPONENTDT?

?

001A00E1F505TEN8DD100000000

001E20 20 20 20 20 20 20PRINT_STRINGDB'E',10,13,'$'

20 20 45 20 20 20 20

0A 0D 24

 

Фиг. 7.25 Преобразование плавающего формата в текстовый (начало)

PUBLICFLOAT_ASCII

;--------------------------------------------

; Эта программа извлекает из вершины стека

;сопроцессора 8087 число и выводит его на

;экран в плавающем формате.

; Параметры: число в ST(0)

; Результат: изображение числа на экране;

;число извлечено из стека сопроцессора 8087

;--------------------------------------------

002FFLOAT_ASCIIPROCNEAR

;-----ST(0)-----;-----ST(1)-----;--ST(2)--

; X; ?; ?

002F9B D9 C0FLDST(0); X; X; ?

00329B D9 E1FABS; |X|; X; ?

00359B D9 E8FLD1; 1; |X|; X

00389B D9 C9FXCHST(1); |X|; 1; X

003B9B D9 F1FYL2X; LOG2(X); X; ?

003E9B D9 E9FLDL2T; LOG2(10); LOG2(X); X

00419B DE F1FDIVRPST(1),ST(0); E=LOGX/LOG10; X; ?

0044D9 3E 0000 RFNSTCWOLD_CW;;;

00489BFWAIT;;;

0049A1 0000 R MOVAX,OLD_CW;;;

004C25 F3FFANDAX,NOT 0C00H;;;

004F0D 0400ORAX,0400H;;;

0052A3 0002 R MOVNEW_CW,AX;;;

00559B D9 2E 0002 RFLDCWNEW_CW;;;

005A9B D9 FCFRNDINT; I = INT(E); X; ?

005D9B D9 2E 0000 RFLDCWOLD_CW;;;

00629B DF 16 0004 RFISTEXPONENT; I; X; ?

00679B D9 E0FCHS; -I; X; ?

006AE8 0000 E CALLTEN_TO_X; 10 ** (-I); X; ?

9B DE C9FMULPST(1),ST(0); X/10**I; ?; ?

00709B DA 0E 001A RFIMULTEN8; Мантисса; ?; ?

00759B DF 36 0006 RFBSTPBCD_RESULT; ?; ?; ?

007A9B DF 06 0004 RFILDEXPONENT; I; ?; ?

007F9B DF 36 0010 RFBSTPBCD_EXPONENT; ?; ?; ?

;-----Вывод на экран значений,запомненных как упакованные

;целые двоично-десятичные числа

0084FCCLD

00858D 3E 001E RLEADI,PRINT_STRING; Указатель на выводимую

;строку

0089A0 000F R MOVAL,BYTE PTR BCD_RESULT+9

008CE8 00C3 R CALLPRINT_SIGN; Печать знака

008FA0 000A R MOVAL,BYTE PTR BCD_RESULT+4

0092E8 00DF R CALLPRINT_NYBBLE; Печать первой цифры

0095B0 2EMOVAL,'.'; Десятичная точка

0097AASTOSB

00988D 1E 0009 RLEABX,BCD_RESULT+3

009CB9 0004MOVCX,4; Печать 8 байт (16 цифр)

009FDO_BYTE: ;после десятичной точки

009FE8 00CD R CALLPRINT_BYTE

00A2E2 FBLOOPDO_BYTE

00A4B0 45MOVAL,'E'; Символ экспоненты

00A6AASTOSB

 

Фиг. 7.25 Преобразование плавающего формата в текстовый (продолжение)

00A7A0 0019 R MOVAL,BYTE PTR BCD_EXPONENT+9

00AAE8 00C3 R CALLPRINT_SIGN; Печать знака экспоненты

00ADA0 0011 R MOVAL,BYTE PTR BCD_EXPONENT+1

00B0E8 00DF R CALLPRINT_NYBBLE; Первая цифра экспоненты

00B38D 1E 0010 RLEABX,BCD_EXPONENT

00B7E8 00CD R CALLPRINT_BYTE; Оставшиеся цифры

00BA8D 16 001E RLEADX,PRINT_STRING

00BEB4 09MOVAH,9H

00C0CD 21INT21H; Вывод всей строки на экран

00C2C3RET

00C3FLOAT_ASCIIENDP

 

;-----Эта подпрограмма выводит ' ' или '+'

00C3PRINT_SIGNPROCNEAR

00C33C 00CMPAL,0; Проверка на знак

00C5B0 20MOVAL,' '; Занесение положительного знака

00C774 02JZPOSITIVE

00C9B0 2DMOVAL,'-'; Занесение минуса

00CBPOSITIVE:

00CBAASTOSB; Сохранение в выводимой строке

00CCC3RET

00CDPRINT_SIGNENDP

 

;-----Эта программа печатает две десятичные цифры,

;находящиеся в памяти по адресу [BX]

 

00CDPRINT_BYTEPROCNEAR

00CD8A 07MOVAL,[BX]; Выборка байта

00CF51PUSHCX

00D0B1 04MOVCL,4

00D2D2 E8SHRAL,CL; Сдвиг старшей цифры

00D459POPCX

00D5E8 00DF R CALLPRINT_NYBBLE; Печать старшей цифры

00D88A 07MOVAL,[BX]; Выборка младшей цифры

00DAE8 00DF R CALLPRINT_NYBBLE; Печать младшей цифры

00DD4BDECBX; Переход на следующую пару цифр

00DEC3RET

00DFPRINT_BYTEENDP

 

;-----Печать одной десятичной цифры из регистра AL

 

00DFPRINT_NYBBLEPROCNEAR

00DF24 0FANDAL,0FH; Выделение младшей цифры

00E104 30ADDAL,'0'; Преобразование в символ

00E3AASTOSB; Сохранение в выводимой строке

00E4C3RET

00E5PRINT_NYBBLEENDP

00E5CODEENDS

END

 

Фиг. 7.25 Преобразование плавающего формата в текстовый (продолжение)

 

Первая часть программы определяет правильный порядок исходного

числа.В программе логарифм числа по основанию 10 находится с

помощью формулы

Log10(X) = Log2(X)/Log2(10)

 

Затем округляется порядок в направлении минус бесконечности,

опять используя управление округлением.В предыдущем примере,

вычисляя 10X, мы пользовались умножением для переноса исходного

числа в нужный диапазон.Теперь мы используем константу TENB

(которая содержит целое число 108) для того, чтобы вернуть число в

нужный диапазон.Наконец, команда FBSTP дважды преобразует числа в

десятичное представление; сначала она дает нам девять цифр мантиссы

числа, а затем - три цифры порядка.

 

Остальная часть программы выполняет символьную обработку,

необходимую для преобразования десятичного представления в строки

символов.Программа определяет и показывает знаки числа и порядка.

Она распаковывает десятичные байты и преобразует их в символы;

подпрограмма PRINT_BYTE делает распаковку, а подпрограмма

PRINT_NYBBLE выполняте преобразование в символы.Заметим, что в

этом случае не нужна команда XLAT, так как все цифры имеют значения

между 0 и 9.(Но если исходное число - одно из неопределенных

чисел, символьная строка будет содержать некоторые непонятные

символы).

 

Эта программа верно печатает любое число, лежащее в диапазоне

длинных действительных чисел.Любое число, выходящее за пределы

возможностей этого представления (например 101234) имеет поле

порядка, сокращенное до трех цифр.Конечно, вы можете изменить

программу так, чтобы она обрабатывала четыре цифры поля порядка,

если вы этого желаете.Но существует все же число, которое

программой обрабатывается верно, но вы, возможно, пожелаетет

изменить его изображение.Если исходное число 0, результат

печатается в виде 0.00000000E-932.Так происходит потому, что поле

порядка имеет смещение; процессор 8087 представляет число 0 с

минимально возможным порядком (-4932) и с нулевой мантиссой.Когда

программа преобразует число в код ASCII, она верно печатает

мантиссу и порядок (за исключением того, что ей приходится усекать

порядок до трех цифр).Если вы захотите обрабатывать такой порядок

отдельно, то измените программу, вставив в нее проверку на нуль

(чаще всего, с помощью команды FTST) в самом начале, рассматривая

это, как специальный случай.


 

Mail.ru