• 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
    ",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("
    
    第一层循环i=%d
    ",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("
    
    第一层循环i=%d
    ",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	",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("
    
    第一层循环i=%d
    ",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	",j,count);
    
    
        //第二个循环end
        _asm{
            pop ecx
            pop eax
            add eax,1                // j++
            loop loop2
        };
    
        if(count ==1)
        {
            printf("%d是素数
    ",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步的判断等其他语句再统一转换成汇编代码。

  • 相关阅读:
    mysql——前面内容——前期整理笔记00
    mysql——触发器——概念
    mysql——触发器——示例
    mysql——多表——外连接查询——左连接、右连接、复合条件查询
    mysql——多表——合并查询结果
    IT职场人生系列之七:学外语
    IT职场人生系列之十三:技术?管理?业务?
    IT职场人生系列之五:怎样面试
    IT职场人生系列之十二:语言与技术I
    IT职场人生系列之四:怎样写简历
  • 原文地址:https://www.cnblogs.com/little-kwy/p/12252796.html
Copyright © 2020-2023  润新知