免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 5757 | 回复: 5
打印 上一主题 下一主题

理解x87浮点编程之一:物理资源 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2007-03-24 14:00 |只看该作者 |倒序浏览
这是根据AMD文档写的,如有不妥敬请指正!


一、X87 包括以下几个物理资源:

■浮点数据寄存器(X87 Data Registers):包括 FPR0 ~ FPR7 共 8 个寄存器。
     这8个浮点寄存器是浮点数存放的物理存储。每个寄存器80位宽,也就是说,每个浮点数的长度是80位,这是Intel定义的独有的所谓扩展双精度(Double-Extended Precision )。
     这8个浮点寄存器组织为Intel 独创的结构环形栈结构,相当于只有8个存储空间的栈结构。也具有内存栈结构的特性,也就是LIFO(后进先出)。由高(FPR7)向下(FPR0)生长。

■控制字寄存器(Control Word Register):这个寄存器16位宽,这个寄存器非常重要,主要起了以下几个作用:
       ★        精度控制
       ★        舍入控制
       ★        异常位的控制

■状态字寄存器(Status Word Register):这个寄存器16位宽,保存x87浮点处理器的重要状态。
    主要也是起以下几个作用:
   ★记录浮点寄存器栈顶TOP
     ★记录条件标志位(如:FUCOMP 指令比较后的状态)
   ★记录异常标志位

■标签字寄存器(Tag Word Register):这个寄存器16位宽,只有一个作用,就是记录每1个浮点寄存器的使用情况,8个浮点寄存器分为占用2位,所以每个寄存器有4个状态,分别为:00有效(Valid)、01零值(Zero)、10特殊的(Spical)、11空闲(Empty)。

■指令指针寄存器(Instruction Pointer Register):这个寄存器64位宽,保存最后一条非控制指令(non-Control Instruction)的指针,也就是说除了像FINIT、FSAVE这种x87控制指令外的x87非控制指令。

■数据指针寄存器(Data Pointer Register):这个寄存器64位宽,保存最后一条非控制指令(non-Control Instruction)的操作数的指针。

■Opcode 寄存器:这个寄存器11位宽,保存最后一条非控制x87指令的Opcode码。


二、物理资源组织
1、x87浮点数据寄存器(FPR0 ~ FPR7)
     x87共有8个浮点寄存器,分别为FPR0 ~ FPR7,这8个寄存器被组织成一个栈结构,与内存栈结构具有相同的特性,所不同的是:内存栈结构以内存为载体,而浮点寄存器栈是以浮点寄存器为载体,并且,通过两条指令FINCSTP和FDECSTP可以回卷。
浮点寄存器栈只有8个存储单元,因此极有可能会溢出。当栈满时,FINCSTP 回卷,当栈空时,FDECSTP回卷。

      浮点寄存器栈的栈顶指针记录在状态寄存器的Bit11 ~ Bit13。共3位合计8个数值,分别为000 ~ 111,也就是0 ~ 7,指示当前的栈顶位置在哪个浮点寄存器上。假如为010,则浮点寄存器栈顶位于FPR2。执行一条FLD,相当于执行一条PUSH指令,状态寄存器的Bit11 ~ Bit13减1,变成了001,这时TOP指针指向FPR1。

2、控制字寄存器(FCW)

      如图,RC域控制舍入,PC域控制精度,BIT0 ~ BIT5 是异常位掩码,当这些掩码位清0时,发生相应的异常时,将会产生#MF (x87 Floating-Point Exception-Pending (Vector 16))异常,这个是缺省的异常模式,当OM位置为1时,发生溢出异常,将调用#OF—Overflow exception (Vector 4)。

   精度控制:x87缺省的精度是扩展双精度(Double extended precision),分别为:
   00: 单精度(Single precision)
   01:   保留未用
   10: 双精度(Double precision)
   11: 扩展双精度(Double extended precision)

  舍入控制:是关于舍入控制方面的简单叙述,我暂时还未能理解透彻,所以不便论叙


3、状态字寄存器(FSW)

      如图,BIT0 ~ BIT5 对应相应的异常位,发生相当的异常时,相应位置1。
    SF域:栈错误异常,当栈满时,发生PUSH或Load Into 栈行为时产生栈错误异常;当栈空时,发生Pop行为,也就是有提领栈行为时产生栈错误异常。
    发生栈错误异常,也就是意味着发生栈溢出行为,分为两种情况:向上溢出(OverFlow)以及向下溢出(UnderFlow),处理器区别这两种溢出是根据C1域(条件1),当C1=1时,是向上溢出(overflow),当C1=0时,是向下溢出(underflow)。
    并且当SF异常时,处理器也置IE位为1,也属于无效操作异常(Invalid Operation Exception),SF异常在控制字寄存器中无相应掩码位。

    ES域:控制寄存器中相应异常掩码清0,并发生相应的异常时;或者,其它类型的异常发生时ES被置为1。
    条件码(C0~C3):x87的条件码作用相当于x86中的Eflags寄存器的条件码的作用。
    栈顶指针(TOP):栈顶指针000~111是x87浮点寄存器的索引值。共8个值,分别指示FPR0~FPR7,在汇编语法层,ST(0)表示栈顶


4、标签字寄存器(FTW)

      如图,标签字寄存器很简单,一目了然,每2位对应于一个浮点寄存器,处理器动态更新浮点寄存器的使用状态。当FTW寄存器为0时栈满,当FTW寄存器为FFFF时栈空。



(--未完--)

[ 本帖最后由 mik 于 2007-3-24 14:01 编辑 ]

论坛徽章:
3
2015年迎新春徽章
日期:2015-03-04 09:56:11数据库技术版块每日发帖之星
日期:2016-08-03 06:20:00数据库技术版块每日发帖之星
日期:2016-08-04 06:20:00
2 [报告]
发表于 2007-03-30 01:17 |只看该作者
我有空来补指令集,明天晚上吧
今天太晚了,睡觉了

论坛徽章:
0
3 [报告]
发表于 2007-03-30 12:41 |只看该作者
原帖由 cjaizss 于 2007-3-30 01:17 发表于 2楼  
我有空来补指令集,明天晚上吧
今天太晚了,睡觉了


呵呵,这样,那就等兄弟写指令部分。有劳兄弟~

我正写数据部分。我原先安排第2部分写数据,第3部分写指令,第4部分写实例。

论坛徽章:
3
2015年迎新春徽章
日期:2015-03-04 09:56:11数据库技术版块每日发帖之星
日期:2016-08-03 06:20:00数据库技术版块每日发帖之星
日期:2016-08-04 06:20:00
4 [报告]
发表于 2007-03-30 22:32 |只看该作者
在说明这些指令之前,我先做如下说明:
X87 fpu协处理器基于栈式设计,我们用%st(0)...%st(7)来表示,一共8个,%st(0)为栈顶,为3位栈指针寄存器所指。
既然是栈操作,那么就有进栈出栈操作。
进栈操作:操作后,新进栈的就存在%st(0),所有寄存器往后递推,原来%st(0)现在是%st(1),原来%st(1)现在是%st(2)...
出栈操作:操作后,所有寄存器往前递推,原来%st(1)现在是%st(0),原来%st(2)现在是%st(1)...
所有浮点寄存器长80位,为扩展精度,另外,单精度32位,双精度64位。
以下指令说明中Addr代指地址

[ 本帖最后由 cjaizss 于 2007-3-30 23:38 编辑 ]

论坛徽章:
3
2015年迎新春徽章
日期:2015-03-04 09:56:11数据库技术版块每日发帖之星
日期:2016-08-03 06:20:00数据库技术版块每日发帖之星
日期:2016-08-04 06:20:00
5 [报告]
发表于 2007-03-30 23:46 |只看该作者
以下为压栈
指令:
        flds Addr
        将Addr处所存单精度数压栈
指令:
        fldl Addr
        将Addr处所存双精度数压栈
指令:
        fldt Addr
        将Addr处所存扩展精度数压栈
指令:
        fildl Addr
        将Addr处所存有符号4字节整型转换为浮点数压栈
指令:
        fildll Addr
        将Addr处所存有符号8字节整型转换为浮点数压栈
指令:
        fld %st(i)
        将%st(i)寄存器所存扩展精度数压栈

以下为栈顶(%st(0))保存到内存,出栈与否可选择(最后带p字母的代表出栈)
指令:
        fsts Addr
        单精度数保存到Addr,不出栈
指令:
        fstps Addr
        单精度数出栈,保存到Addr
指令:
        fstl Addr
        双精度数保存到Addr,不出栈
指令:
        fstpl Addr
        双精度数出栈,保存到Addr
指令:
        fstt Addr
        扩展精度数保存到Addr,不出栈
指令:
        fstpt Addr
        扩展精度数出栈,保存到Addr
指令:
        fistl Addr
        将扩展精度取整之后,保存到Addr处4位有符号整数,不出栈
指令:
        fistpl Addr
        将扩展精度取整之后,保存到Addr处4位有符号整数,出栈
指令:
        fistll Addr(我记得有,但是需要硬件支持)
        将扩展精度取整之后,保存到Addr处8位有符号整数,不出栈
指令:
        fistpll Addr(我记得有,但是需要硬件支持)
        将扩展精度取整之后,保存到Addr处8位有符号整数,出栈
指令:
        fst %st(i)
        将%st(0)复制到%st(i),不出栈
指令:
        fstl %st(i)
        将%st(0)复制到%st(i),出栈(注意:这里%st(i)是当前%st(i),不是%st(0)出栈后的%st(i))
                                           [to be continued]

[ 本帖最后由 cjaizss 于 2007-3-31 00:16 编辑 ]

论坛徽章:
3
2015年迎新春徽章
日期:2015-03-04 09:56:11数据库技术版块每日发帖之星
日期:2016-08-03 06:20:00数据库技术版块每日发帖之星
日期:2016-08-04 06:20:00
6 [报告]
发表于 2007-04-03 20:34 |只看该作者
特殊值压栈指令
指令:
        fldz
        将0压栈       
指令:
        fld1
        将1压栈
指令:
        fldpi
        将圆周率PI压栈
指令:
        fldl2t
        将以2为底10的对数压栈
指令:
        fldl2e
        将以2为底e的对数压栈
指令:
        fldlg2
        将以10为底2的对数压栈
指令:
        fldln2
        将2的自然对数压栈

居然没有找到压e的指令。
           [to be continued]

交换指令
指令:
        fxch
        交换%st(0)和%st(1)

[ 本帖最后由 cjaizss 于 2007-4-3 20:41 编辑 ]
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP