В следующий раз, пожалуйста, разместите свои попытки комментариев рядом с разборкой. Мне нужно много времени, чтобы напечатать все, чтобы посмотреть, окажусь ли я там же, где и вы. Кроме того, существует целый обмен стеками для обратного проектирования. Я обычно не смотрю на него, но там есть несколько хороших экспертов по x86.
скажем, v1 = contents of addr1
и 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
Итак, в конце концов, st(0) = e^[address1]
с двумя другими значениями, оставшимися в стеке FP. (Содержимое остальной части стека FP и его глубина — это огромный вопрос, который вы упустили из анализа. Вставки и извлечения стека FP должны быть сбалансированы (за исключением того, что возвращаемое значение остается в st(0)
), так что может служить проверкой того, правильно ли вы отследили фрагмент кода.)
AFAICT, v2 остается в стеке FP в конце этого и не используется в расчетах. Похоже, у вас было 2 лишних щелчка в вашей трассировке.
person
Peter Cordes
schedule
09.08.2015