Загрузка и сохранение стека регистров FPU 


Мы поможем в написании ваших работ!



ЗНАЕТЕ ЛИ ВЫ?

Загрузка и сохранение стека регистров FPU



Для выполнения операций над вещественными числами необходимо хотя бы одно из этих чисел загрузить в стек регистров FPU. Загрузить в стек можно вещественные числа и 16- или 32-разрядные целые числа. Следует помнить, что при загрузке целых чисел они преобразуются в формат с плавающей точкой.

Для просмотра чисел в стеке можно воспользоваться функцией FpuState из библиотеки Fpu.lib. Она преобразует значения регистров FPU в текст и сохраняет его в памяти по указанному адресу.

Пример 1.7.1. Загрузка разнотипных вещественных чисел 3.51, 0.866e-06, ‑124.3198 и целых чисел 123 и 987 в стек и просмотр его содержимого.

.686

.model flat, stdcall

 

option casemap: none

В следующих примерах этот фрагмент указываться не будет, но вставлять в программы его необходимо!
include \masm32\include\windows.inc

include \masm32\include\user32.inc

include \masm32\include\kernel32.inc

include \masm32\include\Fpu.inc

include \masm32\include\debug.inc

 

includelib \masm32\lib\user32.lib

includelib \masm32\lib\kernel32.lib

includelib \masm32\lib\Fpu.lib

includelib \masm32\lib\debug.lib

 

.data

X Real4 3.51

Y Real8 0.866e-06

Z Real10 -124.3198

W word 123d

D dword 987d

Caption Byte "Состояние регистров FPU",0

State byte 400 dup (0); текст состояния FPU

 

.code

start:

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

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

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

fild W; загрузка целого числа X

fild D; загрузка целого числа X

invoke FpuState, ADDR State; копирует состояние регистров FPU

; в текстовую переменную State

invoke MessageBox, 0, addr State, addr Caption, MB_OK

invoke ExitProcess, 0

end start

Скомпилируйте программу с помощью Project®Build All и запустите на выполнение с помощью Project®Run Programm. Вы должны увидеть окно состояний регистров FPU (рис.1.7.1). Обратите внимание на представление чисел в стеке и значения флагов регистра состояния. Заглавными буквами обозначаются установленные флаги. Таким образом, установлен только один флаг – флаг PE, т.е. результат не может быть представлен точно (см. главу 2 настоящего пособия). Регистр тегов показывает, что загрузку пяти регистров правильными значениями (Value), а три регистра – пусты (Free – свободны). Поле TOP регистра тегов указывает, что на вершине стека сейчас находится регистр R3.

Пример 1.7.2. Пусть заданы два вещественных числа 3.5, 1.23 и два целых числа 10 и 2. Для нахождения их суммы достаточно загрузить любое из этих чисел в стек FPU и по очереди складывать его с остальными.

.data

X Real4 3.5

Y Real4 1.23

W word 10d

D word 2

S Real10?

Caption Byte "Состояние регистров FPU",0

State byte 400 dup (0)

.code

start:

fld X; загрузка X на вершину стека: ST=X

fadd Y; сложение с вещественным числом: ST=ST+Y=X+Y

fiadd W; сложение с целым числом: ST=ST+W=X+Y+W

fiadd D; сложение с целым числом: ST=ST+D=X+Y+W+D

invoke FpuState, ADDR State

invoke MessageBox, 0, addr State, addr Caption, MB_OK

invoke ExitProcess, 0

end start

Результат 16.73 можно увидеть в окне сообщений на вершине стека.

Для сохранения результатов вычислений в памяти можно воспользоваться командами fst, fstp, fist, fistp (см. Приложение В). Однако для вывода результатов в текстовом виде этого мало. Необходимо преобразовать двоичное представление результата в текстовое представление для вывода на экран. С этой целью можно использовать функцию FpuFLtoA из библиотеки Fpu.lib. Она имеет следующие параметры:

- указатель на 80-разрядное вещественное число. Этот параметр игнорируется и может быть заменён нулевым значением, когда указан флаг расположения источника в FPU – SRC1_FPU;

- непосредственно адресованный операнд или указатель на переменную в памяти, которая определяет точность десятичного представления: число десятичных знаков до и после запятой. Когда указан флаг STR_REG, то младший байт этого операнда определяет число цифр после запятой, но не более 16. Если разрядов дробной части меньше, чем указано, то справа дополняются нули. Следующий по старшинству байт определяет число разрядов перед запятой, но не более 17, из них 16 – для символов и один – для знака числа. Если разрядов целой части меньше, чем указано, то слева дополняются пробелы. Байт целой части игнорируется, когда указан научный формат;

- указатель на переменную в памяти, где размещать текст. Размер переменной должен быть достаточным, чтобы вместить в себя все символы числа. Максимальный размер равен 34 байтам-символам, из них не более 17 символов используется для вывода целой части, один байт – для десятичной запятой, 15 байтов – для знаков после запятой, и терминальный ноль;

- логическая сумма трёх нижеуказанных флагов.

1) Флаг источника может принимать одно из двух значений:

SRC1_FPU – источник в FPU;

SRC1_REAL – источник в памяти.

2) Флаг точности может принимать одно из двух значений:

SRC2_DMEM – указатель на 32-битное беззнаковое целое;

SRC2_DIMM – 32-битное беззнаковое целое.

3) Флаг формата может принимать одно из двух значений:

STR_REG – десятичный фиксированный формат (по умолчанию);

STR_SCI – научный формат (знак, мантисса, порядок).

Пример 1.7.3. Программа показывает преобразование вещественного числа, находящегося в вершине стека регистров, в текстовое представление и сохранение его в память по адресу Dest с тремя разрядами для целой части и тремя – для дробной части. Размер переменной Dest равен 10 разрядам, хотя можно было задать по минимуму 6. Следует отметить, что с переменной Dest нельзя производить вычисления, так как переменная R не число, а его текстовое представление в виде ASCII-кодов символов числа.

.data

X Real4 3.5

Y Real4 1.23

Dest byte 10 dup (0)

.code

start:

fld X

fadd Y

invoke FpuFLtoA, 0, 303h, ADDR Dest, SRC1_FPU or SRC2_DIMM

PrintString Dest

invoke ExitProcess, 0

end start

Пример 1.7.4. Программа показывает преобразование вещественного числа, выдавленного из стека FPU, в текстовое представление и сохранение его в память по адресу Dest с 14 разрядами для дробной части в научном формате. Обратите внимание, что результат неточен. Причина этого – неточное представление десятичных вещественных чисел в двоичном коде. Компиляторы современных языков программирования округляют вещественные числа в памяти до требуемой точности. В нашем примере достаточно указать всего 2 знака после запятой, а не 14.

.data

X Real4 3.5

Y Real4 1.23

R Real10?

Dest byte 40 dup (0)

.code

start:

fld X

fadd Y

fstp R

invoke FpuFLtoA, ADDR R, 14, ADDR Dest, SRC1_REAL or SRC2_DIMM or STR_SCI

PrintString Dest

invoke ExitProcess, 0

end start

С переменной Dest нельзя производить вычисления, так как эта переменная не число, а его текстовое представление в виде ASCII-кодов цифр числа. Числом является переменная R и именно с ней возможны дальнейшие вычисления.

Упражнение 1.7.1. На основе примера 1.7.4 разработать программу вычитания X‑Y. Разность разместить в памяти, в 80-битной переменной так, как это сделано в примере 1.7.4. Команда разности описана в Приложении В. Подсказка: для выполнения вычитания необходимо загрузить в стек переменную X, после чего вычесть из неё переменную Y с помощью команды fsub Y. При этом загружать Y в стек не обязательно. Для вывода результата в окно отладки его надо предварительно преобразовать в текстовое представление с помощью функции FpuFLtoA.

Для выполнения арифметических операций над числами, представленными в текстовом виде, необходимо воспользоваться функцией FpuAtoFL из библиотеки Fpu.lib для их преобразования в вещественные числа. Эта функция имеет следующие параметры:

- указатель на текстовую переменную, представляющую число. Текст может начинаться пробелами, но должен завершаться нулём. Число может быть записано в десятичной или экспоненциальной нотации и содержать не более 18 знаков.

- указатель на 80-разрядную вещественную переменную в памяти, где размещать результат. Этот параметр игнорируется и может принимать нулевое значение, если третьим параметром указан флаг DEST_FPU.

- Один из двух флагов приёмника результата:

DEST_FPU – результат помещается в стек FPU;

DEST_MEM – результат помещается в память.

Пример 1.7.5. Программа показывает преобразование текстовых представлений чисел X и Y в вещественное представление, и обратное преобразование их суммы в текст.

.data

X Byte "3.5",0

Y Byte "1.27",0

R Byte 10 Dup (0)

.code

start:

invoke FpuAtoFL, ADDR X, 0, DEST_FPU

invoke FpuAtoFL, ADDR Y, 0, DEST_FPU

fadd

invoke FpuFLtoA, 0, 2, ADDR R, SRC1_FPU or SRC2_DIMM

PrintString R

invoke ExitProcess, 0

end start

Упражнение 1.7.2. На основе примера 1.7.5 разработать программу умножения X*Y. Произведение вывести в окно отладки в текстовом виде. Подсказка: при обратном преобразовании следует указать правильное число знаков после запятой, чтобы не произошла потеря значащих разрядов.



Поделиться:


Последнее изменение этой страницы: 2016-06-29; просмотров: 893; Нарушение авторского права страницы; Мы поможем в написании вашей работы!

infopedia.su Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав. Обратная связь - 13.58.77.98 (0.011 с.)