浮点指令

来源:互联网 发布:黑龙江网络广播电视台 编辑:程序博客网 时间:2024/05/16 13:06

浮点协处理器

浮点协处理器是一个循环栈结构,数据入栈时,栈中如有数据,数据会顺序的向下压栈。如果 8 个浮点寄存器中都有值的情况下继续压栈,会丢弃 st(7) 中的数据。出栈时,如果栈顶有数据,那么栈顶的数据会跑到栈底去。

这里写图片描述

出栈和入栈的指令

出栈的指令有 FILD, FLD, FLD1 等,这些指令可以概括为 load系列 指令;出栈指令为 FSTP。另外,对于浮点指令,其操作数只能是 浮点寄存器单元 或者 内存单元

–>浮点指令查阅

整型转换为浮点型及作为参数

int main(int argc, char* argv[]){    float f = argc;    printf("%f", f);    return 0;}

这里写图片描述

  • fild 将整型数据压入栈中;

  • sub esp, 8 意义为为了将一个 double 类型的变量作为参数入栈而开辟空间。因为浮点数作为变参时必须转换为双精度浮点值。

  • fstp 将 st(0) 的位置数据弹出

浮点数的运算

int main(int argc, char* argv[]){    double dbl = 3.14;    int n = (dbl * argc + dbl - 3.0) / argc;    int m1 = sqrt(dbl);    int m2 = log(dbl);    int m3 = sin(dbl);    printf("%f, %f, %f, %f", m1, m2, m3, n);    return 0;}

这里写图片描述

再浮点运算中,编译器并不会对其进行运算上的优化,因为优化都已经交给浮点处理器了。我看到的,都是很直白的加减乘除指令。对于 sin/log/sqrt 等数学上的计算,也有对应的指令来帮助一步完成。

在 Debug 版中,VC 编译器对于浮点的 sin 等指令,会生成非标准的函数进行计算。

浮点的比较

= 和 !=

int main(int argc, char* argv[]){  float f = argc;  double dbl = 3.14;  if (dbl == f)  {    printf("dbl == f\r\n");  }  if (dbl != f)  {    printf("dbl != f\r\n");  }    return 0;}

这里写图片描述

浮点数比较后,处理器中的标志位置将会置位。

test ah, 40

上面的指令检查了零标志位是否置位。可以知道零标志位是在控制位中的第 7 位。

> 和 <=

int main(int argc, char* argv[]){    float f = argc;    double dbl = 3.14;    if (dbl > f)    {        printf("dbl == f\r\n");    }    if (dbl <= f)    {        printf("dbl != f\r\n");    }    return 0;}

这里写图片描述

test ah, 1

< 和 >=

int main(int argc, char* argv[]){  float f = argc;  double dbl = 3.14;  if (dbl < f)  {    printf("dbl < f\r\n");  }  if (dbl >= f)  {    printf("dbl >= f\r\n");  }  return 0;}

这里写图片描述

test ah, 41h