; requires that st7 is free before this
fld qword [new_val] ; requires that at most 7 st regs were in use
fstp st(3) ; replace st3 which was originally st2, and pop
fxch st(2) ; swap st0 and st2
fstp st(0) ; discard it with a pop after storing to itself
fld qword [new_value] ; push a new value into st0
fxchg st(2) ; swap it back to st2
1条答案
按热度按时间vngu2lb81#
如果x87寄存器堆栈尚未满(所有8个寄存器),则可以将新值加载到st 0中,然后在x87寄存器之间进行复制。
最后一条指令将st 0复制到st 3,然后弹出x87堆栈以丢弃st 0,将st 3,2,1向下带到它们原来的st 2,1,0位置。
如需有关x87寄存器堆栈运作方式、指令功能的详细信息及范例,请参阅http://www.ray.masmcode.com/tutorial/index.html。
一般来说,你可以使用
fxch
将一个值交换到st0
中,在st0
中你可以对它进行修改,比如fadd
。或者在这里,丢弃它并加载一个新值,即使st0..7之前都在使用。如果您从
fld
中意外获得QNaN,这通常是您不平衡x87堆栈的信号。当目标已经“在使用中”时,fld
将设置st 0 = NaN。正如http://www.ray.masmcode.com/tutorial/fpuchap4.htm所言:如果将成为新ST(0)的ST(7)数据寄存器不为空,则检测到StackFault和Invalid操作异常,并在状态字中设置这两个标志。状态字中的TOP寄存器指针仍将递减,ST(0)中的新值将为INDEFINITE NAN(即QNaN)。
此外,如果确实需要存储到内存中,您不太可能希望将每个dword或qword相隔256个字节进行存储。(如果它们是十六进制的,您没有使用尾随
h
或前导0x
)。qword [esp+0]
/qword [esp+4]
/qword [esp+8]
会更有意义。