title: C inline assembly help (digital mars c compiler)
body: <p><strong>Scratch last edit... it still isn't working, and adressing offsets are still in bytes, as far as I know >_&lt;</strong></p>
  
  <p>I'm trying to write my own implementation of arbitrary precision integer arithmetic in C. To do so efficiently, I needed to use inline assembler functions to be able to access the carry flag, and access both the high and low 32 bits of the result of a 32bx32b multiplication.</p>
  
  <p>So I wrote this function that multiplies two 32-bit integers a and b, and stores the high part of the product in c and the low part in d.</p>
  
  <pre><code>void longMul(int a, int b, int *c, int *d) {
  asm {
      mov EAX, a
      mul b
      mov ESI, c
      mov [ESI], EDX
      mov ESI, d
      mov [ESI], EAX
  }
  </code></pre>
  
  <p>}</p>
  
  <p>Now I call this function from within my BigInteger_Mul function, where a and b are pointers to arrays of integers (which is how I store the Big Integers), and i and j are indices into a and b. highPart and lowPart store the result of the multiply. So it looks like this in my code (I omitted most of the code because the question only pertains to one line):</p>
  
  <pre><code> void BigInteger_Mul( length, int *a, int *b, int *dest) {     
       ... do a bunch of stuff ...
       int highPart, lowPart;
       longMul( *(a+i), *(b+j), &amp;highPart, &amp;lowPart);
       ... do a bunch more stuff ...
  }
  </code></pre>
  
  <p>I've tested it and the code works exactly as I intended it to (... for at least one set of inputs :P). Now, I'm trying to make the Mul function more efficient by converting it entirely to assembly, inlining all the function calls, and optimizing.</p>
  
  <p>So my first step was to replace the line:</p>
  
  <pre><code>longMul( *(a+i), *(b+j), &amp;highPart, &amp;lowPart);
  </code></pre>
  
  <p>with what I thought would be functionally equivalent assembly code:</p>
  
  <pre><code>asm {
              mov ESI, a
              mov ECX, i
              mov EAX, [ESI+ECX*4]
  
              mov ESI, b
              mov ECX, j
              mul [ESI+ECX*4]
  
              mov lowPart, EAX
              mov highPart, EDX
  }
  </code></pre>
  
  <p>And I'm getting completely wrong results. So why does the second block of code not behave like the first? Forgive my noobishness, I have no background in x86 assembly and just decided to jump straight in. It's probably a stupid mistake, too.</p>
  
  <p>EDIT: I just found out that inline assembly is supposed to preserve the ESI register. Even when I store it's contents in a variable, then restore them at the end, it doesn't seem to help.</p>