x86浮点运算基础:FPU寄存器、FLD/FSTP与FADD/FSUB等指令精讲

Source

目录

035-浮点指令FLD,FSTP,FADD与FPU寄存器

一、浮点数的存放方式

 二、st0至st7 浮点寄存器

 三 FLD,FSTP,FADD指令

036-浮点指令fsub  (减法)

一、浮点指令fsub

037-浮点指令fmul (乘法)

一、浮点指令fmul

038-浮点指令FDIV  (除法)

一、浮点指令FDIV   格式

039-浮点数与整数运算指令 FILD

一、浮点指令FILD格式

040-浮点指令CVTTPS2PI(浮点数转整数)

一、浮点指令CVTTPS2PI


035-浮点指令FLD,FSTP,FADDFPU寄存器

知识点:

 浮点数的存放方式

 st0st7

 FLD,FST,FADD指令

一、浮点数的存放方式

#include "stdafx.h"

int _tmain(int argc, _TCHAR* argv[])

{    

       float f=8.765f;

       f++;

       return 0;

}

00401000  /$  55            PUSH EBP

00401001  |.  8BEC          MOV EBP,ESP

00401003  |.  51            PUSH ECX      //相当于 SUB ESP,4

00401004  |.  D905 F0204000 FLD DWORD PTR DS:[4020F0]    //FLD相当于PUSH,把[4020F0]处的值压入st0寄存器

0040100A  |.  D95D FC       FSTP DWORD PTR SS:[EBP-4]  //FSTP相当于POP,把st0寄存器的值弹出到[EBP-4]内存处

0040100D  |.  D945 FC       FLD DWORD PTR SS:[EBP-4] //[EBP-4]内存处的值压入到st0寄存器

00401010  |.  DC05 E8204000 FADD QWORD PTR DS:[4020E8]       //FADD相当于ADD,把st0中的值加上[4020E8]内存处的值

QWORD64位的

00401016  |.  D95D FC       FSTP DWORD PTR SS:[EBP-4]

00401019  |.  33C0          XOR EAX,EAX

0040101B  |.  8BE5          MOV ESP,EBP      //相当于 ADD ESP,4

0040101D  |.  5D            POP EBP

0040101E  \.  C3            RETN

dd 4020F0, 32位浮点方式查看4020F0处内存值如下:

dq 4020E8,以64位双精度方式查看4020E8处内存值如下:

 二、st0st7 浮点寄存器

st0st780位长双精度寄存器

  FLD,FSTP,FADD指令

FLD类似于   PUSH指令

FSTP类似于  POP指令

FADD类似于  ADD指令

FLDFSTPFADD的操作针对的是st0st7寄存器,并不是对栈进行操作

FLD DWORD PTR DS:[4020F0]

FSTP DWORD PTR SS:[EBP-4]

    

FLD DWORD PTR SS:[EBP-4]

FADD QWORD PTR DS:[4020E8]

    

FSTP DWORD PTR SS:[EBP-4]

   

036-浮点指令fsub  (减法)

知识点:

 浮点指令 fsub

一、浮点指令fsub

   格式

   fsub memvar // st0=st0-memvar

#include "stdafx.h"

int _tmain(int argc, _TCHAR* argv[])

{

       float f=98.86f;

       f - -;

       f=f-3.0f;

       return 0;

}

00401000  /$  55            PUSH EBP

00401001  |.  8BEC          MOV EBP,ESP

00401003  |.  51            PUSH ECX

00401004  |.  D905 F8204000 FLD DWORD PTR DS:[4020F8]

0040100A  |.  D95D FC       FSTP DWORD PTR SS:[EBP-4]

0040100D  |.  D945 FC       FLD DWORD PTR SS:[EBP-4]

00401010  |.  DC25 F0204000 FSUB QWORD PTR DS:[4020F0]

00401016  |.  D95D FC       FSTP DWORD PTR SS:[EBP-4]

00401019  |.  D945 FC       FLD DWORD PTR SS:[EBP-4]

0040101C  |.  DC25 E8204000 FSUB QWORD PTR DS:[4020E8]

00401022  |.  D95D FC       FSTP DWORD PTR SS:[EBP-4]

00401025  |.  33C0          XOR EAX,EAX

00401027  |.  8BE5          MOV ESP,EBP

00401029  |.  5D            POP EBP

0040102A  \.  C3            RETN

037-浮点指令fmul (乘法)

知识点:

 浮点指令 fmul

一、浮点指令fmul

   格式

   fmul  memvar // st0=st0*memvar  

int _tmain(int argc, _TCHAR* argv[])

{

         double f1,f2;             

       f1=3.333f;

       f2=6.366f;

       f1=f1*f2;

//00401003  |.  83EC 10       SUB ESP,10          ;  double f1,f2;

//00401006  |.  DD05 F0204000 FLD QWORD PTR DS:[4020F0]

//0040100C  |.  DD5D F0       FSTP QWORD PTR SS:[EBP-10]   ;  f1=[4020f0]=3.333;

//0040100F  |.  DD05 E8204000 FLD QWORD PTR DS:[4020E8]

//00401015  |.  DD5D F8       FSTP QWORD PTR SS:[EBP-8]    ;  f2=[4020e8]=6.366

//00401018      DD45 F0       FLD QWORD PTR SS:[EBP-10]

//0040101B                       FMUL QWORD PTR SS:[EBP-8]   ;  st0=st0*f2=6.366*3.33

//0040101E      DD5D F0       FSTP QWORD PTR SS:[EBP-10]   ;  f1=21.21788

return 0;

}

038-浮点指令FDIV  (除法)

知识点:

 038-浮点指令FDIV()

一、浮点指令FDIV   格式

   FDIVmemvar // st0=st0 / memvar

int _tmain(int argc, _TCHAR* argv[])

{

  float f1,f2;

  f1=3.33;

  f2=2.00;

  f1=f1/f2;

 

//00401003  |.  83EC 08       SUB ESP,8      ;  float f1,f2;

//00401006  |.  D905 E8204000 FLD DWORD PTR DS:[4020E8]

//0040100C  |.  D95D F8       FSTP DWORD PTR SS:[EBP-8]  ;  f1=3.33

//0040100F  |.  D905 E4204000 FLD DWORD PTR DS:[4020E4]

//00401015  |.  D95D FC       FSTP DWORD PTR SS:[EBP-4]  ;  f2=2.00

//00401018  |.  D945 F8       FLD DWORD PTR SS:[EBP-8]

//0040101B  |.  D875 FC       FDIV DWORD PTR SS:[EBP-4]  ;  st0=st0/f2

//0040101E  |.  D95D F8       FSTP DWORD PTR SS:[EBP-8]  ;  f1=1.665

       return 0;

}

039-浮点数与整数运算指令 FILD

知识点:

 浮点指令FILD

一、浮点指令FILD格式

  整数入栈指令

  FILD memvar // st0=(double)memvar   //把整数转化为双精度浮点数压入ST0寄存器中

与之相似的指令有FIST st0的数转换成整数放置到变量中

#include "stdafx.h"

int _tmain(int argc, _TCHAR* argv[])

{

       double f=666.886;

       int i=2;

       f=f+i;

       return 0;

}

00401000  /$  55            PUSH EBP

00401001  |.  8BEC          MOV EBP,ESP

00401003  |.  83EC 10       SUB ESP,10   //double f; int i

00401006  |.  DD05 E8204000 FLD QWORD PTR DS:[4020E8]   //PUSH 666.886 to ST0

0040100C  |.  DD5D F0       FSTP QWORD PTR SS:[EBP-10]              //f=666.886, POP ST0 to f (EBP-10)

0040100F  |.  C745 FC 02000>MOV DWORD PTR SS:[EBP-4],2        //i=2

00401016  |.  DB45 FC       FILD DWORD PTR SS:[EBP-4]         //PUSH i to ST0 as double

00401019  |.  DC45 F0       FADD QWORD PTR SS:[EBP-10] //add ST0 with f

0040101C  |.  DD5D F0       FSTP QWORD PTR SS:[EBP-10] // POP ST0 to f

0040101F  |.  33C0          XOR EAX,EAX

00401021  |.  8BE5          MOV ESP,EBP

00401023  |.  5D            POP EBP

00401024  \.  C3            RETN

040-浮点指令CVTTPS2PI(浮点数转整数)

知识点:

浮点指令CVTTPS2PI

一、浮点指令CVTTPS2PI

     mem这个浮点数截断取整 后放到通用寄存器里边

    CVTTPS2PI mm0,mem// mm0 

  CVTTPS2PI MM0,DQWORD PTR SS:[ebp]  //[eax]

  CVTTPS2PI MM0,DQWORD PTR SS:[ESP]

#include "stdafx.h"

int _tmain(int argc, _TCHAR* argv[])

{

       double f=666.886;

       int i=2;

       i=f+i;

       return 0;

}

00401000  /$  55            PUSH EBP

00401001  |.  8BEC          MOV EBP,ESP

00401003  |.  83EC 10       SUB ESP,10

00401006  |.  DD05 F8204000 FLD QWORD PTR DS:[4020F8]

0040100C  |.  DD5D F0       FSTP QWORD PTR SS:[EBP-10]

0040100F  |.  C745 FC 02000>MOV DWORD PTR SS:[EBP-4],2

00401016  |.  DB45 FC       FILD DWORD PTR SS:[EBP-4]

00401019  |.  DC45 F0       FADD QWORD PTR SS:[EBP-10]

0040101C  |.  E8 FF070000   CALL 40.00401820

00401021  |.  8945 FC       MOV DWORD PTR SS:[EBP-4],EAX

00401024  |.  33C0          XOR EAX,EAX

00401026  |.  8BE5          MOV ESP,EBP

00401028  |.  5D            POP EBP

00401029  \.  C3            RETN

在上面的CALL 40.00401820指令中,就有一条如下指令:

00401836  |.  0F2C0424      CVTTPS2PI MM0,DQWORD PTR SS:[ESP]

MM0 对应EAX

MM1 对应ECX

MM2 对应EDX

…………


计算机科学与技术 & 计算机网络技术:双专业课程体系完全导航指南

 本系列目录

1、逆向工程基础:Ollydbg(OD)调试器实战与MOV指令寻址方式精讲

2、汇编语言核心概念精讲:从ADD、SUB、MOVSX/MOVZX到LEA与寄存器详解

3、x86汇编条件跳转指令完全解析:从CMP到有/无符号跳转与If实现

4、x86汇编函数调用完全解析:栈帧(EBP/ESP)构建与三种调用约定(cdecl/stdcall/fastcall)对比

5、汇编逆向还原核心:if-else与switch-case结构的识别与C代码重构

6、编译器优化揭秘:对比for循环的汇编实现与INC vs ADD指令的性能抉择

7、x86浮点运算基础:FPU寄存器、FLD/FSTP与FADD/FSUB等指令精讲

8、汇编位移指令全解与逆向实战:从SHR/SHL到ROL/ROR,逆向分析strcmp

9、汇编位运算指令精讲:掌握AND/OR/XOR/NOT四大核心操作

10、x86汇编字符串处理:SCASB/SCASW指令与REPNE/REPE重复前缀详解

11、汇编实战:用REPNZ SCASB与REPZ CMPSB从零实现strcmpA/W

12、x86汇编批量操作指令:LOOP循环控制与STOS/LODS串操作详解

13、x86条件置位指令(SETxx)完全指南:从标志位解读到条件判断实战

14、游戏逆向工程实战:从CALL分析、基址定位到冷却破解与内存修改