Search code examples
cassemblysieve-of-eratosthenesattsieve-algorithm

Sieve of Eratosthenes in AT&T Assemby


I have written a simple program in C to find all prime numbers within a given range using Sieve of Eratosthenes. In school, we are currently learning assembly in a class, but I can't figure out how to write the three loops. I have somewhat figured it out in NASM, which I have fiddled with before, but we have to use AT&T. Any suggestions what I can do with "void sieve()"?

#include <stdio.h>
#include <stdlib.h>

void sieve(int *, int);

int main()
{
    int *a, n, i;
    n = 46000;
    printf("Enter the range : ");
    scanf("%d", &n);
    a = malloc(sizeof(int)*n);
    sieve(a,n);

    printf("\nThe primes numbers from 1 to %d are: ", n);
    for(i=2; i<=n; i++)
    {
        if(a[i] == 1)
        printf("%d, ", i);
    }
    printf(".\n\n");

    return 0;
}

void sieve(int *a, int n)
{
    int i, j;
    for(i=2; i<=n; i++)
    a[i] = 1;
    for(i=2; i<=n; i++)
    {
        if(a[i] == 1)
        {
            for(j=i; (i*j)<=n; j++)
            a[(i*j)] = 0;
        }
    }
}

Solution

  • Here are some pseudo code in C and Assembly of the two most common loop constructions.

    PseudoCode of While Loop in C:

    while ([condition]) {
        [body]
    }
    

    PseudoCode of While Loop in Assembly:

    begin_loop:
        [condition]
        test or cmp instruction
        jcc end_loop (conditional jmp according to the condition)
        [body]
        jmp begin_loop
    end_loop:
    

    PseudoCode of For Loop in C:

    for ([initialization]; [condition]; [increment]) {
        [body]
    }
    

    PseudoCode of For Loop in Assembly:

        [initialization]
    begin_loop:
        [condition]
        test or cmp instruction
        jcc end_loop (conditional jmp according to the condition)
        [body]
        [increment]
        jmp begin_loop
    end_loop:
    

    Some code of converting the outer loop of:

    for(i=2; i<=n; i++)
    {
        if(a[i] == 1)
        {
            for(j=i; (i*j)<=n; j++)
            a[(i*j)] = 0;
        }
    }
    

    to Assembly:

        mov ecx, 2
        mov eax, N (variable n)
    
    begin_loop:
        cmp ecx, eax
        jg end_loop
        lea ebx, A (array)
        test [ebx + i*4], 1 (4 is assuming size of element of A is 4 bytes)
        jnz continue
    
        # the other loop
    
    continue:
        inc ecx
        jmp begin_loop
    
    end_loop:
    

    Be careful with the use of register, if you need to use the register for other operations in the middle of the loop, save their current value (eg: to the stack with push reg), and when need to used the older value again restored (eg: with pop reg if it's in the stack).