1

for example,i want to edit st(2)

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

that is my wrong way st(0,1,2) will be qnan

Peter Cordes
  • 328,167
  • 45
  • 605
  • 847

1 Answers1

2

If the x87 register stack isn't already full (all 8 regs), you can load a new value into st0 and then copy between x87 registers.

; 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

The last instruction copies st0 to st3, then pops the x87 stack to discard st0, bringing the st3,2,1 down to their original st2,1,0 positions.

See http://www.ray.masmcode.com/tutorial/index.html for details on how the x87 register stack works, and what the instructions do, with examples.


In general you can use fxch to swap a value into st0 where you can modify do stuff with it, like fadd to it. Or here, discard it and load a new value, even if st0..7 were all in use previously.

  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

If you're getting QNaN when you didn't expect it from fld, that's often a sign you unbalanced the x87 stack. fld when the destination is already "in use" will set st0 = NaN. As http://www.ray.masmcode.com/tutorial/fpuchap4.htm puts it:

If the ST(7) data register which would become the new ST(0) is not empty, both a Stack Fault and an Invalid operation exceptions are detected, setting both flags in the Status Word. The TOP register pointer in the Status Word would still be decremented and the new value in ST(0) would be the INDEFINITE NAN (which is a QNaN).


Also, if you did need to store to memory, it's very unlikely that you'd want to store each dword or qword 256 bytes apart. (If those are even hex? You didn't use a trailing h or leading 0x). qword [esp+0] / qword [esp+4] / qword [esp+8] would make way more sense.

Peter Cordes
  • 328,167
  • 45
  • 605
  • 847