电子产业一站式赋能平台

PCB联盟网

搜索
查看: 28|回复: 0
收起左侧

结合源码分析MCU汇编和C语言的区别

[复制链接]

598

主题

598

帖子

7488

积分

高级会员

Rank: 5Rank: 5

积分
7488
发表于 昨天 11:46 | 显示全部楼层 |阅读模式
关注+星标公众,不错过精彩内容作者 | strongerHuang微信公众号 | 嵌入式专栏
现在做单片机开发,可能很少看到有直接用汇编做项目了,但单片机的启动文件、RTOS底层等一些地方,依然还有汇编代码的身影。
不知道大家有没有学过汇编,或者有没有用汇编语言编过程?
学习汇编语言
我在2010年学习单片机编程的时候,老师教学都还是用汇编教我们,包括教学实验,也是要求我们用汇编写程序。
  • MOV  A,#00HMOV  P1,A
    我记得那会儿,老师要求我们把汇编指令背下来。虽然现在很多汇编指令写不出来了,但看到很多汇编代码,还是基本明白它的意思。
    以前计算机三级(PC技术)的上机考试,就是用汇编编程,我那个时候上机考试还是满分。当时觉得自己很牛逼,现在看来就是一菜鸟

    2wz24ldlvy16409637124.png

    2wz24ldlvy16409637124.png

    汇编转C语言
    刚开始学习汇编那会儿,我真的用汇编在51单片机上写流水灯程序。后面看了用C语言写流水灯程序,突然发现,哇,用C语言写程序还能这么简单、方便。
    于是,我就那个时候开始放弃了汇编,转向了C语言。包括后面我在大学实验室自己学习、DIY做东西、以及后面的全国大学生电子设计竞赛,都是用C语言编写的程序。
    10行汇编程序,可能只需要一行C语言代码就能实现,这是C语言相比汇编简化的优点。
    但是,C语言编写的程序,经过编译,也会转为汇编。比如我们在线调试代码的时候,会看到类似的“汇编窗口”:

    of2g5atljrz6409637224.png

    of2g5atljrz6409637224.png

    因为以前单片机的运行速度不高,且内存和Flash容量不大,要求节约程序空间。
    所以使用汇编的优点:代码运行效率更高、更节约代码存储空间
    对比汇编和C语言点灯程序
    汇编语言写程序的主要缺点:语法复杂、可读性差等。
    下面分享一个实例:51单片机上的流水灯程序。分别用C语言和汇编写出来,大家对比一下就知道了。
    C语言版:
  • /******************** 宏定义 **************************/#define   MAIN_Fosc    22118400L  //定义主时钟
    /******************** 延时函数 **************************/voiddelay_ms(u8 ms){     u16 i;do{        i = MAIN_Fosc / 13000;while(--i)  ;   //14T per loop     }while(--ms);}
    /******************** 主函数 **************************/voidmain(void){  P0M1 = 0;  P0M0 = 0;  //设置为准双向口  P1M1 = 0;  P1M0 = 0;  //设置为准双向口  P2M1 = 0;  P2M0 = 0;  //设置为准双向口  P3M1 = 0;  P3M0 = 0;  //设置为准双向口  P4M1 = 0;  P4M0 = 0;  //设置为准双向口  P5M1 = 0;  P5M0 = 0;  //设置为准双向口  P6M1 = 0;  P6M0 = 0;  //设置为准双向口  P7M1 = 0;  P7M0 = 0;  //设置为准双向口
    while(1)  {    P17 = 0;    delay_ms(250);    delay_ms(250);    P17 = 1;    P16 = 0;    delay_ms(250);    delay_ms(250);    P16 = 1;    P47 = 0;    delay_ms(250);    delay_ms(250);    P47 = 1;    P46 = 0;    delay_ms(250);    delay_ms(250);    P46 = 1;  }}
    汇编语言版:
  • ;********************宏定义 **************************/Fosc_KHZEQU  22118  ;22118KHZ
    STACK_POIRTEREQU    0D0H  ;堆栈开始地质
    ;********************延时函数 **************************/F_delay_ms:PUSH02H    ;入栈R2PUSH03H    ;入栈R3PUSH04H    ;入栈R4
    MOVR2,A
    L_delay_ms_1:MOVR3, #HIGH (Fosc_KHZ / 13)MOVR4, #LOW (Fosc_KHZ / 13)L_delay_ms_2:MOVA, R4      ;1T    Total 13T/loopDECR4        ;2TJNZL_delay_ms_3  ;4TDECR3L_delay_ms_3:DECA        ;1TORLA, R3      ;1TJNZL_delay_ms_2  ;4TDJNZR2, L_delay_ms_1
    POP04H    ;出栈R2POP03H    ;出栈R3POP02H    ;出栈R4RET
    ;********************主程序 **************************/ORG0100H    ;resetF_Main:CLRAMOVP0M1, A   ;设置为准双向口MOVP0M0, AMOVP1M1, A   ;设置为准双向口MOVP1M0, AMOVP2M1, A   ;设置为准双向口MOVP2M0, AMOVP3M1, A   ;设置为准双向口MOVP3M0, AMOVP4M1, A   ;设置为准双向口MOVP4M0, AMOVP5M1, A   ;设置为准双向口MOVP5M0, AMOVP6M1, A   ;设置为准双向口MOVP6M0, AMOVP7M1, A   ;设置为准双向口MOVP7M0, A
    MOVSP, #STACK_POIRTERMOVPSW, #0    ;选择第0组R0~R7
    L_MainLoop:CLRP1.7MOVA, #250LCALLF_delay_ms    ;延时250msLCALLF_delay_ms    ;延时250msSETBP1.7
    CLRP1.6MOVA, #250LCALLF_delay_ms    ;延时250msLCALLF_delay_ms    ;延时250msSETBP1.6
    CLRP4.7MOVA, #250LCALLF_delay_ms    ;延时250msLCALLF_delay_ms    ;延时250msSETBP4.7
    CLRP4.6MOVA, #250LCALLF_delay_ms    ;延时250msLCALLF_delay_ms    ;延时250msSETBP4.6
    SJMPL_MainLoop
    上面两个程序,实现的功能都一样(流水灯),但对比代码,大家发现有啥区别?
    对于有汇编基础的同学来说,可能这个简单的流水灯程序还是很好理解。
    但是,对于大部分人来说,肯定都会觉得汇编很难读。是的,这个是汇编的“特点”。
    最后
    汇编语法,对于绝大部分读者来说,我现在是不建议再深入学习了,只需要了解一些基础的内容即可。
    有少部分人,想从事底层开发,比如底层驱动、单片机验证、固件库开发等这些读者,有时间还是可以进一步了解汇编的一些技术。
    ------------ END ------------

    v20wn34scnj6409637324.gif

    v20wn34scnj6409637324.gif

    ●专栏《嵌入式工具●专栏《嵌入式开发》●专栏《Keil教程》●嵌入式专栏精选教程
    关注公众号回复“加群”按规则加入技术交流群,回复“1024”查看更多内容。
    点击“阅读原文”查看更多分享。
  • 回复

    使用道具 举报

    发表回复

    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则


    联系客服 关注微信 下载APP 返回顶部 返回列表