1

一般来说,我对组装很陌生,尤其是对 FPU 的使用。

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

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

循环中发生了一些事情,对 (mean - element)^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
4

1 回答 1

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
于 2012-05-12T19:45:28.043 回答