专栏首页m0w3nC语言与汇编的嵌入式编程:求100以内素数

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

写汇编之前,需要搞清楚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步的判断等其他语句再统一转换成汇编代码。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • C语言与汇编的嵌入式编程:统计字符串中各字符出现的次数

    墨文
  • C语言与汇编的嵌入式编程:main中模拟函数的调用(两数交换)

    注明:swap函数大致处理过程为:把下个地址压入堆栈,然后参数入栈,然后把所有寄存器压入堆栈,分配空间,空间清C然后变量赋值开始程序然后做堆栈平衡清理堆栈

    墨文
  • 一个汇编小demo

    墨文
  • Firefox内存释放重用漏洞高级利用(Pwn2Own2014、CVE-2014-1512)

    大家好,Pwn2Own 2014是令人兴奋的并且今年我们要挑战的所有主流浏览器和操作系统比以往任何时候更安全。然而,安全并不是意味着牢不可破,它意味着需要付出更...

    FB客服
  • Python之Scrapy海报资源海量下载

    今天小编给大家带来的是使用 Python 的 scrapy 框架快速写一个“千图网”的海报原图下载的爬虫,可以给设计专业的相关的人下载图片参考设计海报,也可在活...

    用户6825444
  • PS 太难学?腾讯这个小程序 3 秒就能生成一张海报 | 亲儿子

    知晓君
  • 问题: 在jupyter中看不到pyth

    1.命令行输入: python -m ipykernel install --user 将当前环境的python3加入到jupyter中。

    py3study
  • 使用jenkins实现tomcat自动化部署

    6)编译选项使用 pom.xml 文件进行编译,并使用 clean package 进行打包

    似水的流年
  • Visual Studio Code 代理设置

    Visual Studio Code (简称 VS Code)是由微软研发的一款免费、开源的跨平台文本(代码)编辑器,在十多年的编程经历中,我使用过非常多的的代...

    张善友
  • 使用jenkins实现tomcat自动化部署

    似水的流年

扫码关注云+社区

领取腾讯云代金券