Intel x87 FPU的使用基础

Intel x87 FPU专门用于执行标量浮点计算,可以对单精度浮点(32位)、双精度浮点(64位)以及扩展双精度浮点(80位)进行计算,并顺从IEEE754标准。

x87 FPU可以工作在32位兼容模式下以及64位模式下,在这两种下,FPU的数据寄存器的个数都一样,只有8个。对x87 FPU的数据寄存器的访问方式与一般的寄存器有所不同,它是栈式访问。你通过 FLD 指令把外部数据搬到x87 FPU的数据寄存器中时,那么x87 FPU会根据所搬数据的长度(32位、64位、80位)将输入数据分别对待为单精度浮点、双精度浮点和扩展双精度浮点方式,然后统一转为双精度扩展模式放到数据栈顶。因此x87 FPU的数据寄存器长度为80位,并且后续的浮点计算都是基于扩展双精度进行的。

在栈顶的数据寄存器索引为0,那么它下面一个就是1, 然后是2, 以此类推,到栈底则为7。数据输出到存储器时使用 FSTFSTP 指令,前者仅仅是根据目标存储器的长度(32位、64位、80位)将扩展双精度类型分别转为单精度、双精度、扩展双精度类型,然后输出到指定的存储器位置中。对于 FSTP 指令,除了将数据搬到外部外,还会执行推出堆栈的操作。另外,FLDFST 以及 FSTP 还能搬移FPU内部寄存器的数据,FLD 的作用是将指定的FPU数据寄存器位置的数据搬移到栈顶寄存器中,而 FST 则是将栈顶寄存器的数据搬移到指定的FPU数据寄存器的位置。

这边要注意的是,由于80位(10个字节)并不是32位(4个字节)的整数倍,因此数据加载或存储双精度扩展浮点往往是用96位(12个字节)为单位进行,所以 “tbyte” 所指的就是“twelve bytes”,呵呵呵。这里可以列一下Intel汇编格式的字节、字宽指定修饰词——byte(字节,8位),word(字,16位),dword(双字,32位),qword(四字,64位),tbyte(十二字节,96位),mmword(64位,但只能用于MMX指令集中),xmmword(128位,用于SSE指令集),ymmword(256位,用于AVX和AVX2指令集),zmmword(512位,用于AVX-512指令集)。

下面是一段演示计算sin(10.05) + cos(20.05)的代码,三角函数中的参数都以弧度制表示。

/** hi.c 
 * test
 * Created by Zenny Chen on 2/11/11. 
 * Copyright 2011 GreenGames Studio. All rights reserved. 
 **/ 
#include <stdio.h>

void test(long double *p, long double *q) 
{
    __asm__(".intel_syntax noprefix");
    __asm__("fld tbyte ptr [rdi] \n" // use double extended float -- st(0) holds 10.05
            "fld tbyte ptr [rsi] \n" // use double extended float -- st(0) holds 20.05, st(1) holds 10.05
            "fcos \n" // cos
            "fstp st(2) \n" // mov st(0) (i.e. cos(20.05) result) to st(2) and pop the value 
            "fsin \n" // now st(0) holds 10.05 and does fsin
            "fadd st(0), st(1) \n" // add st(0) and st(1) and store the result to st(0)
            "fstp dword ptr [rdi] \n" // automatically truncate to single-float, write to the first arg and pop the value 
            ); 
    __asm__(".att_syntax");
}

int main(void)
{
    long double a = 10.05;
    long double b = 20.05; 
    // calculate: sin(10.05) + cos(20.05) = -0.2233334
    test(&a, &b);
    printf("The answer is: %f\n", *(float*)&a);
}  

上述内联汇编用AT&T汇编语法格式写的话,如下表示:

.text
.align 2
.globl _asm_test

_asm_test: 
    fldt (%rdi)
    fldt (%rsi)
    fcos
    fstp %st(2)
    fsin
    fadd %st(1), %st(0)
    fstp (%rdi)
    ret 
  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值