目录
035-浮点指令FLD,FSTP,FADD与FPU寄存器
知识点:
浮点数的存放方式
st0至st7
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]内存处的值
QWORD是64位的
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处内存值如下:
二、st0至st7 浮点寄存器
st0到st7是80位长双精度寄存器
三 FLD,FSTP,FADD指令
FLD类似于 PUSH指令
FSTP类似于 POP指令
FADD类似于 ADD指令
FLD、FSTP、FADD的操作针对的是st0到st7寄存器,并不是对栈进行操作
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串操作详解