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