第70部分- Linux x86 64位汇编 FPU之保存和恢复

第70部分- Linux x86 64位汇编 FPU之保存和恢复

FPU数据寄存器用于自己的FPU计算完,还用于MMX技术的计算。

所以涉及到FPU状态的保存和恢复。

FSTENV指令用于把FPU环境存储到一个内存块中。

会保存如下寄存器:

控制寄存器/状态寄存器/标记寄存器/FPU指令指针偏移量/FPU数据指针/FPU最后执行的操作码,并没有保存数据,如果要保存数据,则必须要使用FSAVE指令。

FLDENV指令用于把内存块的值加载会FPU环境中。

FSTENV示例

.section .data
value1:
   .float 12.34
value2:
   .float 56.789
rup:
   .byte 0x7f, 0x0b
.section .bss
   .lcomm buffer, 28
.section .text
.globl _start
_start:
   nop
   finit;//初始化FPU,所有stx设置为0
   flds value1;//加载value1到st0
   flds value2;// 加载value2到st0,value1到st1中。
   fldcw rup;//加载控制器内容为0x7f,0x0b
   fstenv buffer;//加载FPU环境到buffer
   finit;//初始化FPU
   flds value2;//重新加载value2到st0
   flds value1;// 重新加载value1到st0,value2到st1中。
   fldenv buffer;//从buffer中恢复FPU环境

   movq $60,%rax
   syscall

as -g -o fpuenv.o fpuenv.s

ld -o fpuenv fpuenv.o

这里例子通过gdb来进行反汇编查看。

通过(gdb) x /28b &buffer来查看buffer中内容。保存之后内容如下:

(gdb) x /28b &buffer

0x600100 <buffer>: 0x7f    0x0b    0xff    0xff    0x00    0x30    0xff    0xff

0x600108 <buffer+8>:   0xff    0x0f    0xff    0xff    0xbb    0x00    0x40    0x00

0x600110 <buffer+16>:  0x00    0x00    0x00    0x00    0x00    0x00    0x00    0x00

0x600118 <buffer+24>:  0x00    0x00    0xff    0xff

通过info all查看fpu的寄存器。

FSAVE示例

.section .data
value1:
   .float 12.34
value2:
   .float 56.789
rup:
   .byte 0x7f, 0x0b
.section .bss
   .lcomm buffer, 108
.section .text
.globl _start
_start:
   nop
   finit
   flds value1
   flds value2
   fldcw rup
   fsave buffer;//此处设置断点进行寄存器观察

   flds value2
   flds value1

   frstor buffer 

    movq $60,%rax ;//此处设置断点进行寄存器观察恢复后
   syscall

as -g -o fpusave.o fpusave.s

ld -o fpusave fpusave.o

在fsave之前如下:

st0            56.78900146484375   (raw 0x4004e327f00000000000)

st1            12.340000152587890625   (raw 0x4002c570a40000000000)

st2            0    (raw 0x00000000000000000000)

st3            0    (raw 0x00000000000000000000)

st4            0    (raw 0x00000000000000000000)

st5            0    (raw 0x00000000000000000000)

st6            0    (raw 0x00000000000000000000)

st7            0    (raw 0x00000000000000000000)

fctrl          0xb7f   2943

fstat          0x3000  12288

ftag           0xfff   4095

在fsave之后如下,堆栈顶部值移动了:

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)

fctrl          0x37f   895

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值