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