专栏首页m0w3nC语言与汇编的嵌入式编程:统计字符串中各字符出现的次数

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
    
    }
}

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • C语言与汇编的嵌入式编程:求100以内素数

     由于C语言中使用的是for进行循环,使用VC调试汇编时,发现for汇编的jmp需要具体地址才可以进行,对于程序来讲不方便

    墨文
  • 一个汇编小demo

    墨文
  • C语言与汇编的嵌入式编程:main中模拟函数的调用(两数交换)

    注明:swap函数大致处理过程为:把下个地址压入堆栈,然后参数入栈,然后把所有寄存器压入堆栈,分配空间,空间清C然后变量赋值开始程序然后做堆栈平衡清理堆栈

    墨文
  • 《coredump问题原理探究》Linux x86版5.8节C风格数据结构内存布局之结构体数组结构体coredump

    版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/xuzhina/article/detai...

    血狼
  • web自动化 基于python+Selenium+PHP+Ftp实现的轻量级web自动化测试框架

    官方下载地址:https://pypi.python.org/pypi/setuptools#downloads

    授客
  • 这个反人类的智障网站,能成功注册算我输!

    我俩达到了从认识到现在为止,最高度一致的结论 —— 没什么比卸载某些软件更屎的体验了!

    闫小林
  • 一文概述 2018 年深度学习 NLP 十大创新思路

    AI 科技评论按:Sebastian Ruder 是一位 NLP 方向的博士生、研究科学家,目前供职于一家做 NLP 相关服务的爱尔兰公司 AYLIEN,同时,...

    AI研习社
  • 一文概述 2018 年深度学习 NLP 十大创新思路

    AI 科技评论按:Sebastian Ruder 是一位 NLP 方向的博士生、研究科学家,目前供职于一家做 NLP 相关服务的爱尔兰公司 AYLIEN,同时,...

    AI科技评论
  • MethHC: 整合了癌症相关的甲基化与基因表达谱数据的数据库

    在MethHC数据库中,提供了18种癌症相关的DNA甲基化,microRNA表达谱和基因表达谱的数据,这里的数据来源于TCGA数据库。同时采用线性回归的方法计算...

    生信修炼手册
  • 实战篇 | 用Xpath,bs4,正则三种方式爬51job

    最近整理一个爬虫系列方面的文章,不管大家的基础如何,我从头开始整一个爬虫系列方面的文章,让大家循序渐进的学习爬虫,小白也没有学习障碍.

    叫我龙总

扫码关注云+社区

领取腾讯云代金券