先抄一段书:
浮点执行环境的寄存器主要是8个通用数据寄存器和几个专用寄存器,它们是状态寄存器、控制寄存器、标记寄存器等
8个浮点数据寄存器(FPU Data Register),编号FPR0 ~ FPR7。每个浮点寄存器都是80位的,以扩展精度格式存储数据。当其他类型数据压入数据寄存器时,PFU自动转换成扩展精度;相反,数据寄存器的数据取出时,系统也会自动转换成要求的数据类型。
8个浮点数据寄存器组成首尾相接的堆栈,当前栈顶ST(0)指向的FPRx由状态寄存器中TOP字段指明。数据寄存器不采用随机存取,而是按照“后进先出”的堆栈原则工作,并且首尾循环。向数据寄存器传送(Load)数据时就是入栈,堆栈指针TOP先减1,再将数据压入栈顶寄存器;从数据寄存器取出(Store)数据时就是出栈,先将栈顶寄存器数据弹出,再修改堆栈指针使TOP加1。浮点寄存器栈还有首尾循环相连的特点。例如,若当前栈顶TOP=0(即ST(0) = PFR0),那么,入栈操作后就使TOP=7(即使ST(0) = PFR7),数据被压入PFR7。所以,浮点数据寄存器常常被称为浮点数据栈。
为了表明浮点数据寄存器中数据的性质,对应每个FPR寄存器,都有一个2位的标记(Tag)位,这8个标记tag0 ~ tag7组成一个16位的标记寄存器。
这是我偶然发现的,st(0)中的数值在出栈后都到哪里去了?
先看一段程序:
.386
.model flat,stdcall
option casemap:none
include windows.inc
include user32.inc
includelib user32.lib
include kernel32.inc
includelib kernel32.lib
.const
szCaption db 'This is caption.',0
szStart db 'the final value %x',0
.data
szBuffer db 32 dup(?)
.data?
szValue dd ?
vFirst dd ?
vSecond dd ?
vThird dd ?
.code
start:
mov vFirst,1000
mov vSecond,100
mov vThird,10
mov szValue,0
finit
fild vFirst
fild vSecond
fild vThird
fdivp st(1),st
fistp szValue
invoke wsprintf,addr szBuffer,addr szStart,szValue
invoke MessageBox,NULL,offset szBuffer,offset szCaption,MB_OK
invoke ExitProcess,NULL
end start
一段小程序,1000/100后所得值出栈,100/10后值出栈
用OllyDBG反编译
st0至st7中的值
按f7步进,进行到0040103d
再按f7
接着按f7
可以看到,虽然加上了empty标志,但值确实压入了栈尾。