-2

我用 C 语言编写了一个简单的程序,使用埃拉托色尼筛法查找给定范围内的所有素数。在学校,我们目前正在上课学习汇编,但我不知道如何编写三个循环。我在 NASM 中有所了解,我之前曾摆弄过,但我们必须使用 AT&T。有什么建议我可以用“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;
        }
    }
}
4

1 回答 1

0

以下是两个最常见的循环结构C中的一些伪代码。Assembly

While循环中的伪代码C

while ([condition]) {
    [body]
}

While循环中的伪代码Assembly

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

For循环中的伪代码C

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

For循环中的伪代码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:

一些转换外循环的代码:

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

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:

注意寄存器的使用,如果在循环中间需要将寄存器用于其他操作,保存它们的当前值(例如:push reg用:pop reg如果它在堆栈中)。

于 2014-09-17T13:51:52.843 回答