装配FPU Stack Breaking;结果为-1。#IND

时间:2012-05-12 19:30:08

标签: assembly x86 stack nan fpu

我对装配很新,特别是对FPU的使用。

我正在为学校写一份计算一组随机数的标准偏差的作业。

加载数组,平均计算工作正常。整个过程适用于7个或更小值的数组,但返回-1。#IND(这意味着NaN?),数组大小为8或更多元素。

循环中发生的事情是(均值 - 元素)^ 2值的总和。我不确定发生了什么,但我假设FPU堆栈在某种程度上有所破坏。

如果有人能指出我正确的方向,我会非常高兴。

fla = REAL8

; STD DEVIATION
stdDev:
        call    meanCalcFunc            ; fmean = loaded

        mov     ebx, offset array1      ; Location of Element into EBX
        mov     ecx, [esp+4]            ; ECX = num of elements in array
        mov     mem1, 0                 ; Mem1 = 0
        fld     mem1                    ; ST = 0
        fstp    fla                     ; fla = ST = 0

mainFunc:
        mov     eax, [ebx]              ; Array Element into EAX
        mov     mem1, eax               ; Array Element into mem1
        fld     fmean                   ; ST = mean of array

        fisub   mem1                    ; mean - element -> ST

        fld     ST                      ; Now ST and ST(1) = difference of mean - element
        fmulp   ST(1), ST               ; Difference^2 in ST(1)

        fld     ST(1)                   ; Copy Difference^2 to ST

        fadd    fla                     ; FLA += Difference^2
        fstp    fla                 

        add     ebx, 4                  ; Move to next element in array
        loop    mainFunc

        fld     fla                     ; ST = Sum of squares

        mov     ecx, [esp+4]            ; Num of elements to ECX
        mov     mem1, ecx               ; Num of elements to mem1

        fidiv   mem1                    ; ST = Sum of squares / num of elements

        fst     fla

        fsqrt                           ; ST = final result

        fstp    fla                     ; flb = final result

        INVOKE _gcvt, fla, 8, ADDR outstring
        output  devlbl, outstring

        ret

1 个答案:

答案 0 :(得分:5)

你的循环包含不平衡的加载和弹出数量,因此每次循环迭代在x87堆栈上再留下一个项目。当堆栈溢出时,您将获得您正在观察的结果。别这么做。

instruction        elements on stack
-------------------------------------------
mainFunc:          k
fld     fmean      k + 1
fisub   mem1       k + 1
fld     ST         k + 2
fmulp   ST(1), ST  k + 1
fld     ST(1)      k + 2
fadd    fla        k + 2
fstp    fla        k + 1
loop    mainFunc   k + 1