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步的判斷等其他語句再統一轉換成匯編代碼。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM