2012-05-12 2 views
1

저는 일반적으로 어셈블리, 특히 FPU를 사용하는 데 익숙합니다.어셈블리 FPU 스택 속보; 결과는 -1입니다. # IND

나는 임의의 숫자 배열의 표준 편차를 계산하는 학교 과제를 쓰고 있습니다.

배열이로드되어 평균 계산이 정상적으로 작동합니다. 전체 프로세스는 7 개 이하의 값으로 구성된 배열에 대해 작동하지만, 8 개 이상의 배열 크기에 대해 -1 IND # (NaN?을 의미)를 반환합니다.

(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 
+0

FPU 스택을 모두 사용한 것 같습니다. "* 스택 오버플로라는 용어는 프로그램이 메모리에서 x87 FPU 레지스터 스택으로 8 개의 값을로드 (푸시)하고 스택에 푸시 된 다음 값이 이미 값이 들어있는 레지스터로 스택 랩 어라운드를 발생시키는 상황에서 기인합니다. 무효 연산 예외가 가면 x87 FPU **는 실행중인 명령어에 따라 부동 소수점, 정수 또는 패킹 된 10 진 정수 무제한 값 **을 대상 피연산자에 반환합니다. * " – DCoder

+0

그래, 생각. 그러나 나는 내가 할 수있을 때 내가로드 한 대부분의 값을 터뜨리려고 노력했다. 스택의 일부를 비울 수있는 다른 방법이 있습니까? – QuestionablePurple

답변

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 
+0

와우, 놀라 울 정도로 상세한 답변. 나는 루프 내에서 다른 팝을 던지면서 그것을 고쳤다. 정말 고맙습니다. – QuestionablePurple