|
沙发

楼主 |
发表于 2010-3-13 23:34:11
|
只看该作者
保存和恢复 FPU 状态
上面看到,FSTENV 指令存储了 FPU 环境,但是不能恢复 FPU 数据寄存器。
为了保存包括数据在内的完整 FPU 环境,必须使用 FSAVE 指令。
FSAVE 指令把所有 FPU 寄存器复制到一个 108 字节的内存位置,然后初始化 FPU 状态。使用 FRSTOR 指令恢复 FPU 时,所有 FPU 寄存器 (包括数据寄存器)都会被恢复。
.section .data
value1:
.float 12.34
value2:
.float 56.789
rup:
.byte 0x7f, 0x0b
.section .bss
.lcomm buffer, 108
.section .text
.global _start
_start:
nop
finit
flds value1
flds value2
fldcw rup
fsave buffer
flds value2
flds value1
frstor buffer
movl $1, %eax
movl $0, %ebx
int $0x80 程序说明:
这里要注意在执行 FSAVE 指令之后的情况。在 GDB 里查看一下寄存器:... ...
fctrl 0x37f 895
st0 0 (raw 0x00000000000000000000)
st1 0 (raw 0x00000000000000000000)
st2 0 (raw 0x00000000000000000000)
st3 0 (raw 0x00000000000000000000)
st4 0 (raw 0x00000000000000000000)
st5 0 (raw 0x00000000000000000000)
st6 56.78900146484375 (raw 0x4004e327f00000000000)
st7 12.340000152587890625 (raw 0x4002c570a40000000000)
... ... 从上面的显示来看,堆栈的顶部被移动了,原来顶部的值现在位于寄存器堆栈的底部。并且,控制寄存器的值也被复位为默认值。可以在调试器中查看缓冲区内存位置中的值的情况:(gdb) x/108xb &buffer
0x80490c0 <buffer>: 0x7f 0x0b 0xff 0xff 0x00 0x30 0xff 0xff
0x80490c8 <buffer+8>: 0xff 0x0f 0xff 0xff 0x7e 0x80 0x04 0x08
0x80490d0 <buffer+16>: 0x73 0x00 0x05 0x01 0xb4 0x90 0x04 0x08
0x80490d8 <buffer+24>: 0x7b 0x00 0xff 0xff 0x00 0x00 0x00 0x00
0x80490e0 <buffer+32>: 0x00 0xf0 0x27 0xe3 0x04 0x40 0x00 0x00
0x80490e8 <buffer+40>: 0x00 0x00 0x00 0xa4 0x70 0xc5 0x02 0x40
0x80490f0 <buffer+48>: 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
0x80490f8 <buffer+56>: 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
0x8049100 <buffer+64>: 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
0x8049108 <buffer+72>: 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
0x8049110 <buffer+80>: 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
0x8049118 <buffer+88>: 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
0x8049120 <buffer+96>: 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
0x8049128 <buffer+104>: 0x00 0x00 0x00 0x00 缓冲区里不仅包含了控制、状态和标记寄存器,还包含了 FPU 数据寄存器的值。执行 FRSTOR 指令后,可以查看所有的寄存器,它们都被恢复位执行 FSAVE 时的状态。 |
|