18.5: Floating-Point Arithmetic Instructions
- Page ID
- 19978
\( \newcommand{\vecs}[1]{\overset { \scriptstyle \rightharpoonup} {\mathbf{#1}} } \)
\( \newcommand{\vecd}[1]{\overset{-\!-\!\rightharpoonup}{\vphantom{a}\smash {#1}}} \)
\( \newcommand{\id}{\mathrm{id}}\) \( \newcommand{\Span}{\mathrm{span}}\)
( \newcommand{\kernel}{\mathrm{null}\,}\) \( \newcommand{\range}{\mathrm{range}\,}\)
\( \newcommand{\RealPart}{\mathrm{Re}}\) \( \newcommand{\ImaginaryPart}{\mathrm{Im}}\)
\( \newcommand{\Argument}{\mathrm{Arg}}\) \( \newcommand{\norm}[1]{\| #1 \|}\)
\( \newcommand{\inner}[2]{\langle #1, #2 \rangle}\)
\( \newcommand{\Span}{\mathrm{span}}\)
\( \newcommand{\id}{\mathrm{id}}\)
\( \newcommand{\Span}{\mathrm{span}}\)
\( \newcommand{\kernel}{\mathrm{null}\,}\)
\( \newcommand{\range}{\mathrm{range}\,}\)
\( \newcommand{\RealPart}{\mathrm{Re}}\)
\( \newcommand{\ImaginaryPart}{\mathrm{Im}}\)
\( \newcommand{\Argument}{\mathrm{Arg}}\)
\( \newcommand{\norm}[1]{\| #1 \|}\)
\( \newcommand{\inner}[2]{\langle #1, #2 \rangle}\)
\( \newcommand{\Span}{\mathrm{span}}\) \( \newcommand{\AA}{\unicode[.8,0]{x212B}}\)
\( \newcommand{\vectorA}[1]{\vec{#1}} % arrow\)
\( \newcommand{\vectorAt}[1]{\vec{\text{#1}}} % arrow\)
\( \newcommand{\vectorB}[1]{\overset { \scriptstyle \rightharpoonup} {\mathbf{#1}} } \)
\( \newcommand{\vectorC}[1]{\textbf{#1}} \)
\( \newcommand{\vectorD}[1]{\overrightarrow{#1}} \)
\( \newcommand{\vectorDt}[1]{\overrightarrow{\text{#1}}} \)
\( \newcommand{\vectE}[1]{\overset{-\!-\!\rightharpoonup}{\vphantom{a}\smash{\mathbf {#1}}}} \)
\( \newcommand{\vecs}[1]{\overset { \scriptstyle \rightharpoonup} {\mathbf{#1}} } \)
\( \newcommand{\vecd}[1]{\overset{-\!-\!\rightharpoonup}{\vphantom{a}\smash {#1}}} \)
\(\newcommand{\avec}{\mathbf a}\) \(\newcommand{\bvec}{\mathbf b}\) \(\newcommand{\cvec}{\mathbf c}\) \(\newcommand{\dvec}{\mathbf d}\) \(\newcommand{\dtil}{\widetilde{\mathbf d}}\) \(\newcommand{\evec}{\mathbf e}\) \(\newcommand{\fvec}{\mathbf f}\) \(\newcommand{\nvec}{\mathbf n}\) \(\newcommand{\pvec}{\mathbf p}\) \(\newcommand{\qvec}{\mathbf q}\) \(\newcommand{\svec}{\mathbf s}\) \(\newcommand{\tvec}{\mathbf t}\) \(\newcommand{\uvec}{\mathbf u}\) \(\newcommand{\vvec}{\mathbf v}\) \(\newcommand{\wvec}{\mathbf w}\) \(\newcommand{\xvec}{\mathbf x}\) \(\newcommand{\yvec}{\mathbf y}\) \(\newcommand{\zvec}{\mathbf z}\) \(\newcommand{\rvec}{\mathbf r}\) \(\newcommand{\mvec}{\mathbf m}\) \(\newcommand{\zerovec}{\mathbf 0}\) \(\newcommand{\onevec}{\mathbf 1}\) \(\newcommand{\real}{\mathbb R}\) \(\newcommand{\twovec}[2]{\left[\begin{array}{r}#1 \\ #2 \end{array}\right]}\) \(\newcommand{\ctwovec}[2]{\left[\begin{array}{c}#1 \\ #2 \end{array}\right]}\) \(\newcommand{\threevec}[3]{\left[\begin{array}{r}#1 \\ #2 \\ #3 \end{array}\right]}\) \(\newcommand{\cthreevec}[3]{\left[\begin{array}{c}#1 \\ #2 \\ #3 \end{array}\right]}\) \(\newcommand{\fourvec}[4]{\left[\begin{array}{r}#1 \\ #2 \\ #3 \\ #4 \end{array}\right]}\) \(\newcommand{\cfourvec}[4]{\left[\begin{array}{c}#1 \\ #2 \\ #3 \\ #4 \end{array}\right]}\) \(\newcommand{\fivevec}[5]{\left[\begin{array}{r}#1 \\ #2 \\ #3 \\ #4 \\ #5 \\ \end{array}\right]}\) \(\newcommand{\cfivevec}[5]{\left[\begin{array}{c}#1 \\ #2 \\ #3 \\ #4 \\ #5 \\ \end{array}\right]}\) \(\newcommand{\mattwo}[4]{\left[\begin{array}{rr}#1 \amp #2 \\ #3 \amp #4 \\ \end{array}\right]}\) \(\newcommand{\laspan}[1]{\text{Span}\{#1\}}\) \(\newcommand{\bcal}{\cal B}\) \(\newcommand{\ccal}{\cal C}\) \(\newcommand{\scal}{\cal S}\) \(\newcommand{\wcal}{\cal W}\) \(\newcommand{\ecal}{\cal E}\) \(\newcommand{\coords}[2]{\left\{#1\right\}_{#2}}\) \(\newcommand{\gray}[1]{\color{gray}{#1}}\) \(\newcommand{\lgray}[1]{\color{lightgray}{#1}}\) \(\newcommand{\rank}{\operatorname{rank}}\) \(\newcommand{\row}{\text{Row}}\) \(\newcommand{\col}{\text{Col}}\) \(\renewcommand{\row}{\text{Row}}\) \(\newcommand{\nul}{\text{Nul}}\) \(\newcommand{\var}{\text{Var}}\) \(\newcommand{\corr}{\text{corr}}\) \(\newcommand{\len}[1]{\left|#1\right|}\) \(\newcommand{\bbar}{\overline{\bvec}}\) \(\newcommand{\bhat}{\widehat{\bvec}}\) \(\newcommand{\bperp}{\bvec^\perp}\) \(\newcommand{\xhat}{\widehat{\xvec}}\) \(\newcommand{\vhat}{\widehat{\vvec}}\) \(\newcommand{\uhat}{\widehat{\uvec}}\) \(\newcommand{\what}{\widehat{\wvec}}\) \(\newcommand{\Sighat}{\widehat{\Sigma}}\) \(\newcommand{\lt}{<}\) \(\newcommand{\gt}{>}\) \(\newcommand{\amp}{&}\) \(\definecolor{fillinmathshade}{gray}{0.9}\)The floating-point arithmetic instructions perform arithmetic operations such as add, subtract, multiplication, and division on single or double precision floating-point values. The following sections present the basic arithmetic operations.
Floating-Point Addition
The general form of the floating-point addition instructions are as follows:
addss <RXdest>, <src> addsd <RXdest>, <src>
Where operation is as follows:
<RXdest> = <RXdest> + <src>
Specifically, the source and destination operands are added and the result is placed in the destination operand (over-writing the previous value). The destination operand must be a floating-point register. The source operand may not be an immediate value. The value of the source operand is unchanged. The destination and source operand must be of the same size (double-words or quadwords). If a memory to memory addition operation is required, two instructions must be used.
For example, assuming the following data declarations:
fSNum1 dd 43.75 fSNum2 dd 15.5 fSAns dd 0.0 fDNum3 dq 200.12 fDNum4 dq 73.2134 fDAns dq 0.0
To perform the basic operations of:
fSAns = fSNum1 + fSNum2 fDAns = fDNum3 + fDNum4
The following instructions could be used:
; fSAns = fSNum1 + fSNum2 movss xmm0, dword [fSNum1] addss xmm0, dword [fSNum2] movss dword [fSAns], xmm0 ; fDAns = fDNum3 + fDNum4 movsd xmm0, qword [fDNum3] addsd xmm0, qword [fDNum4] movsd qword [fDAns], xmm0
For some instructions, including those above, the explicit type specification (e.g., dword, qword) can be omitted as the other operand or the instruction itself clearly defines the size. It is included for consistency and good programming practices.
The floating-point addition instructions are summarized as follows:
Instruction |
Explanation |
addss <RXdest>, <src> |
Add two 32-bit floating-point operands, (<RXdest> + <src>) and place the result in <RXdest> (over-writing previous value). |
Examples: |
addss xmm0, xmm3 addss xmm5, dword [fSVar] |
addsd <RXdest>, <src> |
Add two 64-bit floating-point operands, (<RXdest> + <src>) and place the result in <RXdest> (over-writing previous value). |
Examples: |
addsd xmm0, xmm3 addsd xmm5, qword [fDVar] |
A more complete list of the instructions is located in Appendix B.
Floating-Point Subtraction
The general form of the floating-point subtraction instructions are as follows:
subss <RXdest>, <src> subsd <RXdest>, <src>
Where operation is as follows:
<RXdest> = <RXdest> - <src>
Specifically, the source and destination operands are subtracted and the result is placed in the destination operand (over-writing the previous value). The destination operand must be a floating-point register. The source operand may not be an immediate value. The value of the source operand is unchanged. The destination and source operand must be of the same size (double-words or quadwords). If a memory to memory addition operation is required, two instructions must be used.
For example, assuming the following data declarations:
fSNum1 dd 43.75 fSNum2 dd 15.5 fSAns dd 0.0 fDNum3 dq 200.12 fDNum4 dq 73.2134 fDAns dq 0.0
To perform the basic operations of:
fSAns = fSNum1 - fSNum2 fDAns = fDNum3 - fDNum4
The following instructions could be used:
; fSAns = fSNum1 - fSNum2 movss xmm0, dword [fSNum1] subss xmm0, dword [fSNum2] movss dword [fSAns], xmm0 ;fSAns = fSNum3 - fSNum4 movsd xmm0, qword [fSNum1] subsd xmm0, qword [fSNum2] movsd qword [fSAns], xmm0
For some instructions, including those above, the explicit type specification (e.g., dword, qword) can be omitted as the other operand or the instruction itself clearly defines the size. It is included for consistency and good programming practices.
The floating-point subtraction instructions are summarized as follows:
Instruction |
Explanation |
subss <RXdest>, <src> |
Subtract two 32-bit floating-point operands, (<RXdest> - <src>) and place the result in <RXdest> (over-writing previous value). |
Examples: |
subss xmm0, xmm3 subss xmm5, dword [fSVar] |
subsd <RXdest>, <src> |
Subtract two 64-bit floating-point operands, (<RXdest> - <src>) and place the result in <RXdest> (over-writing previous value). |
Examples: |
subsd xmm0, xmm3 subsd xmm5, qword [fDVar] |
A more complete list of the instructions is located in Appendix B.
Floating-Point Multiplication
The general form of the floating-point multiplication instructions are as follows:
mulss <RXdest>, <src> mulsd <RXdest>, <src>
Where operation is as follows:
<RXdest> = <RXdest> * <src>
Specifically, the source and destination operands are multiplied and the result is placed in the destination operand (over-writing the previous value). The destination operand must be a floating-point register. The source operand may not be an immediate value. The value of the source operand is unchanged. The destination and source operand must be of the same size (double-words or quadwords). If a memory to memory addition operation is required, two instructions must be used.
For example, assuming the following data declarations:
fSNum1 dd 43.75 fSNum2 dd 15.5 fSAns dd 0.0 fDNum3 dq 200.12 fDNum4 dq 73.2134 fDAns dq 0.0
To perform the basic operations of:
fSAns = fSNum1 * fSNum2 fDAns = fDNum3 * fDNum4
The following instructions could be used:
; fSAns = fSNum1 * fSNum2 movss xmm0, dword [fSNum1] mulss xmm0, dword [fSNum2] movss dword [fSAns], xmm0 ; fSAns = fSNum3 * fSNum4 movsd xmm0, dworq [fSNum3] mulsd xmm0, dworq [fSNum4] movsd qword [fSAns], xmm0
For some instructions, including those above, the explicit type specification (e.g., dword, qword) can be omitted as the other operand or the instruction itself clearly defines the size. It is included for consistency and good programming practices.
The floating-point multiplication instructions are summarized as follows:
Instruction |
Explanation |
mulss <RXdest>, <src> |
Multiply two 32-bit floating-point operands, (<RXdest> * <src>) and place the result in <RXdest> (over-writing previous value). |
Examples: |
mulss xmm0, xmm3 mulss xmm5, dword [fSVar] |
mulsd <RXdest>, <src> |
Multiply two 64-bit floating-point operands, (<RXdest> * <src>) and place the result in <RXdest> (over-writing previous value). |
Examples: |
mulsd xmm0, xmm3 mulsd xmm5, qword [fDVar] |
A more complete list of the instructions is located in Appendix B.
Floating-Point Division
The general form of the floating-point division instructions are as follows:
divss <RXdest>, <src> divsd <RXdest>, <src>
Where operation is as follows:
<RXdest> = <RXdest> / <src>
Specifically, the source and destination operands are divided and the result is placed in the destination operand (over-writing the previous value). The destination operand must be a floating-point register. The source operand may not be an immediate value. The value of the source operand is unchanged. The destination and source operand must be of the same size (double-words or quadwords). If a memory to memory addition operation is required, two instructions must be used.
For example, assuming the following data declarations:
fSNum1 dd 43.75 fSNum2 dd 15.5 fSAns dd 0.0 fDNum3 dq 200.12 fDNum4 dq 73.2134 fDAns dq 0.0
To perform the basic operations of:
fSAns = fSNum1 / fSNum2 fDAns = fDNum3 / fDNum4
The following instructions could be used:
; fSAns = fSNum1 / fSNum2 movss xmm0, dword [fSNum1] divss xmm0, dword [fSNum2] movss dword [fSAns], xmm0 ; fSAns = fSNum3 / fSNum4 movsd xmm0, qword [fSNum3] divsd xmm0, qword [fSNum4] movsd qword [fSAns], xmm0
For some instructions, including those above, the explicit type specification (e.g., dword, qword) can be omitted as the other operand or the instruction itself clearly defines the size. It is included for consistency and good programming practices.
The floating-point division instructions are summarized as follows:
Instruction |
Explanation |
divss <RXdest>, <src> |
Divide two 32-bit floating-point operands, (<RXdest> / <src>) and place the result in <RXdest> (over-writing previous value). |
Examples: |
divss xmm0, xmm3 divss xmm5, dword [fSVar] |
divsd <RXdest>, <src> |
Divide two 64-bit floating-point operands, (<RXdest> / <src>) and place the result in <RXdest> (over-writing previous value). |
Examples: |
divsd xmm0, xmm3 divsd xmm5, qword [fDVar] |
A more complete list of the instructions is located in Appendix B.
Floating-Point Square Root
The general form of the floating-point square root instructions are as follows:
sqrtss <RXdest>, <src> sqrtsd <RXdest>, <src>
Where operation is as follows:
<dest> = √ <src>
Specifically, the square root of the source operand is placed in the destination operand (over-writing the previous value). The destination operand must be a floating-point register. The source operand may not be an immediate value. The value of the source operand is unchanged. The destination and source operand must be of the same size (double-words or quadwords). If a memory to memory addition operation is required, two instructions must be used.
For example, assuming the following data declarations:
fSNum1 dd 1213.0 fSAns dd 0.0 fDNum3 dq 172935.123 fDAns dq 0.0
To perform the basic operations of:
fSAns = √ fSNum1 fDAns = √ fSNum3
The following instructions could be used:
; fSAns = sqrt (fSNum1) sqrtss xmm0, dword [fSNum1] movss dword [fSAns], xmm0 ; fDAns = sqrt(fDNum3) sqrtsd xmm0, qword [fDNum3] movsd qword [fDAns], xmm0
For some instructions, including those above, the explicit type specification (e.g., dword, qword) can be omitted as the other operand or the instruction itself clearly defines the size. It is included for consistency and good programming practices.
The floating-point addition instructions are summarized as follows:
Instruction |
Explanation |
sqrtss <RXdest>, <src> |
Take the square root of the 32-bit floating- point source operand and place the result in destination operand (over-writing previous value). Note 1, destination operands must be a floating-point register. |
Examples: |
sqrtss xmm0, xmm3 sqrtss xmm7, dword [fSVar] |
sqrtsd <RXdest>, <src> |
Take the square root of the 64-bit floating- point source operand and place the result in destination operand (over-writing previous value). Note 1, destination operands must be a floating-point register. |
Examples: |
sqrtsd xmm0, xmm3 sqrtsd xmm7, qword [fDVar] |
A more complete list of the instructions is located in Appendix B.