曲径通幽论坛

标题: 传送浮点值及相关指令 [打印本页]

作者: beyes    时间: 2010-1-1 01:26
标题: 传送浮点值及相关指令
FLD 与 FST 指令
FLD 指令用于把浮点值传送入和传送出 FPU 寄存器。FLD 指令的格式是:
fld source
其中 source 可以是 32 位、64位 或者 80位的内存位置。下面的程序测试这条指令:
.section .data

value1:
    .float 12.34
value2:
    .double 2353.631

.section .bss
    .lcomm data, 8

.section .text

.global _start
_start:
    nop
    flds value1
    fldl value2
    fstl data
   
    mov $1, %eax
    mov $0, %ebx
    int $0x80
上面程序中,FLDS 加载单精度浮点数; FLDL 加载双精度浮点数。
类似的,FST 指令用于获取 FPU 寄存器堆栈中顶部的值,并且把这个值存放到内存位置中。也分为 FSTS 和 FSTL 两种,对于单精度数字,使用 FSTS 指令,对于双精度数字使用 FSTL 。

在运行 flds value1 指令后,可以看到 ST0 寄存器的值:
(gdb) print $st0
$2 = 12.340000152587890625

在运行 flds value2 指令后,可以看到 ST0 寄存器的值:
(gdb) print $st0
$1 = 2353.6309999999998581188265234231949
这个值已经被替换为新加载的双精度值(并且调试器正确地把这个值显示为双精度浮点值)。

用 info all 命令查看 STx 寄存器堆栈:
st0            2353.6309999999998581188265234231949     (raw 0x400a931a189374bc6800)
st1            12.340000152587890625    (raw 0x4002c570a40000000000)
正如期望的,当加载新值时,ST0 中的值就被移到 ST1 寄存器中。

执行 FSTL 指令后,现在查看 data 标签值:
(gdb) x/gf &data
0x80490a0 <data>:       2353.6309999999999
FSTL 指令把 ST0 寄存器中的值加载到 data 标签指向的内存位置中。
作者: beyes    时间: 2010-1-4 10:05
标题: 预置浮点值及相关指令
IA-32 指令集包含一些预置的浮点值,可以把它们加载到 FPU 寄存器堆栈中,下标是这些指令:
指令
描述
FLD1
把 +1.0 压入 FPU 堆栈中
FLDL2T
把 10 的对数(底数2)压入 FPU 堆栈中
FLDL2E
把 e 的对数(底数2)压入 FPU 堆栈中
FLDPI
把 pi 的值压入 FPU 堆栈中
FLDLG2
把 2 的对数(底数10)压入 FPU 堆栈中
FLDLN2
把 2 的对数(底数e) 压入堆栈中
FLDZ
把 +0.0 压入压入堆栈中

上面的指令中,FLDZ 压入 0 有点奇怪。在浮点数据类型中,+0.0 和 -0.0 是有区别的。对于大多数操作它们被认为是相同的值,但是在使用除法时,它们产生不同的值(正无穷大和负无穷大)。

下面程序测试这几个指令:
.section .text
.global _start

_start:
        nop
        fld1
        fldl2t
        fldl2e
        fldpi
        fldlg2
        fldln2
        fldz

        movl $1, %eax
        movl $0, %ebx
        int $0x80
在 GDB 中使用 info all 查看 FPU 寄存器堆栈:
st0            0        (raw 0x00000000000000000000)
st1            0.6931471805599453094286904741849753     (raw 0x3ffeb17217f7d1cf79ac)
st2            0.30102999566398119522564642835948945    (raw 0x3ffd9a209a84fbcff799)
st3            3.1415926535897932385128089594061862     (raw 0x4000c90fdaa22168c235)
st4            1.4426950408889634073876517827983434     (raw 0x3fffb8aa3b295c17f0bc)
st5            3.3219280948873623478083405569094566     (raw 0x4000d49a784bcd1b8afe)
st6            1        (raw 0x3fff8000000000000000)
st7            0        (raw 0x00000000000000000000)
可以发现,值的顺序和它们被存放到堆栈中的顺序是相反的。




欢迎光临 曲径通幽论坛 (http://www.groad.net/bbs/) Powered by Discuz! X3.2