assembly 如何在fpu中编辑st(x)?当x>0时

zxlwwiss  于 2022-11-30  发布在  其他
关注(0)|答案(1)|浏览(119)

例如,我想编辑st(2)

fstp [00777700]
fstp [00777800]
fstp [00777900]
mov [00777900],xxx
fld [00777900]
fld [00777800]
fld [00777700]

这是我的错误方式st(0,1,2)将是qnan

vngu2lb8

vngu2lb81#

如果x87寄存器堆栈尚未满(所有8个寄存器),则可以将新值加载到st 0中,然后在x87寄存器之间进行复制。

; 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

最后一条指令将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之前都在使用。

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

如果您从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]会更有意义。

相关问题