第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