What is the result of the following assembly code?
fld qword ptr [address2]
fld qword ptr [address1]
fldl2e
fmulp ST(1),ST
fld ST(0)
frndint
fxch ST(1)
fsub ST,ST(1)
f2xm1
fld1
faddp ST(1),ST
fscale
Here, I don't understand what this code is doing. What I have interpreted is as following:
value[address2]^(2^(value[address1]*log2(e)-roundf(value[address1]*log2(e))))
Which does not make sense. Could someone please correct me?
Next time please post you attempted comments next to the disassembly. It's taking a long time to type everything out to see if I end up at the same place as you. Also, there's a whole stackexchange for reverse engineering. I don't usually look at it, but there are some good x86 experts there.
let's say v1 = contents of addr1
and v2 = ... [addr2]
.
fld qword ptr [address2] ; st(0) = v2
fld qword ptr [address1] ; st(0) = v1, st(1) = v2
fldl2e ; st0 = l2e = log_2(e); st1=v1 st2=v2
fmulp ST(1),ST ; st0 = v1*l2e; st2=v2
fld ST(0) ; st0 = v1*l2e; st1=v1*l2e st2=v2
frndint ; st0 = round(v1*l2e); st1=v1*l2e st2=v2
fxch ST(1) ; st0 = v1*l2e; st1=round(v1*l2e) st2=v2
; careful here, this is fsub, NOT fsubp
fsub ST,ST(1) ; st0 = v1*l2e - round(v1*l2e) = fractional part of v1*l2e = v1l2efrac; st1=round(v1*l2e) st2=v2
f2xm1 ; st0 = 2^(v1l2efrac)-1; st1=round(v1*l2e) st2=v2
fld1 ; st0 = 1.0; st1 = 2^(v1l2efrac)-1 st2=round(v1*l2e) st3=v2
faddp ST(1),ST ; st0 = 1.0 + 2^(v1l2efrac)-1 = 2^v1l2efrac; st1=round(v1*l2e) st2=v2
; st0 = 2^v1l2efrac; st1=round(v1*l2e); st2=v2
fscale ; st0 = 2^v1l2efrac * 2^round(v1*l2e); st1=round(v1*l2e) st2=v2
; st0 = 2^(v1l2efrac + round(v1*l2e)); st1=round(v1*l2e) st2=v2
; simplify: fractional part + integer part = whole
; st0 = 2^(v1*l2e); st1=round(v1*l2e) st2=v2
; simplify: x^y = 2^(y * log2(x))
; st0 = e^v1; st1=round(v1*l2e) st2=v2
So in the end, st(0) = e^[address1]
, with 2 other values still on the FP stack. (The contents of the rest of the FP stack, and how deep it is, is a huge point which you left out of your analysis. FP stack pushes and pops have to balance (except for leaving a return value in st(0)
), so that can act as a check on whether you've correctly traced a piece of code.)
AFAICT, v2 is left on the FP stack at the end of this, and unused in the calculation. It looks like you had 2 extra pops in your tracing.