2010-01-20 4 views
1

У меня возникли проблемы с пониманием того, как получить результат вычисления, выполненного с использованием сопроцессора Intel x86.Вопросы сборки сопроцессора Intel x86

Обратите внимание на следующий сегмент данных.

и следующие сегменты кода, версия 1:

.code 

main: 

fld x  ; 5.0 
fadd k1 ; 5.0 + 3.4 
fistp res ; store as integer (it will round, in this case down) 

mov eax, res ; eax = 00000008 

end main 

и версия 2:

.code 

main: 

fld x  ; 5.0 
fadd k ; 5.0 + 3.4 
fstp res ; store as real 

mov eax, res ; eax = 41066666 

end main 

Я понимаю версия 1, без проблем.

Это версия 2 Я не понимаю. Я могу видеть в отладчике, что он делает точный подсчет в качестве версии 1, но когда пришло время хранить это делает так, как «41066666» !?

В чем причина этого?
Какая "кодировка" была использована, чтобы сделать 8.4 в "41066666"?
Есть ли способ конвертировать его обратно в 8.4, чтобы я мог его распечатать в консоли (например, используя библиотечную функцию StdOut masm32)?

Спасибо.

ответ

4

Floating Pointt Calculator and Converter

Введите 8,4, и вы можете увидеть шестигранной версия числа представляется в виде: 41066666

+0

Спасибо. Что объясняет его. Пожалуйста, уделите немного времени, чтобы ответить на другую часть вопроса: есть ли способ преобразовать его обратно в 8.4, чтобы я мог распечатать его на консоли? Благодарю. – nunos

+0

Ну ... как бы я это сделал в C, было бы назвать printf (% f, x). В какой библиотеке вы используете? Возможно, есть функция, чтобы преобразовать ее для вас. – CookieOfFortune

+0

Как упоминалось в сообщении, я использую masm32. Я не знаю, но, возможно, есть функция masm32, например dwtoa, но для плавающих, которые могут это сделать. – nunos

3

Кодирование является IEEE-754 формат с плавающей запятой. Похоже, вы используете 32-битные поплавки, также известные как одноточечная. Этот формат содержит бит знака, восьмибитовый показатель, который смещен 127 (возможно, 128-я не помню) и 24 бита мантиссы, где 23 сохранены, а недостающий бит является самым значительным и обычно имеет значение один, за исключением денормальных значений. Существует несколько шаблонов со специальным значением: ноль, NaN, бесконечность и денормалы.

Помимо внешнего инструмента, предложенного CookieOfFortune, вы можете написать преобразование с плавающей запятой в ASCII, выполнив множество арифметических операций для определения значения. Существует множество алгоритмов, которые позволяют использовать компромисс для пространства. См. Любой источник библиотеки времени исполнения для ftoa или конверсии% f или% g для printf().

3

0x41066666 8.4 (хорошо, 8.3999996185302734375, если быть точным), закодированный в формате одиночной точности IEEE-754. Вы можете легко отобразить его значение в виде шестнадцатеричного числа, извлекая поля компонента из кодировки, что дало бы вам 0x8.66666, но преобразовать его в десятичный код будет сложнее сделать правильно. Если вы хотите иметь десятичный вывод, проще всего связать с библиотекой C в вашей системе и использовать функцию printf.

В качестве альтернативы, как предлагается wallyk, возьмите источник для одной из процедур преобразования с открытым исходным кодом (или напишите свою собственную реализацию, хотя это удивительно сложная задача, чтобы преуспеть). Вероятно, лучшие легкодоступные источники находятся в файле gdtoa.tgz по адресу Netlib.Сложность этой реализации должна дать вам некоторое представление о связанных с этим проблемах и может указать вам на использование библиотеки =)