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

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

Для деления в FPU есть 6 инструкций: fdiv, fdivp, fdivr, fdivrp, fidiv и fidivr

Инструкции fdiv, fdivp, fdivr, fdivrp могут использоваться без операндов:

fdiv
fdivp
fdivr
fdivrp

Без операндов инструкции fdiv и fdivp вычисляют выражение ST(1) = ST(1)/ST(0). Инструкции fdivr и fdivrp вычисляют выражение ST(1) = ST(0)/ST(1).

Инструкции могут принимать два операнда - два регистра:

fdiv st(0), st(i) ; st(0) = st(0)/st(i)
fdiv st(i), st(0) ; st(i) = st(i)/st(0)
fdivp st(i), st(0) ; st(i) = st(i)/st(0) с извлечением st0
fdivr st(0), st(i) ; st(0) = st(i)/st(0)
fdivr st(i), st(0) ; st(i) = st(0)/st(i)
fdivrp st(i), st(0) ; st(i) = st(0)/st(i) с извлечением st0

Инструкции fdivp и fdivrp также извлекают ST(0) после выполнения операции деления.

Инструкции также могут принимать один операнд - переменную, на которую делится регистр ST(0):

fdiv mem32
fdiv mem64
fdivr mem32
fdivr mem64
fidiv mem16
fidiv mem32
fidivr mem16
fidivr mem32

fdiv и fdivr принимают 32- и 64-битное число с плавающей точкой, а fidiv и fidivr - 16- и 32-битные целочисленные переменные.

Примеры деления с помощью инструкции fdiv. Без операндов:

.data
    st1 real8 20.5
    st0 real8 10.25
    result dword ? 
.code
main proc
    fld st1              ; загружаем число st1 в стек FPU
    fld st0              ; загружаем число st2 в стек FPU
    fdiv                ; ST(0) = ST(1) / ST(0) = 20.5 / 10.25
    fistp result        ; Преобразуем число из ST(0) в dword
    mov eax, result     ; EAX = 2
    ret
main endp
end

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

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

.data
    st0 real8 4.8
    st1 real8 4.6
    st2 real8 1.2
    result dword ? 
.code
main proc
    fld st2              
    fld st1              
    fld st0              
    fdiv st(0), st(2)   ; ST(0) = ST(0) / ST(2)
    fistp result        
    mov eax, result     ; EAX = 4
    ret
main endp
end

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

Деление переменной-числа с плавающей точкой:

.data
    st0 real8 10.0
    n real4 3.3
    result dword ? 
.code
main proc             
    fld st0              
    fdiv n              ;  ST(0) = ST(0) / n
    fistp result        
    mov eax, result     ; EAX = 3
    ret
main endp
end

В ST(0) загружается число st0, которое умножается на значение переменной n.

Помощь сайту
Юмани:
410011174743222
Перевод на карту
Номер карты:
4048415020898850