C语言与汇编的嵌入式编程:统计字符串中各字符出现的次数
原始C语言:
#include<stdio.h> void main(){ char str[1024]; char pipei[] = "abcdefghijklmnopqrstuvwxyz"; int count[26]={0}; int i=0,j=0; scanf("%s",str); printf("%s\n",str); for(i=0;i<1024;i++) { for(j=0;j<26;j++) { if(str[i]==pipei[j]) count[j]+=1; } } for(j=0;j<26;j++) { if(count[j]>0) printf("%c=%d\n",pipei[j],count[j]); } }
加入汇编后代码:
#include<stdio.h> void main(){ char str[1024]; char pipei[] = "abcdefghijklmnopqrstuvwxyz"; int count[26]={0}; int i=0,j=0; scanf("%s",str); printf("%s\n",str); //外层循环start _asm{ mov eax,0 //i=0 mov ecx,1024 //i<1024 loop1: mov i,eax push eax push ecx }; //printf("%c\t",str[i]); //内层循环start _asm{ mov eax,0 mov ecx,26 loop2: mov j,eax push eax push ecx }; if(str[i]==pipei[j]) { count[j]+=1; } //内循环end __asm{ pop ecx pop eax add eax,1 loop loop2 }; //外循环end _asm{ pop ecx pop eax add eax,1 loop loop1 }; //输出统计个数 //外层循环start _asm{ mov eax,0 //i=0 mov ecx,26 //i<26 loop3: mov j,eax push eax push ecx }; if(count[j]>0) printf("%c=%d\n",pipei[j],count[j]); //外循环end _asm{ pop ecx pop eax add eax,1 loop loop3 }; }
后面有时间再优化了。。。。
优化如下:
需要掌握的知识 if语句的汇编表示
构造单循环:
#include<stdio.h> void main(){ char str[1024];
char pipei[] = "abcdefghijklmnopqrstuvwxyz"; int count[26]={0}; int i=0,j=0; char *str1 = "i=%d\n"; char *str2 = "%d=%c\t"; scanf("%s",str); printf("%s\n",str); printf(str2,i,str[i]); //mov edx,dword ptr [ebp-48Ch] //movsx eax,byte ptr [ebp+edx-400h] //push eax //mov ecx,dword ptr [ebp-48Ch] //push ecx //mov edx,dword ptr [ebp-498h] //push edx //call printf (0040d6c0) //add esp,0Ch // == //mov edx, i //movsx eax,str[edx] //push eax //mov ecx,i //push ecx //mov edx,str2 //push edx //call printf //add esp,12 //12=3个变量*4 _asm{ mov i,0 //i=0 start_1024: nop mov eax,i add eax,1 mov i,eax //i++ cmp i,10 // if i<10 jge end_1024 //逐个输出 printf(str2,str[i]); mov edx, i movsx eax,str[edx] push eax mov ecx,i push ecx mov edx,str2 push edx call printf add esp,12 //12=3个变量*4 jmp start_1024 //for 1024 end_1024: nop } }
进一步构造嵌套循环:
#include<stdio.h> void main(){ char str[1024];
char pipei[] = "abcdefghijklmnopqrstuvwxyz"; int count[26]={0}; int i=0,j=0; char *str1 = "i=%d\n"; char *str2 = "\n第一层循环%d=%c\n"; char *str3 = "%d=%c\t"; scanf("%s",str); printf("%s\n",str); printf(str2,i,str[i]); _asm{ //第一个外循环 mov i,0 //i=0 start_1024: nop mov eax,i add eax,1 mov i,eax //i++ cmp i,10 // if i<10 jge end_1024 //第二个内循环 mov j,0 //j=0 start_26: nop mov eax,j add eax,1 mov j,eax //j++ cmp j,26 jge end_26 //逐个输出pipei mov edx, j movsx eax,pipei[edx] push eax mov ecx,j push ecx mov edx,str3 push edx call printf add esp,12 //12=3个变量*4 jmp start_26 //for 1024 end_26: nop //逐个输出 printf(str2,str[i]); mov edx, i movsx eax,str[edx] push eax mov ecx,i push ecx mov edx,str2 push edx call printf add esp,12 //12=3个变量*4 jmp start_1024 //for 1024 end_1024: nop } }
加入判断与统计输出代码:
#include<stdio.h> void main(){ char str[1024];
char pipei[] = "abcdefghijklmnopqrstuvwxyz"; int count[26]={0}; int i=0,j=0; char *str1 = "i=%d\n"; char *str2 = "\n第一层循环%d=%c\n"; char *str3 = "i=%d,j=%d,c=%c\t"; char *str4 = "%c=%d\t"; scanf("%s",str); printf("%s\n",str); _asm{ //第一个外循环 mov i,-1 //i=0 start_1024: nop mov eax,i add eax,1 mov i,eax //i++ cmp i,1024 // if i<1024 jge end_1024 //判断第i个字符串是否为结束符,如果是则退出总循环 movsx eax,str[eax] cmp eax,0h je end_1024 // \n第一层循环%d=%c\n printf(str2,i,str[i]); mov edx, i movsx eax,str[edx] push eax mov ecx,i push ecx mov edx,str2 push edx call printf add esp,12 //12=3个变量*4 //第二个内循环 mov j,-1 //j=-1 start_26: nop mov eax,j add eax,1 mov j,eax //j++ cmp j,26 jge end_26 //逐个输出 "i=%d,j=%d,c=%c\t"; pipei mov edx, j movsx eax,pipei[edx] push eax mov ecx,j push ecx mov ecx,i push ecx mov edx,str3 push edx call printf add esp,16 //12=4个变量*4 //判断str[i]是否与pipei[j]相等,相等加一并退出第二循环 //if(str[i]==pipei[j]) mov edx,i movsx eax,str[edx] mov ecx,j movsx edx,pipei[ecx] cmp eax,edx jne end_count//不相等 //{count[j]+=1 //相等 mov eax,j mov ecx,count[eax*4] add ecx,1 mov edx,j mov count[edx*4],ecx //break; jmp start_1024 //如果找到一个匹配的,则退出第二循环 end_count: nop jmp start_26 //for 26 end_26: nop jmp start_1024 //for 1024 end_1024: nop //到这里统计算法已经结束 //输出统计个数 mov j,-1 //j=-1 start_all: nop mov eax,j add eax,1 mov j,eax //j++ cmp j,26 jge end_all //逐个输出printf(str4,pipei[j],count[j]); mov edx,j mov ecx,count[edx*4] push ecx movsx eax,pipei[edx] push eax mov edx,str4 push edx call printf add esp,12 //12=3个变量*4 jmp start_all //for 26 end_all: nop } }