2017-02-02 16 views
-2

我與我的朋友必須在C#中編寫程序,該程序計算牛頓的迭代並將其用於由我的朋友編寫的特殊ASM庫。圖書館的工作原理是因爲我們在c main函數的visual中運行這個asm代碼,並且我們得到了繪製牛頓分形的所有點。但是當我想在C#中運行函數時,我得到了表中的結果,並且當我想將此結果寫入代碼爲-1073740791(0xc0000409)的文件程序退出中,並且在文件中我有例如10000點或20000點(從170476)時,想從170076到170476的寫作號碼,它的工作..我不知道爲什麼會發生。內存或堆棧的一些問題?錯誤在C#中使用MASM庫時退出

DLL導入:

[DllImport(@"Dll_ASM.dll", CallingConvention = CallingConvention.Cdecl)] 
     static extern void countPointsInAsm(double[] PolynomialCoefficient, double[] fromIntervals, double[] toIntervals, double[] TableOfPixels); 

在任何CallingConvention是同樣的事情。

這裏的算法:
在C:

#define PIXELSWIDTH 436 
#define PIXELSHEIGHT 391 
#define TABLELENGTH 170476 

typedef struct 
{ 
    double real; 
    double imaginary; 
} Complex; 

Complex Add(Complex a, Complex b) 
{ 
    Complex result_complex; 
    result_complex.real = a.real + b.real; 
    result_complex.imaginary = a.imaginary + b.imaginary; 
    return result_complex; 
} 

Complex AddDouble(double a, Complex b) 
{ 
    Complex result_complex; 
    result_complex.real = a + b.real; 
    result_complex.imaginary = b.imaginary; 
    return result_complex; 
} 

Complex Sub(Complex a, Complex b) 
{ 
    Complex result_complex; 
    result_complex.real = a.real - b.real; 
    result_complex.imaginary = a.imaginary - b.imaginary; 
    return result_complex; 
} 

Complex Mul(Complex a, Complex b) 
{ 
    Complex result_complex; 
    result_complex.real = a.real*b.real - a.imaginary*b.imaginary; 
    result_complex.imaginary = a.real*b.imaginary + a.imaginary*b.real; 
    return result_complex; 
} 

Complex Div(Complex a, Complex b) 
{ 
    Complex result_complex; 
    result_complex.real = (a.real*b.real + a.imaginary*b.imaginary)/(b.real*b.real + b.imaginary*b.imaginary); 
    result_complex.imaginary = (a.imaginary*b.real - a.real*b.imaginary)/(b.real*b.real + b.imaginary*b.imaginary); 
    return result_complex; 
} 

double Abs(Complex z) 
{ 
    double result = sqrt((z.real*z.real) + (z.imaginary*z.imaginary)); 
    return result; 
} 

int* CountPointsInC(double PolynomialCoefficients[10], double Intervals[2][2]) 
{ 
    int counter = 0; 
    int iterations = 0; 
    int max_iterations = 1000; 
    double DerivativeCoefficients[9]; 
    Complex z; 
    Complex zp; 
    Complex polynomial_value; 
    Complex derivative_value; 
    int* result_table = (int*)malloc(sizeof(int)*TABLELENGTH); 
    for (int j = 0; j < PIXELSHEIGHT; j++) 
    { 
     for (int k = 0; k < PIXELSWIDTH; k++) 
     { 
      iterations = 0; 
      z.real = (Intervals[0][0] + k*((Intervals[1][0] - Intervals[0][0])/436)); 
      z.imaginary = (Intervals[0][1] + j*((Intervals[1][1] - Intervals[0][1])/391)); 
      for (int i = 0; i < 9; i++) 
      { 
       DerivativeCoefficients[i] = PolynomialCoefficients[i + 1] * (i + 1); 
      }; 

      do 
      { 
       polynomial_value.real = PolynomialCoefficients[9]; 
       polynomial_value.imaginary = 0; 
       derivative_value.real = DerivativeCoefficients[8]; 
       derivative_value.imaginary = 0; 
       for (int i = 8; i >= 0; i--) 
       { 
        polynomial_value = AddDouble(PolynomialCoefficients[i], Mul(polynomial_value, z)); 
       } 
       for (int i = 7; i >= 0; i--) 
       { 
        derivative_value = AddDouble(DerivativeCoefficients[i], Mul(derivative_value, z)); 
       } 
       iterations += 1; 
       zp = z; 
       z = Sub(z, (Div(polynomial_value, derivative_value))); 
      } while ((Abs(Sub(z, zp)) >= 0.01) && (iterations < max_iterations)); 
      result_table[counter] = iterations; 
      counter++; 
     } 
    } 
    return result_table; 
} 

在彙編語言類似:

.data 
    aReal REAL8 ? 
    bReal REAL8 ? 
    realResult REAL8 ? 
    aImaginary REAL8 ? 
    bImaginary REAL8 ? 
    imaginaryResult REAL8 ? 
    doubleNumber REAL8 ? 
    sqrtResult REAL8 ? 
    zReal REAL8 ? 
    zImaginary REAL8 ? 
    zpReal REAL8 ? 
    zpImaginary REAL8 ? 
    polynomialValueReal REAL8 ? 
    polynomialValueImaginary REAL8 ? 
    derivativeValueReal REAL8 ? 
    derivativeValueImaginary REAL8 ? 
    counter REAL4 0.0 
    iterations REAL4 1.0 
    maxIterations REAL4 1000.0 
    k dq 0 
    j dq 0 
    whileCondition REAL8 0.01 
    derivativeCoefficients REAL8 9 dup(?) 
.code 

addComplex PROC 
    ; adding real part 
    fld aReal ; load aReal into st0 
    fadd bReal ; aReal + bReal into st0 
    fstp realResult ; store into realResult 
    ; adding imaginary part 
    fld aImaginary ; load aImaginary into st0 
    fadd bImaginary ; aImaginary + bImaginary into st0 
    fstp imaginaryResult ; store into imaginaryResult 
addComplex ENDP 

addDouble PROC 
    ; adding real part 
    fld aReal ; load aReal into st0 
    fadd doubleNumber ; aReal + doubleNumber into st0 
    fstp realResult ; store into realResult 
    ; adding imaginary part 
    fld aImaginary ; load aImaginary into st0 
    fstp imaginaryResult ; store into imaginaryResult 
    ret 
addDouble ENDP 

subComplex PROC 
    ; subtracting real part 
    fld aReal ; load aReal into st0 
    fsub bReal ; aReal - bReal into st0 
    fstp realResult ; store into realResult 
    ; subtracting imaginary part 
    fld aImaginary ; load aImaginary into st0 
    fsub bImaginary ; aImaginary - bImaginary into st0 
    fstp imaginaryResult ; store into imaginaryResult 
    ret 
subComplex ENDP 

mulComplex PROC 
    ; multing real part 
    fld aReal ; load aReal into st0 
    fmul bReal ; aReal * bReal into st0 
    fld aImaginary ; load aImaginary into st0 and aReal * bReal into st1 
    fmul bImaginary ; aImaginary * bImaginary into st0 
    fsub st(1), st(0) ; aReal * bReal - aImaginary * bImaginary into st 0 
    fxch st(1) ; swap st1 with st0 
    fstp realResult ; store into realResult 
    ; multing imaginary part 
    fld aReal ; load aReal into st0 
    fmul bImaginary ; aReal * bImaginary into st0 
    fld aImaginary ; load aImaginary into st0 and aReal * bImaginary into st1 
    fmul bReal ; aImaginary * bReal into st0 
    fadd st(0), st(1) ; aReal * bImaginary + aImaginary * bReal into st 0 
    fstp imaginaryResult ; store into imaginaryResult 
    ret 
mulComplex ENDP 

divComplex PROC 
    ; diving real part 

    fld aReal ; load aReal into st0 
    fmul bReal ; aReal * bReal into st0 
    fld aImaginary ; load aImaginary into st0 and aReal * bReal into st1 
    fmul bImaginary ; aImaginary * bImaginary into st0 
    fadd st(0), st(1) ; aReal * bReal + aImaginary * bImaginary into st0 

    fld bReal ; load bReal into st0 
    fmul bReal ; bReal * bReal into st0 
    fld bImaginary ; load bImaginary into st0 
    fmul bImaginary ; bImaginary * bImaginary into st0 
    fadd st(0), st(1) ; bReal * bReal + bImaginary * bImaginary into st0 

    fdiv st(2), st(0) ; aReal * bReal + aImaginary * bImaginary/bReal * bReal + bImaginary * bImaginary into st0 
    fxch st(2) ; swap st2 with st0 
    fstp realResult ; store into realResult 

    ; diving imaginary part 
    fld aImaginary ; load aImaginary into st0 
    fmul bReal ; aImaginary * bReal into st0 
    fld aReal ; load aImaginary into st0 and aImaginary * bReal into st1 
    fmul bImaginary ; aReal * bImaginary into st5 
    fsub st(1), st(0) ; aImaginary * bReal - aReal * bImaginary into st1 
    fxch st(1) ; swap st1 with st0 

    fld bReal ; load bReal into st0 
    fmul bReal ; bReal * bReal into st0 
    fld bImaginary ; load bImaginary into st0 
    fmul bImaginary ; bImaginary * bImaginary into st0 
    fadd st(0), st(1) ; bReal * bReal + bImaginary * bImaginary into st0 

    fdiv st(2), st(0) ; aImaginary * bReal - aReal * bImaginary/bReal * bReal + bImaginary * bImaginary into st2 
    fxch st(2) ; swap st2 with st0 
    fstp imaginaryResult ; store into imaginaryResult 
    ret 
divComplex ENDP 

absComplex PROC 
    fld aReal ; load aReal into st0 
    fmul aReal ; aReal * aReal into st0 
    fld aImaginary ; load aImaginary into st0 and aImaginary * bImaginary in3to st1 
    fmul aImaginary ; aImaginary * aImaginary into st0 
    fadd st(0), st(1) ; aReal * aReal + aImaginary * aImaginary into st0 
    fsqrt ; compute square root and store to st0 
    fstp sqrtResult ; store into sqrtResult 
    ret 
absComplex ENDP 

countPointsInAsm PROC 
    mov R13, RCX ; save pointer to PolynomialCoefficients table into R13 
    mov R14, RDX ; save pointer to "fromTable" into R14 
    mov R15, R8 ; save pointer to "toTable" into R15 

    mov RBX, R13 ; pointer to PolynomialCoefficients to RBX 
    mov RCX, 9 ; set loop counter 
    lea RAX, derivativeCoefficients ; pointer to derivativeCoefficients to RAX 
    xor RDI, RDI ; zero into RDI 
    derivativeCoefficientsLoop: 
     fld REAL8 ptr[RBX+8] ; load PolynomialCoefficients[i + 1] 
     fmul iterations ; PolynomialCoefficients[i + 1] * (i + 1); 
     fstp REAL8 ptr[RAX+RDI] 
     mov R12, [RAX+RDI] 
     fld iterations ; iterations to st(0) 
     fld1 ; 1 to st(0) and iterations to st(1) 
     faddp ; iterations + 1 
     fstp iterations 
     add RDI, 8 
     add RBX, 8 
    loop derivativeCoefficientsLoop 
    xor RDI, RDI ; zero into RDI 

    mov RCX, 391 ; set outer loop counter 
    mainOuterLoop: 
     push RCX 
     mov RCX, 436 ; set inner loop counter 
     mainInnerLoop: 

      fld REAL8 ptr[R15] ; load Interval[1][0] 
      fsub REAL8 ptr[R14] ; Interval[1][0] - Interval[0][0] 
      fmul k ; k*(Interval[1][0] - Interval[0][0]) 
      push k 
      mov k, 436 
      fdiv k ; k*(Interval[1][0] - Interval[0][0])/436 
      pop k 
      fadd REAL8 ptr[R14] ; Interval[0][0] + k*(Interval[1][0] - Interval[0][0])/436 
      fstp zReal 

      fld REAL8 ptr[R14+8] ; load Interval[1][1] 
      fsub REAL8 ptr[R15+8] ; Interval[1][1] - Interval[0][1] 
      fmul j ; j*(Interval[1][1] - Interval[0][1]) 
      push j 
      mov j, 391 
      fdiv j ; j*(Interval[1][1] - Interval[0][1])/391 
      pop j 
      fadd REAL8 ptr[R15+8] ; Interval[1][1] + j*(Interval[0][1] - Interval[1][1])/391 
      fstp zImaginary 

      mov iterations, 0 ; zero into iterations 

      doWhileLoop: 
       fld REAL8 ptr[R13+72] ; load PolynomialCoefficients[9] 
       fstp polynomialValueReal ; store into polynomialValueReal 
       mov polynomialValueImaginary, 0 ; zero into polynomialValueImaginary 

       lea RAX, derivativeCoefficients ; pointer to derivativeCoefficients to RAX 
       fld REAL8 ptr[RAX+64] ; load derivativeCoefficients[8] 
       fstp derivativeValueReal ; store into derivativeValueReal 
       mov derivativeValueImaginary, 0 ; zero into derivativeValueImaginary 

       push RCX 
       mov RCX, 9 ; set polynomialValueLoop counter 
       polynomialValueLoop: 
        fld polynomialValueReal ; load polynomialValueReal 
        fstp aReal ; store into aReal 
        fld polynomialValueImaginary ; load polynomialValueImaginary 
        fstp aImaginary ; store into aImaginary 
        fld zReal ; load zReal 
        fstp bReal ; store into bReal 
        fld zImaginary ; load zImaginary 
        fstp bImaginary ; store into bImaginary 
        call mulComplex ; Mul(polynomial_value, z) 
        fld realResult ; load realResult 
        fstp aReal ; store into aReal 
        fld imaginaryResult ; load imaginaryResult 
        fstp aImaginary ; store into aImaginary 

        mov RBX, RCX ; loop counter to RBX 
        dec RBX 
        imul RBX, 8 ; memory locations of PolynomialCoefficients[i-1] 
        fld REAL8 ptr[R13+RBX] ; load PolynomialCoefficients[i-1] 
        fstp doubleNumber ; store into aReal 
        call addDouble ; AddDouble(PolynomialCoefficients[i-1], Mul(polynomial_value, z)) 
        fld realResult ; load realResult 
        fstp polynomialValueReal ; store into polynomialValueReal 
        fld imaginaryResult ; load imaginaryResult 
        fstp polynomialValueImaginary ; store into polynomialValueImaginary 
        finit 
       DEC RCX 
       CMP RCX, 0 
       JNE polynomialValueLoop 

       mov RCX, 8 ; set derivativeValueLoop counter 
       derivativeValueLoop: 
        fld derivativeValueReal ; load derivativeValueReal 
        fstp aReal ; store into aReal 
        fld derivativeValueImaginary ; load derivativeValueImaginary 
        fstp aImaginary ; store into aImaginary 
        fld zReal ; load zReal 
        fstp bReal ; store into bReal 
        fld zImaginary ; load zImaginary 
        fstp bImaginary ; store into bImaginary 
        call mulComplex ; Mul(derivative_value, z) 
        fld realResult ; load realResult 
        fstp aReal ; store into aReal 
        fld imaginaryResult ; load imaginaryResult 
        fstp aImaginary ; store into aImaginary 

        mov RBX, RCX ; loop counter to RBX 
        dec RBX 
        imul RBX, 8 ; memory locations of DerivativeCoefficients[i-1] 
        fld REAL8 ptr[RAX+RBX] ; load DerivativeCoefficients[i-1] 
        fstp doubleNumber ; store into aReal 
        call addDouble ; AddDouble(DerivativeCoefficients[i-1], Mul(derivative_value, z)) 
        fld realResult ; load realResult 
        fstp derivativeValueReal ; store into polynomialValueReal 
        fld imaginaryResult ; load imaginaryResult 
        fstp derivativeValueImaginary ; store into polynomialValueImaginary 
        finit 
       DEC RCX 
       CMP RCX, 0 
       JNE derivativeValueLoop 
       pop RCX 

       fld1 ; load 1 
       fadd iterations ; iterations + 1 
       fstp iterations ; store into iterations 

       fld zReal ; load zReal 
       fstp zpReal ; store into zpReal 
       fld zImaginary ; load zImaginary 
       fstp zpImaginary ; store into zpImaginary 

       fld polynomialValueReal ; load polynomialValueReal 
       fstp aReal ; store into aReal 
       fld polynomialValueImaginary ; load polynomialValueImaginary 
       fstp aImaginary ; store into aImaginary 
       fld derivativeValueReal ; load derivativeValueReal 
       fstp bReal ; store into bReal 
       fld derivativeValueImaginary ; load derivativeValueImaginary 
       fstp bImaginary ; store into bImaginary 
       call divComplex ; Div(polynomial_value, derivative_value) 
       fld realResult ; load realResult 
       fstp bReal ; store into bReal 
       fld imaginaryResult ; load imaginaryResult 
       fstp bImaginary ; store into bImaginary 
       fld zReal ; load zReal 
       fstp aReal ; store into aReal 
       fld zImaginary ; load zImaginary 
       fstp aImaginary ; store into aImaginary 
       call subComplex ; Sub(z, (Div(polynomial_value, derivative_value))) 
       fld realResult ; load realResult 
       fstp zReal ; store into zReal 
       fld imaginaryResult ; load imaginaryResult 
       fstp zImaginary ; store into zImaginary 

       fld zReal ; load zReal 
       fstp aReal ; store into aReal 
       fld zImaginary ; load zImaginary 
       fstp aImaginary ; store into aImaginary 
       fld zpReal ; load zpReal 
       fstp bReal ; store into bReal 
       fld zpImaginary ; load zpImaginary 
       fstp bImaginary ; store into bImaginary 
       call subComplex ; Sub(z, zp) 
       fld realResult ; load realResult 
       fstp aReal ; store into aReal 
       fld imaginaryResult ; load imaginaryResult 
       fstp aImaginary ; store into aImaginary 
       call absComplex ; (Abs(Sub(z, zp)) 
       finit 

       fld sqrtResult ; load sqrtResult 
       fcomp whileCondition ; compare sqrtResult with 0.01 
       fstsw AX 
       sahf 
       jb toEnd; if sqrtResult < 0.01 end doWhileLoop 

       fld iterations ; load iterations as int 
       fcomp maxiterations ; compare iterations with maxiterations 
       fstsw AX 
       sahf 
       jb doWhileLoop ; if iterations >= maxiterations end doWhileLoop 
      toEnd: 
      fld iterations ; load iterations 
      mov RAX, R9 ; pointer to resultTable to RAX 
      fstp REAL8 ptr[RAX+RDI] ; add iterations to resultTable: result_table[counter] = iterations 
      add RDI, 8 

      fld1 ; load 1 
      fadd counter ; counter + 1 
      fstp counter ; store into counter 

      inc k 
     dec RCX 
     cmp RCX, 0 
     JNE mainInnerLoop 

     inc j 
     mov k, 0 
     pop RCX 
    dec RCX 
    cmp RCX, 0 
    JNE mainOuterLoop 
    ret 
countPointsInAsm ENDP 
end 

我想我也不能降低代碼的大小。 之前我們遇到了FPU​​堆棧的問題,因爲寄存器是溢出的,但是使用clear:'finit'有幫助。

+1

這是STATUS_STACK_BUFFER_OVERRUN,一個非常嚴重的事故總是會立即終止應用程序。不在C程序中獲取診斷並不意味着該錯誤不存在,它可能很容易錯過,因爲您沒有使用/ GS進行編譯,或者腐敗沒有損壞任何關鍵的東西。破壞堆棧在彙編代碼中很容易做到。我們看不到它。 –

+0

請包含[mcve],即彙編代碼。 –

回答

1

每個調用約定都要求您必須按下彈出要在函數中更改的CPU寄存器。你做得到嗎?在您的asm代碼和流行指令結束時,我看不到推送說明。您可以安全地使用eax/rax等幾個,但不是全部。請參閱C調用約定的文檔以查看完整列表。

更新:我發現這篇關於64位代碼中的寄存器的MSDN文章。您必須手動按下彈出標記爲的所有寄存器,保存爲https://msdn.microsoft.com/en-us/library/6t169e9c.aspx

+0

它在某些方面有幫助,現在我得到錯誤005'訪問衝突'。我讀過它可能是ptr數組的問題,但我沒有注意到代碼中存在這樣的問題。我需要以特殊的方式在C#中傳遞數組嗎? MASM是否寫入這個數組? – sebax

+0

使用調試器查找哪個數組指針導致訪問衝突。 –

+0

這是我的堆棧愚蠢的錯誤。一切都是正確的,並有效。非常感謝你。推送和彈出寄存器是解決方案。 – sebax