前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >C语言与汇编的嵌入式编程:求100以内素数

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

作者头像
墨文
发布2020-02-28 15:20:50
2K0
发布2020-02-28 15:20:50
举报
文章被收录于专栏:m0w3nm0w3n

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

C代码如下:

代码语言:javascript
复制
#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循环

代码语言:javascript
复制
#include <stdio.h>
void main(){

   //test loop
    _asm{

        mov ax,2

        mov cx,11

        s:add ax,ax

        loop s

    };
}

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

代码语言:javascript
复制
#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循环的目的

代码语言:javascript
复制
#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语言与汇编的嵌入式编程。

改造后的代码:

代码语言:javascript
复制
#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步的判断等其他语句再统一转换成汇编代码。

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2020-02-02 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档