Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi asm MulDiv64 C übersetzung stürzt ab ... (https://www.delphipraxis.net/108762-asm-muldiv64-c-uebersetzung-stuerzt-ab.html)

stoxx 19. Feb 2008 05:21


asm MulDiv64 C übersetzung stürzt ab ...
 
beim Übersetzen eines C Quelltextes tritt noch ein GleitkommadivisionsFehler auf...
Wissen die Assembler Profis mehr?
Vielen Dank schonmal !!


Delphi-Quellcode:


type Var128 = packed record
 DW : array[0..3] of DWORD;
end;

function xMulDiv64(operant, multiplier, divider : int64) : int64; stdcall;
var
  quotient : Var128;

//   // Declare 128bit storage
//   struct{
//      unsigned long DW[4];
//   }var128, quotient;
//   // Change semantics for intermediate results for Full Div
//   // by renaming the vars
//   #define REMAINDER quotient
//   #define QUOTIENT edi
begin


asm

      mov      eax, dword ptr[operant+4]
      xor      eax, dword ptr[multiplier+4]
      xor      eax, dword ptr[divider+4]
      pushfd
end;



   // Take absolute values because algorithm is for unsigned only
   operant      := ABS(operant);
   multiplier   := ABS(multiplier);
   divider      := ABS(divider);

asm

      // First check divider for 0
      mov      eax, dword ptr[divider+4]
      or      eax, dword ptr[divider]
      jnz      @@dividerOK
      div      eax
@@dividerOK:
      lea      edi,[var128]               // edi = &var128
      // Check multiplier for 1 or 0
      xor      eax, eax
      cmp      eax, dword ptr[multiplier+4]
      jnz      @@startMUL
      cmp      eax, dword ptr[multiplier]
      jnz      @@multiNotNUL
      xor      edx, edx
      popfd                           // cleanup stack
      jmp      @@done
@@multiNotNUL:
      // Set result HI part to 0
      xor      eax,eax
      mov      dword ptr[edi+12], eax
      mov      dword ptr[edi+8], eax
      mov      eax, 1
      cmp      eax, dword ptr[multiplier]
      jnz      @@smallMUL
      // Multiplier is 1 so just copy operant to result
      mov      eax, dword ptr[operant+4]
      mov      dword ptr[edi+4], eax
      mov      eax, dword ptr[operant]
      mov      dword ptr[edi], eax
      jmp      @@startDIV
@@smallMUL:
      // Test for 32/32 bit multiplication
        xor      eax, eax
        mov      ecx, dword ptr[operant+4]
        or     ecx, eax        //;test for both hiwords zero.
      jnz      @@startMUL
      // Do 32/32 bit multiplication
        mov      ecx, dword ptr[multiplier]
      mov      eax, dword ptr[operant]
      mul      ecx
      mov      dword ptr[edi+4], edx
      mov      dword ptr[edi], eax
      jmp      @@startDIV
@@startMUL:
      // Check signs
      // Multiply: var128 = operant * multiplier
      mov      eax, dword ptr[multiplier]      // eax = LO(multiplier)
      mul      dword ptr[operant]            // edx:eax = eax * LO(operant)
      mov      dword ptr[edi], eax            // var128.DW0 = eax
      mov      ecx, edx                  // ecx = edx

      mov      eax, dword ptr[multiplier]      // eax = LO(multiplier)
      mul      dword ptr[operant+4]         // edx:eax = eax * HI(operant)
      add      eax, ecx                  // eax = eax + ecx
      adc      edx, 0                     // edx = edx + 0 + carry
      mov      ebx, eax
      mov      ecx, edx

      mov      eax, dword ptr[multiplier+4]
      mul      dword ptr[operant]
      add      eax, ebx
      mov      dword ptr[edi+4], eax
      adc      ecx, edx
      pushfd

      mov      eax, dword ptr[multiplier+4]
      mul      dword ptr[operant+4]
      popfd
      adc      eax, ecx
      adc      edx, 0
      mov      dword ptr[edi+8], eax
      mov      dword ptr[edi+12], edx
@@startDIV:
      // Divide: var128 = var128 / divider
      //
      // Test divider = 32bit value
      mov      eax, dword ptr[divider+4]
      cmp      eax, 0
      jnz      @@fullDIV
      mov      ecx, dword ptr[divider]
      cmp      ecx, 1
      jz      @@applySign

      // Start 128/32 bit division
      mov      eax, dword ptr[edi+12]
      xor      edx, edx
      div      ecx
      mov      dword ptr[quotient+12], eax

      mov      eax, dword ptr[edi+8]
      div      ecx
      mov      dword ptr[quotient+8], eax

      mov      eax, dword ptr[edi+4]
      div      ecx
      mov      dword ptr[quotient+4], eax

      mov      eax, dword ptr[edi]
      div      ecx
      mov      dword ptr[quotient], eax
      
      // Copy the quotient to the result storage (var128)
      mov      eax, dword ptr[quotient+12]
      mov      dword ptr[edi+12], eax
      mov      eax, dword ptr[quotient+8]
      mov      dword ptr[edi+8], eax
      mov      eax, dword ptr[quotient+4]
      mov      dword ptr[edi+4], eax
      mov      eax, dword ptr[quotient]
      mov      dword ptr[edi], eax
      // To sign correction and return
      jmp      @@applySign

@@fullDIV:
      // Full 128/64 bit division
      xor      eax, eax
      mov      dword ptr[quotient+12], eax
      mov      dword ptr[quotient+8], eax
      mov      dword ptr[quotient+4], eax
      mov      dword ptr[quotient], eax

      mov      ecx, 128
@@loop1:
      // Compute REMAINDER:QUOTIENT = REMAINDER:QUOTIENT shl 1
      shl      dword ptr[edi], 1
      rcl      dword ptr[edi+4], 1
      rcl      dword ptr[edi+8], 1
      rcl      dword ptr[edi+12], 1
      rcl      dword ptr[quotient], 1
      rcl      dword ptr[quotient+4], 1
      rcl      dword ptr[quotient+8], 1
      rcl      dword ptr[quotient+12], 1

      // Test (REMAINDER >= Divider)
      xor      eax, eax
      cmp      dword ptr[quotient+12], eax
      ja      @@iftrue
      jb      @@iffalse

      cmp      dword ptr[quotient+8], eax
      ja      @@iftrue
      jb      @@iffalse

      mov      eax, dword ptr[quotient+4]
      cmp      eax, dword ptr[divider+4]
      ja      @@iftrue
      jb      @@iffalse

      mov      eax, dword ptr[quotient]
      cmp      eax, dword ptr[divider]
      jb      @@iffalse
@@iftrue:
      // Remainder = remainder - divider
      mov      eax, dword ptr[divider]
      sub      dword ptr[quotient], eax
      mov      eax, dword ptr[divider+4]
      sbb      dword ptr[quotient+4], eax
      xor      eax, eax
      sbb      dword ptr[quotient+8], eax
      sbb      dword ptr[quotient+12], eax
      // Quotient = quotient +1
      add      dword ptr[edi], 1
      adc      dword ptr[edi+4], 0
      adc      dword ptr[edi+8], 0
      adc      dword ptr[edi+12], 0
@@iffalse:
      // Loop size = 101 bytes, is less than 127 so loop is possible
      loop   @@loop1

@@applySign:
      // Correct the sign of the result based on the stored combined sign
      popfd
      jns      @@storeRes
      not      dword ptr[edi+12]
      not      dword ptr[edi+ 8]
      not      dword ptr[edi+ 4]
      not      dword ptr[edi]
      add      dword ptr[edi], 1
      adc      dword ptr[edi+ 4], 0
      adc      dword ptr[edi+ 8], 0
      adc      dword ptr[edi+12], 0

@@storeRES:
      // Get low order qword from var128
      mov      edx, dword ptr[edi+4]
      mov      eax, dword ptr[edi]
@@done:
   
   // result is returned in edx:eax
END;
end;


Delphi-Quellcode:
/*
 *   Source file:      MulDiv64.cpp
 *   Author:            Richard van der Wal
 *   Contact:         [email]R.vdWal@xs4all.nl[/email]
 *
 *   Description:
 *      Implementation for MulDiv64 and MulShr64
 *
 *   $Log: $
 */


/*
 * MulDiv64
 * Multiplies an operant by a multiplier and divides the result by a divider
 * Used for scaling 64 bit integer values
 *     Xscaled = Xstart * Multiplier / Divider
 * Uses 128 bit intermediate result
 */
#define ABS64(num) (num >=0 ? num : -num)
//
__int64 _stdcall MulDiv64(__int64 operant, __int64 multiplier, __int64 divider)
{
   // Declare 128bit storage
   struct{
      unsigned long DW[4];
   }var128, quotient;
   // Change semantics for intermediate results for Full Div
   // by renaming the vars
   #define REMAINDER quotient
   #define QUOTIENT edi

   // Save combined sign on stack
   _asm{
      mov      eax, dword ptr[operant+4]
      xor      eax, dword ptr[multiplier+4]
      xor      eax, dword ptr[divider+4]
      pushfd
   }

   // Take absolute values because algorithm is for unsigned only
   operant      = ABS64(operant);
   multiplier   = ABS64(multiplier);
   divider      = ABS64(divider);

   _asm{
      // First check divider for 0
      mov      eax, dword ptr[divider+4]
      or      eax, dword ptr[divider]
      jnz      dividerOK
      div      eax
dividerOK:
      lea      edi,[var128]               // edi = &var128
      // Check multiplier for 1 or 0
      xor      eax, eax
      cmp      eax, dword ptr[multiplier+4]
      jnz      startMUL
      cmp      eax, dword ptr[multiplier]
      jnz      multiNotNUL
      xor      edx, edx
      popfd                           // cleanup stack
      jmp      done
multiNotNUL:
      // Set result HI part to 0
      xor      eax,eax
      mov      dword ptr[edi+12], eax
      mov      dword ptr[edi+8], eax
      mov      eax, 1
      cmp      eax, dword ptr[multiplier]
      jnz      smallMUL
      // Multiplier is 1 so just copy operant to result
      mov      eax, dword ptr[operant+4]
      mov      dword ptr[edi+4], eax
      mov      eax, dword ptr[operant]
      mov      dword ptr[edi], eax
      jmp      startDIV
smallMUL:
      // Test for 32/32 bit multiplication
        xor      eax, eax
        mov      ecx, dword ptr[operant+4]
        or     ecx, eax        ;test for both hiwords zero.
      jnz      startMUL
      // Do 32/32 bit multiplication
        mov      ecx, dword ptr[multiplier]
      mov      eax, dword ptr[operant]
      mul      ecx
      mov      dword ptr[edi+4], edx
      mov      dword ptr[edi], eax
      jmp      startDIV
startMUL:
      // Check signs
      // Multiply: var128 = operant * multiplier
      mov      eax, dword ptr[multiplier]      // eax = LO(multiplier)
      mul      dword ptr[operant]            // edx:eax = eax * LO(operant)
      mov      dword ptr[edi], eax            // var128.DW0 = eax
      mov      ecx, edx                  // ecx = edx

      mov      eax, dword ptr[multiplier]      // eax = LO(multiplier)
      mul      dword ptr[operant+4]         // edx:eax = eax * HI(operant)
      add      eax, ecx                  // eax = eax + ecx
      adc      edx, 0                     // edx = edx + 0 + carry
      mov      ebx, eax
      mov      ecx, edx

      mov      eax, dword ptr[multiplier+4]
      mul      dword ptr[operant]
      add      eax, ebx
      mov      dword ptr[edi+4], eax
      adc      ecx, edx
      pushfd

      mov      eax, dword ptr[multiplier+4]
      mul      dword ptr[operant+4]
      popfd
      adc      eax, ecx
      adc      edx, 0
      mov      dword ptr[edi+8], eax
      mov      dword ptr[edi+12], edx
startDIV:
      // Divide: var128 = var128 / divider
      //
      // Test divider = 32bit value
      mov      eax, dword ptr[divider+4]
      cmp      eax, 0
      jnz      fullDIV
      mov      ecx, dword ptr[divider]
      cmp      ecx, 1
      jz      applySign

      // Start 128/32 bit division
      mov      eax, dword ptr[edi+12]
      xor      edx, edx
      div      ecx
      mov      dword ptr[quotient+12], eax

      mov      eax, dword ptr[edi+8]
      div      ecx
      mov      dword ptr[quotient+8], eax

      mov      eax, dword ptr[edi+4]
      div      ecx
      mov      dword ptr[quotient+4], eax

      mov      eax, dword ptr[edi]
      div      ecx
      mov      dword ptr[quotient], eax
      
      // Copy the quotient to the result storage (var128)
      mov      eax, dword ptr[quotient+12]
      mov      dword ptr[edi+12], eax
      mov      eax, dword ptr[quotient+8]
      mov      dword ptr[edi+8], eax
      mov      eax, dword ptr[quotient+4]
      mov      dword ptr[edi+4], eax
      mov      eax, dword ptr[quotient]
      mov      dword ptr[edi], eax
      // To sign correction and return
      jmp      applySign

fullDIV:
      // Full 128/64 bit division
      xor      eax, eax
      mov      dword ptr[REMAINDER+12], eax
      mov      dword ptr[REMAINDER+8], eax
      mov      dword ptr[REMAINDER+4], eax
      mov      dword ptr[REMAINDER], eax

      mov      ecx, 128
loop1:
      // Compute REMAINDER:QUOTIENT = REMAINDER:QUOTIENT shl 1
      shl      dword ptr[QUOTIENT], 1
      rcl      dword ptr[QUOTIENT+4], 1
      rcl      dword ptr[QUOTIENT+8], 1
      rcl      dword ptr[QUOTIENT+12], 1
      rcl      dword ptr[REMAINDER], 1
      rcl      dword ptr[REMAINDER+4], 1
      rcl      dword ptr[REMAINDER+8], 1
      rcl      dword ptr[REMAINDER+12], 1

      // Test (REMAINDER >= Divider)
      xor      eax, eax
      cmp      dword ptr[REMAINDER+12], eax
      ja      iftrue
      jb      iffalse

      cmp      dword ptr[REMAINDER+8], eax
      ja      iftrue
      jb      iffalse

      mov      eax, dword ptr[REMAINDER+4]
      cmp      eax, dword ptr[divider+4]
      ja      iftrue
      jb      iffalse

      mov      eax, dword ptr[REMAINDER]
      cmp      eax, dword ptr[divider]
      jb      iffalse
iftrue:
      // Remainder = remainder - divider
      mov      eax, dword ptr[divider]
      sub      dword ptr[REMAINDER], eax
      mov      eax, dword ptr[divider+4]
      sbb      dword ptr[REMAINDER+4], eax
      xor      eax, eax
      sbb      dword ptr[REMAINDER+8], eax
      sbb      dword ptr[REMAINDER+12], eax
      // Quotient = quotient +1
      add      dword ptr[QUOTIENT], 1
      adc      dword ptr[QUOTIENT+4], 0
      adc      dword ptr[QUOTIENT+8], 0
      adc      dword ptr[QUOTIENT+12], 0
iffalse:
      // Loop size = 101 bytes, is less than 127 so loop is possible
      loop   loop1

applySign:
      // Correct the sign of the result based on the stored combined sign
      popfd
      jns      storeRes
      not      dword ptr[edi+12]
      not      dword ptr[edi+ 8]
      not      dword ptr[edi+ 4]
      not      dword ptr[edi]
      add      dword ptr[edi], 1
      adc      dword ptr[edi+ 4], 0
      adc      dword ptr[edi+ 8], 0
      adc      dword ptr[edi+12], 0

storeRES:
      // Get low order qword from var128
      mov      edx, dword ptr[edi+4]
      mov      eax, dword ptr[edi]
done:
   }
   // result is returned in edx:eax
}

stoxx 28. Feb 2008 14:21

Re: asm MulDiv64 C übersetzung stürzt ab ...
 
hmm .. weiss wirklich niemand, wie man den C ASM Quelltext nach Delphi übersetzt? .. hmmmm
*nochmal hochschieb*

gammatester 28. Feb 2008 15:33

Re: asm MulDiv64 C übersetzung stürzt ab ...
 
Interessant das diese Zeile ohne Fehler übersetzt wird, var128 ist ein type!

Delphi-Quellcode:
      lea     edi,[var128]              // edi = &var128
Im C-Code gibt es zwei 128-Bit-Variable. Also mal versuchen mit

Delphi-Quellcode:
type TVar128 = packed record
DW : array[0..3] of DWORD;
end;

...

var
  var128, quotient: TVar128;
Im übrigen halte ich es für ziemlich gefährlich. mit den Flags auf dem Stack zu jonglieren.

Gruß Gammatester

himitsu 28. Feb 2008 15:53

Re: asm MulDiv64 C übersetzung stürzt ab ...
 
erster Versuch,

!! hab irgendwie CombinedSign vergessen einzusetzen, also da wo es verwendet wird(werden sollte)
(hab es nicht selber auf den Stack kopiert)


nja, für den Anfang ... wenn ich nochmal etwas Zeit hab, schau ich wieder rein,
aber eventuell findet ja noch wer "den" Fehler.

Delphi-Quellcode:
// Source file: MulDiv64.cpp
// Author:      Richard van der Wal
// Contact:     [email]R.vdWal@xs4all.nl[/email]
//
// Description:   Implementation for MulDiv64 and MulShr64
//
// $Log: $

// Multiplies an operant by a multiplier and divides the result by a divider
// Used for scaling 64 bit integer values
//   Xscaled = Xstart * Multiplier / Divider
// Uses 128 bit intermediate result

Function MulDiv64(Operant, Multiplier, Divider: Int64): Int64; StdCall;
  Type TVar128 = Array[0..3] of LongWord;

  Var Remainder, Quotient: TVar128;
    CombinedSign: LongWord;

  Begin
    // Save combined sign
    CombinedSign := Int64Rec(Operant).Hi xor Int64Rec(Multiplier).Hi
      xor Int64Rec(Divider).Hi;

    // Take absolute values because algorithm is for unsigned only
    If Operant   < 0 Then Operant   := -Operant;
    If Multiplier < 0 Then Multiplier := -Multiplier;
    If Divider   < 0 Then Divider   := -Divider;

    ASM
      // First check Divider for 0
      MOV   EAX, DWORD PTR [&Divider+4]
      OR    EAX, DWORD PTR [&Divider+0]
      JNZ   @DividerOK
      DIV   EAX

      @DividerOK:
      LEA   EDI, [&Quotient]               // EDI := @Quotient

      // Check multiplier for 1 or 0
      XOR   EAX, EAX
      CMP   EAX, DWORD PTR [&Multiplier+4]
      JNZ   @StartMUL
      CMP   EAX, DWORD PTR [&Multiplier+0]
      JNZ   @MultiNotNUL
      XOR   EDX, EDX
      JMP   @Done

      @MultiNotNUL:
      // Set result HI part to 0
      XOR   EAX, EAX
      MOV   DWORD PTR [EDI+12], EAX
      MOV   DWORD PTR [EDI+ 8], EAX
      MOV   EAX, 1
      CMP   EAX, DWORD PTR [&Multiplier+0]
      JNZ   @SmallMUL
      // Multiplier is 1 so just copy operant to result
      MOV   EAX, DWORD PTR [&Operant+4]
      MOV   DWORD PTR [EDI+4], EAX
      MOV   EAX, DWORD PTR [&Operant+0]
      MOV   DWORD PTR [EDI+0], EAX
      JMP   @StartDIV

      @SmallMUL:
      // Test for 32/32 bit multiplication
      XOR   EAX, EAX
      MOV   ECX, DWORD PTR [&Operant+4]
      OR    ECX, EAX                       // test for both hiwords zero.
      JNZ   @StartMUL
      // Do 32/32 bit multiplication
      MOV   ECX, DWORD PTR [&Multiplier+0]
      MOV   EAX, DWORD PTR [&Operant+0]
      MUL   ECX
      MOV   DWORD PTR [EDI+4], EDX
      MOV   DWORD PTR [EDI+0], EAX
      JMP   @StartDIV

      @StartMUL:
      // Check signs
      // Multiply: Quotient = operant * multiplier
      MOV   EAX, DWORD PTR [&Multiplier+0] // EAX = LO(multiplier)
      MUL   DWORD PTR [&Operant+0]         // EDX:EAX = EAX * LO(operant)
      MOV   DWORD PTR [EDI+0], EAX         // Quotient[0] = EAX
      MOV   ECX, EDX                       // ECX = EDX

      MOV   EAX, DWORD PTR [&Multiplier+0] // EAX = LO(multiplier)
      MUL   DWORD PTR [&Operant+4]         // EDX:EAX = EAX * HI(operant)
      ADD   EAX, ECX                       // EAX = EAX + ECX
      ADC   EDX, 0                          // EDX = EDX + 0 + carry
      MOV   EBX, EAX
      MOV   ECX, EDX

      MOV   EAX, DWORD PTR [&Multiplier+4]
      MUL   DWORD PTR [&Operant+0]
      ADD   EAX, EBX
      MOV   DWORD PTR [EDI+4], EAX
      ADC   ECX, EDX
      pushfd
      MOV   EAX, DWORD PTR [&Multiplier+4]
      MUL   DWORD PTR [&Operant+4]
      popfd
      ADC   EAX, ECX
      ADC   EDX, 0
      MOV   DWORD PTR [EDI+ 8], EAX
      MOV   DWORD PTR [EDI+12], EDX

      @StartDIV:
      // Divide: Quotient = Quotient / Divider
      //
      // Test Divider = 32bit value
      MOV   EAX, DWORD PTR [&Divider+4]
      CMP   EAX, 0
      JNZ   @FullDIV
      MOV   ECX, DWORD PTR [&Divider+0]
      CMP   ECX, 1
      JZ    @ApplySign

      // Start 128/32 bit division
      MOV   EAX, DWORD PTR [EDI+12]
      XOR   EDX, EDX
      DIV   ECX
      MOV   DWORD PTR [EDI+12], EAX

      MOV   EAX, DWORD PTR [EDI+8]
      DIV   ECX
      MOV   DWORD PTR [EDI+8], EAX

      MOV   EAX, DWORD PTR [EDI+4]
      DIV   ECX
      MOV   DWORD PTR [EDI+4], EAX

      MOV   EAX, DWORD PTR [EDI+0]
      DIV   ECX
      MOV   DWORD PTR [EDI+0], EAX

      // Copy the Quotient to the result storage
      MOV   EAX, DWORD PTR [EDI+12]
      MOV   DWORD PTR [EDI+12], EAX
      MOV   EAX, DWORD PTR [EDI+ 8]
      MOV   DWORD PTR [EDI+ 8], EAX
      MOV   EAX, DWORD PTR [EDI+ 4]
      MOV   DWORD PTR [EDI+ 4], EAX
      MOV   EAX, DWORD PTR [EDI+ 0]
      MOV   DWORD PTR [EDI+ 0], EAX
      // To sign correction and return
      JMP   @ApplySign

      @FullDIV:
      // Full 128/64 bit division
      XOR   EAX, EAX
      MOV   DWORD PTR [&Remainder+12], EAX
      MOV   DWORD PTR [&Remainder+ 8], EAX
      MOV   DWORD PTR [&Remainder+ 4], EAX
      MOV   DWORD PTR [&Remainder+ 0], EAX

      MOV   ECX, 128
      @Loop1:
      // Compute Remainder:Quotient = Remainder:QUOTIENT shl 1
      SHL   DWORD PTR [EDI+ 0], 1
      RCL   DWORD PTR [EDI+ 4], 1
      RCL   DWORD PTR [EDI+ 8], 1
      RCL   DWORD PTR [EDI+12], 1
      RCL   DWORD PTR [&Remainder+ 0], 1
      RCL   DWORD PTR [&Remainder+ 4], 1
      RCL   DWORD PTR [&Remainder+ 8], 1
      RCL   DWORD PTR [&Remainder+12], 1

      // Test (Remainder >= Divider)
      XOR   EAX, EAX
      CMP   DWORD PTR [&Remainder+12], EAX
      JA    @IfTrue
      JB    @IfFalse

      CMP   DWORD PTR [&Remainder+ 8], EAX
      JA    @IfTrue
      JB    @IfFalse

      MOV   EAX, DWORD PTR [&Remainder+ 4]
      CMP   EAX, DWORD PTR [&Divider+4]
      JA    @IfTrue
      JB    @IfFalse

      MOV   EAX, DWORD PTR [&Remainder+ 0]
      CMP   EAX, DWORD PTR [&Divider+0]
      JB    @IfFalse

      @IfTrue:
      // Remainder = Remainder - Divider
      MOV   EAX, DWORD PTR [&Divider+0]
      SUB   DWORD PTR [&Remainder+ 0], EAX
      MOV   EAX, DWORD PTR [&Divider+4]
      SBB   DWORD PTR [&Remainder+ 4], EAX
      XOR   EAX, EAX
      SBB   DWORD PTR [&Remainder+ 8], EAX
      SBB   DWORD PTR [&Remainder+12], EAX
      // Quotient = Quotient +1
      ADD   DWORD PTR [EDI+ 0], 1
      ADC   DWORD PTR [EDI+ 4], 0
      ADC   DWORD PTR [EDI+ 8], 0
      ADC   DWORD PTR [EDI+12], 0

      @IfFalse:
      // Loop size = 101 bytes, is less than 127 so loop is possible
      LOOP @Loop1

      @ApplySign:
      // Correct the sign of the result based on the stored combined sign
      JNS   @StoreRes
      NOT   DWORD PTR [EDI+12]
      NOT   DWORD PTR [EDI+ 8]
      NOT   DWORD PTR [EDI+ 4]
      NOT   DWORD PTR [EDI+ 0]
      ADD   DWORD PTR [EDI+ 0], 1
      ADC   DWORD PTR [EDI+ 4], 0
      ADC   DWORD PTR [EDI+ 8], 0
      ADC   DWORD PTR [EDI+12], 0

      @StoreRes:
      // Get low order qword from Quotient
      MOV   EDX, DWORD PTR [EDI+4]
      MOV   DWORD PTR [&Result+4], EAX

      MOV   EAX, DWORD PTR [EDI+0]
      MOV   DWORD PTR [&Result+0], EAX

      @Done:
    End;
  End;
Zitat:

Interessant das diese Zeile ohne Fehler übersetzt wird, var128 ist ein type!
bin zwar nicht so gut in C, aber ich kein Wunder, daß ich da irgendwie Probleme beim Übersetzen hatte :wall:

stoxx 5. Mär 2008 13:53

Re: asm MulDiv64 C übersetzung stürzt ab ...
 
Hi Himitsu !

hab vielen Dank für Deine Hilfe. Läuft zwar jetzt ohne Abstürze, aber rechnet total falsch... irgendwie scheint der OriginalCode falsch zu sein ...

Delphi-Quellcode:
i2 := 6000000;
i3 := 5266;
i4 := 5266;
i := MulDiv64(i2, i3, i4);
´


da kommt irgendwie 25769803782000000 raus .. hmmm ...
naja ...
trotzdem vielen Dank für Deine Mühe !!

himitsu 5. Mär 2008 14:08

Re: asm MulDiv64 C übersetzung stürzt ab ...
 
hmmm :stupid:
wie gesagt, ein paar Fehler sind bei mir auf jedenfall noch drin, vorallem da ich wohl irgendwie vergessen hab das Vorzeichen wieder einzurechnen :wall:

hat denn schonmal wer versucht den Originalcode in einem C-Programm laufen zu lassen?

Wenn nicht, vielleicht findet sich hier ja noch wer, der die Möglichkeit dazu hat ^^


Alle Zeitangaben in WEZ +1. Es ist jetzt 18:59 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz