写一个求100以内素数的C语言与汇编的嵌入式编程

Posted 墨文

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了写一个求100以内素数的C语言与汇编的嵌入式编程相关的知识,希望对你有一定的参考价值。

写汇编之前,需要搞清楚C语言代码的写法,这里以最简单的算法举例说明

C代码如下:

#include <stdio.h>
void main(){

    int i,j;
    int count=1;

    for(i=2;i<=100;i++)
    {
        for(j=2;j<i/2;j++)
        {
            if(i%j==0)
            {
                count=0;
                break;
            }    
        }

        if(count == 1)
        {
            printf("%d\\n",i);
        }
        count = 1;
    }    
}

 

 由于C语言中使用的是for进行循环,使用VC调试汇编时,发现for汇编的jmp需要具体地址才可以进行,对于程序来讲不方便

 

 然后查找资料,汇编中可以使用loop循环,因此,先实现一个loop循环

#include <stdio.h>
void main(){

   //test loop
    _asm{

        mov ax,2

        mov cx,11

        s:add ax,ax

        loop s

    };
}

进一步,我们在loop循环里面加上printf输出语句

#include <stdio.h>
void main(){

    int i=0xA; // dword ptr [ebp-4],0Ah
    int j=0xB; // dword ptr [ebp-8],0Bh
    int count=0; // dword ptr [ebp-0Ch],1

    //第一个循环start
    _asm{
        mov eax,2                    //    i=2
        mov ecx,9                    //    i<100
        loop1:                        // 开始循环1
        mov i,eax    // 保存i
        push eax                     // push eax和ecx到堆栈,是因为程序调用printf函数后,会改变ecx的值,所以需要先记录下来,再通过pop ecx和eax还原原来的eax和ecx的值
        push ecx
    };

    printf("\\n\\n第一层循环i=%d\\n",i);

    //第一个循环end
    _asm{
        pop ecx
        pop eax
        add eax,1                //    i++
        loop loop1
    };

    printf("ssssssssss");

}

 

 

在此基础上,我们

再实现一个loop循环里面嵌入一个loop循环,即可达到for循环里面嵌套for循环的目的

#include <stdio.h>
void main(){

    int i=0xA; // dword ptr [ebp-4],0Ah
    int j=0xB; // dword ptr [ebp-8],0Bh
    int count=0; // dword ptr [ebp-0Ch],1

    //第一个循环start
    _asm{
        mov eax,2                    //    i=2
        mov ecx,9                    //    i<100
        loop1:                        // 开始循环1
        mov i,eax    // 保存i
        push eax                     // push eax和ecx到堆栈,是因为程序调用printf函数后,会改变ecx的值,所以需要先记录下来,再通过pop ecx和eax还原原来的eax和ecx的值
        push ecx
    };

    printf("\\n\\n第一层循环i=%d\\n",i);

    //第二个循环start
    _asm{
        mov eax,2                    // j=2
        mov ecx,i   // j<i
        sub ecx,1                    // j=i-2
        loop2:                        // 开始循环2
        mov j,eax   //    保存j 
        push eax                    // push eax和ecx到堆栈,是因为程序调用printf函数后,会改变ecx的值,所以需要先记录下来,再通过pop ecx和eax还原原来的eax和ecx的值
        push ecx
    };

    printf("j=%d\\t",j);

    //第二个循环end
    _asm{
        pop ecx
        pop eax
        add eax,1                // j++
        loop loop2
    };

    //第一个循环end
    _asm{
        pop ecx
        pop eax
        add eax,1                //    i++
        loop loop1
    };

    printf("ssssssssss");

}

 

 最后在循环过程中,加上是否为素数的判断if语句,即可简单实现C语言与汇编的嵌入式编程。

改造后的代码:

#include <stdio.h>
void main(){

    int i=0xA; // dword ptr [ebp-4],0Ah
    int j=0xB; // dword ptr [ebp-8],0Bh
    int count=0; // dword ptr [ebp-0Ch],1

    //第一个循环start
    _asm{
        mov eax,2                    //    i=2
        mov ecx,99                    //    i<100
        loop1:                        // 开始循环1
        mov i,eax    // 保存i
        push eax                     // push eax和ecx到堆栈,是因为程序调用printf函数后,会改变ecx的值,所以需要先记录下来,再通过pop ecx和eax还原原来的eax和ecx的值
        push ecx
    };

    printf("\\n\\n第一层循环i=%d\\n",i);

    //第二个循环start
    _asm{
        mov eax,2                    // j=2
        mov ecx,i   // j<i
        sub ecx,1                    // j=i-2
        loop2:                        // 开始循环2
        mov j,eax   //    保存j 
        push eax                    // push eax和ecx到堆栈,是因为程序调用printf函数后,会改变ecx的值,所以需要先记录下来,再通过pop ecx和eax还原原来的eax和ecx的值
        push ecx
    };

    

    //判断是否为素数
    if(i%j==0)
    {
        count+=1;
    }

    /*
    _asm{
        //if(i%j==0)
        mov         eax,i
        cdq
        idiv        eax,j
        test        edx,edx
        jne         loop2+2Ah (0040d822)
        //{
        //count+=1;
        mov         edx,dword ptr [ebp-0Ch]
        add         edx,1
        mov         dword ptr [ebp-0Ch],edx
        //}
    }*/

    printf("j=%d,count=%d\\t",j,count);


    //第二个循环end
    _asm{
        pop ecx
        pop eax
        add eax,1                // j++
        loop loop2
    };

    if(count ==1)
    {
        printf("%d是素数\\n",j);
    }

    count =0;

    //第一个循环end
    _asm{
        pop ecx
        pop eax
        add eax,1                //    i++
        loop loop1
    };

    printf("ssssssssss");

}

最后,还可以将if,printf等转换为汇编

 

 

总结下思路;

1、先用C语言写好一个算法程序

2、使用loop代替for循环

3、在loop循环中加入printf输出语句,实现循环变量值得打印

4、在loop循环中嵌入loop循环

5、加上判断等其他语句

6、再将第5步的判断等其他语句再统一转换成汇编代码。

 

以上是关于写一个求100以内素数的C语言与汇编的嵌入式编程的主要内容,如果未能解决你的问题,请参考以下文章

写一个C语言编程,求素数及反序数

用C语言输出1000以内的全部素数

C语言求范围之内素数的和与个数?

c语言求1000以内的素数(素数是只能被1和它本身整除的数)

求1到100以内所有素数之和(c语言)

c语言中用筛选法求素数