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

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

Для выполнения умножения FPU предоставляет инструкции fmul, fmulp и fimul. Инструкции fmul и fmulp умножают два значения с плавающей точкой. Инструкция fimul умножает целое число и значение с плавающей точкой. Эти инструкции допускают следующие формы:

fmul
fmulp
fmul st(0), st(i)
fmul st(i), st(0)
fmul mem32
fmul mem64
fmulp st(i), st(0)
fimul mem16
fimul mem32

Без операндов fmul и fmulp извлекают ST(0) и ST(1), умножают эти значения и помещают их произведение обратно в стек.

Инструкция fmul с двумя регистровыми операндами перемножают операнды и помещают результат в первый регистр. Один из регистров должен быть ST(0). Инструкция fmulp с двумя операндами аналогично перемножает значения обоих регистров, но после этого также извлекает значение регистра ST(0).

Инструкция fmul также может принимать один операнд - 32- или 64-битную переменную. Она преобразуют указанную переменную в 80-битное значение расширенной точности, а затем умножают ST(0) на это значение. Дополнительно инструкция fimul принимает 16- и 32-битные пременные - целые числа, которые умножаются на ST(0).

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

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

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

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

.data
    st0 real8 5.0
    st1 real8 4.6
    st2 real8 1.2
    result dword ? 
.code
main proc
    fld st2              
    fld st1              
    fld st0              
    fmul st(0), st(2)   ; ST(0) = ST(0) * ST(2)
    fistp result        
    mov eax, result     ; EAX = 6
    ret
main endp
end

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

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

.data
    st0 real8 10.0
    n real4 3.2
    result dword ? 
.code
main proc             
    fld st0              
    fmul n              ;  ST(0) = ST(0) * n
    fistp result        
    mov eax, result     ; EAX = 32
    ret
main endp
end

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

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