Сложение чисел с плавающей точкой в FPU

Последнее обновление: 02.07.2023

FPU предоставляет ряд инструкций для выполнения арифметических операций. Для сложения применяются инструкции fadd, faddp и fiadd

Если инструкциям fadd и faddp не передается параметр, то они извлекает два значения из вершины стека, складывает их и помещает их сумму обратно в стек.

fadd
faddp

Если инструкции fadd передаются два регистра FPU, то она добавляет значение второго операнда к значению первого операнда. Один из операндов должен быть регистром ST(0).

fadd st(i), st(0)
fadd st(0), st(i)

Инструкция faddp с двумя операндами добавляет ST(0) (который всегда должен быть вторым операндом) к первому операнду, а затем извлекает ST(0). Первый операнд должен быть одним из других регистров FPU.

faddp st(i), st(0)

Еще две формы fadd добавляют 32- или 64-битную переменную с плавающей точкой к значению в ST(0). Эти формы инструкции преобразует 32- или 64-битные операнды в 80-битное значение повышенной точности перед выполнением сложения. Но использовать 80-битные переменные нельзя операнд

fadd mem32
fadd mem64

Инструкция fiadd добавляет к ST(0) значение 16- и 32-битных переменных, которые представляют целые числа.

fiadd mem16
fiadd mem32

В зависимости от ситуации Эти инструкции могут генерировать исключения стека, точности, потери значимости (undeflow), переполнения, денормализации и недопустимой операции.

Применение fadd без параметров:

.data
    n1 real8 3.4
    n2 real8 4.6
    result dword ? 
.code
main proc
    fld n1              ; загружаем число n1 в стек FPU
    fld n2              ; загружаем число n2 в стек FPU
    fadd                ; складываем ST(0) и ST(1)
    fistp result        ; Преобразуем число из ST(0) в dword
    mov eax, result     ; EAX = 8
    ret
main endp
end

Здесь в стек FPU последовательно загружаются переменные n1 и n2. Поскольку больше ничего не загружается в стек, то эти переменные будут располагаться в регистрах ST(0) (n2) и ST(1)(n1). И инструкция fadd сложит их и поместит результат в ST(0).

Другой пример - сложим значения из двух регистров:

.data
st0 real8 3.4
st1 real8 4.6
st2 real8 1.6
result dword ? 
.code
main proc
    fld st2              
    fld st1              
    fld st0              
    fadd st(0), st(2)   ; складываем значения из регистров ST(0) и ST(2)
    fistp result        
    mov eax, result     ; EAX = 5
    ret
main endp
end

Здесь складываем значения из регистров ST(0) и ST(2). Результатом будет число 5.0, которое помещается в первый регистр - ST(0).

Третий пример - сложение с переменной:

.data
st0 real8 3.4
n real4 10.6
result dword ? 
.code
main proc             
    fld st0              
    fadd n              ; прибавляем к ST(0) значение переменной n
    fistp result        
    mov eax, result     ; EAX = 14
    ret
main endp
end
Помощь сайту
Юмани:
410011174743222
Перевод на карту
Номер карты:
4048415020898850