Shawn S
Shawn S

Reputation: 9

Sum 1 + 11 + 111... n terms in x86 Assembly

So I'm trying to sum 1 + 11 + 111 given a number, n, which determines how many values of the series I add together. i.e n = 2, I will add 1 + 11, or n = 3, I will add 1 + 11 + 111. I have written the function in C already, but I am trying to translate it into x86 assembly and I am having trouble. Here is the C function:

int summation(int n)
   {
    int sum = 0, j = 1;
    for (int i = 1; i <= n; i++)
    {
    sum = sum + j;

    // Appending a 1 at the end
    j = (j * 10) + 1;
   }

    return sum;

Here is my x86 assembly code:

unsigned int seriesSum(int n)
{
unsigned int sum=0;

__asm 
{
   mov ebx, n //input n
   mov eax, 1
   mov ecx, 10
   mov edx, 0



   Begin:
   cmp ebx, 0 // determines end of loop or not
   je EndOfWhile
       add edx, edx
       add edx, eax
       mul ecx
       add eax, eax
       inc eax
       dec ebx

       jmp Begin //Loop back

    EndOfWhile:
   mov sum, edx 


}
return sum;

I thought I have it translated correctly but I seem to be getting 0s as my sum.

Upvotes: 0

Views: 1099

Answers (2)

Peter Cordes
Peter Cordes

Reputation: 364220

Use imul eax, ecx to just do eax *= ecx without storing the high half anywhere. (One-operand imul is a full multiply that stores the result in edx:eax.)

Or even better, eax = eax*10 +1 in x86 is best done with add eax,eax / lea eax, [eax+eax*4 + 1], not with mul or imul at all. Actually, optimizing for latency instead of code-size, you'd want to avoid the 3-component LEA by splitting it up as

lea  eax, [eax + eax*4]   ; eax *= 5
lea  eax, [1 + eax*2]     ; NOT  [ 1 + eax + eax ], which is shorter but slower
                          ; eax = orig_eax*5*2 + 1

NASM and YASM optimize that for code size into [ 1 + eax + eax*1 ] (so it can use a base + scaled-index + disp8 instead of disp32 + scaled-index). I'm not sure how to override the addressing mode; [dword 1 + eax*2] uses a disp32, but still splits the eax*2 into eax + eax*1, and strict eax*2 doesn't assemble. Hopefully an answer exists for How to force NASM to encode [1 + rax*2] as disp32 + index*2 instead of disp8 + base + index?

Obviously MASM will be different, but I don't have MASM available.

Upvotes: 1

Chris Dodd
Chris Dodd

Reputation: 126203

You're using edx to hold your sum, but the mul ecx instruction puts the upper word of the result into edx clobbering it.

Upvotes: 2

Related Questions