用汇编和C语言 写流水灯程序

开发 后端
现在可能很少看到汇编程序了,但单片机的启动文件、RTOS底层代码等一些地方,依然还有汇编代码的身影。不知道大家有没有学过汇编,或者有没有用汇编语言编过程?

 [[394717]]

现在可能很少看到汇编程序了,但单片机的启动文件、RTOS底层代码等一些地方,依然还有汇编代码的身影。

不知道大家有没有学过汇编,或者有没有用汇编语言编过程?

今天就给大家分享一下汇编语言的那些事。

1学习汇编语言

我在10年学习单片机编程的时候,老师教学都还是用汇编教我们,包括教学实验,也是要求我们用汇编写程序。

  1. MOV  A,#00H 
  2. MOV  P1,A 

我记得那会儿,老师要求我们把汇编指令背下来。虽然现在很多汇编指令写不出来了,但看到很多汇编代码,还是基本明白它的意思。

以前计算机三级(PC技术)的上机考试,就是用汇编编程,我那个时候上机考试还是满分。当时觉得自己很牛逼,现在看来就是一菜鸟图片

2汇编转C语言

刚开始学习汇编那会儿,我真的用汇编在51单片机上写流水灯程序。后面看了用C语言写流水灯程序,突然发现,哇,用C语言写程序还能这么简单、方便。

于是,我就那个时候开始放弃了汇编,转向了C语言。包括后面我在大学实验室自己学习、DIY做东西、以及后面的全国大学生电子设计竞赛,都是用C语言编写的程序。

10行汇编程序,可能只需要一行C语言代码就能实现,这是C语言相比汇编简化的优点。

但是,C语言编写的程序,经过编译,也会转为汇编。比如我们在线调试代码的时候,会看到类似的“汇编窗口”:

因为以前单片机的运行速度不高,且内存和Flash容量不大,要求节约程序空间。

所以使用汇编的优点:代码运行效率更高、更节约代码存储空间。

3对比用汇编和C语言写流水灯程序

汇编语言写程序的主要缺点:语法复杂、可读性差、代码量大等。

下面分享一个实例:51单片机上的流水灯程序。分别用C语言和汇编写出来,大家对比一下就知道了。

C语言版:

  1. /******************** 宏定义 **************************/ 
  2. #define   MAIN_Fosc    22118400L  //定义主时钟 
  3.  
  4. /******************** 延时函数 **************************/ 
  5. void  delay_ms(u8 ms) 
  6.      u16 i; 
  7.    do{ 
  8.         i = MAIN_Fosc / 13000; 
  9.       while(--i)  ;   //14T per loop 
  10.      }while(--ms); 
  11.  
  12. /******************** 主函数 **************************/ 
  13. void main(void) 
  14.   P0M1 = 0;  P0M0 = 0;  //设置为准双向口 
  15.   P1M1 = 0;  P1M0 = 0;  //设置为准双向口 
  16.   P2M1 = 0;  P2M0 = 0;  //设置为准双向口 
  17.   P3M1 = 0;  P3M0 = 0;  //设置为准双向口 
  18.   P4M1 = 0;  P4M0 = 0;  //设置为准双向口 
  19.   P5M1 = 0;  P5M0 = 0;  //设置为准双向口 
  20.   P6M1 = 0;  P6M0 = 0;  //设置为准双向口 
  21.   P7M1 = 0;  P7M0 = 0;  //设置为准双向口 
  22.  
  23.   while(1) 
  24.   { 
  25.     P17 = 0; 
  26.     delay_ms(250); 
  27.     delay_ms(250); 
  28.     P17 = 1; 
  29.     P16 = 0; 
  30.     delay_ms(250); 
  31.     delay_ms(250); 
  32.     P16 = 1; 
  33.     P47 = 0; 
  34.     delay_ms(250); 
  35.     delay_ms(250); 
  36.     P47 = 1; 
  37.     P46 = 0; 
  38.     delay_ms(250); 
  39.     delay_ms(250); 
  40.     P46 = 1; 
  41.   } 

汇编语言版:

  1. ;******************** 宏定义 **************************/ 
  2. Fosc_KHZ  EQU  22118  ;22118KHZ 
  3.  
  4. STACK_POIRTER  EQU    0D0H  ;堆栈开始地质 
  5.  
  6.  
  7. ;******************** 延时函数 **************************/ 
  8. F_delay_ms: 
  9.   PUSH  02H    ;入栈R2 
  10.   PUSH  03H    ;入栈R3 
  11.   PUSH  04H    ;入栈R4 
  12.  
  13.   MOV    R2,A 
  14.  
  15. L_delay_ms_1: 
  16.   MOV    R3, #HIGH (Fosc_KHZ / 13) 
  17.   MOV    R4, #LOW (Fosc_KHZ / 13) 
  18.    
  19. L_delay_ms_2: 
  20.   MOV    A, R4      ;1T    Total 13T/loop 
  21.   DEC    R4        ;2T 
  22.   JNZ    L_delay_ms_3  ;4T 
  23.   DEC    R3 
  24. L_delay_ms_3: 
  25.   DEC    A        ;1T 
  26.   ORL    A, R3      ;1T 
  27.   JNZ    L_delay_ms_2  ;4T 
  28.    
  29.   DJNZ  R2, L_delay_ms_1 
  30.  
  31.   POP    04H    ;出栈R2 
  32.   POP    03H    ;出栈R3 
  33.   POP    02H    ;出栈R4 
  34.   RET 
  35.  
  36.  
  37. ;******************** 主程序 **************************/ 
  38.     ORG    0100H    ;reset 
  39. F_Main: 
  40.   CLR    A 
  41.   MOV    P0M1, A   ;设置为准双向口 
  42.    MOV    P0M0, A 
  43.   MOV    P1M1, A   ;设置为准双向口 
  44.    MOV    P1M0, A 
  45.   MOV    P2M1, A   ;设置为准双向口 
  46.    MOV    P2M0, A 
  47.   MOV    P3M1, A   ;设置为准双向口 
  48.    MOV    P3M0, A 
  49.   MOV    P4M1, A   ;设置为准双向口 
  50.    MOV    P4M0, A 
  51.   MOV    P5M1, A   ;设置为准双向口 
  52.    MOV    P5M0, A 
  53.   MOV    P6M1, A   ;设置为准双向口 
  54.    MOV    P6M0, A 
  55.   MOV    P7M1, A   ;设置为准双向口 
  56.    MOV    P7M0, A 
  57.  
  58.   MOV    SP, #STACK_POIRTER 
  59.   MOV    PSW, #0    ;选择第0组R0~R7 
  60.  
  61. L_MainLoop: 
  62.   CLR    P1.7 
  63.   MOV    A, #250 
  64.   LCALL  F_delay_ms    ;延时250ms 
  65.   LCALL  F_delay_ms    ;延时250ms 
  66.   SETB  P1.7 
  67.  
  68.   CLR    P1.6 
  69.   MOV    A, #250 
  70.   LCALL  F_delay_ms    ;延时250ms 
  71.   LCALL  F_delay_ms    ;延时250ms 
  72.   SETB  P1.6 
  73.  
  74.   CLR    P4.7 
  75.   MOV    A, #250 
  76.   LCALL  F_delay_ms    ;延时250ms 
  77.   LCALL  F_delay_ms    ;延时250ms 
  78.   SETB  P4.7 
  79.  
  80.   CLR    P4.6 
  81.   MOV    A, #250 
  82.   LCALL  F_delay_ms    ;延时250ms 
  83.   LCALL  F_delay_ms    ;延时250ms 
  84.   SETB  P4.6 
  85.  
  86.   SJMP  L_MainLoop 

上面两个程序,实现的功能都一样(流水灯),但对比代码,大家发现有啥区别?

对于有汇编基础的同学来说,可能这个简单的流水灯程序还是很好理解。

但是,对于大部分人来说,肯定都会觉得汇编很难读。是的,这个是汇编的“特点”。

4最后

汇编语法,对于绝大部分读者来说,我现在是不建议再深入学习了,只需要了解一些基础的内容即可。

有少部分人,想从事底层开发,比如底层驱动、单片机验证、固件库开发等这些读者,有时间还是可以进一步了解汇编的一些技术。

 

责任编辑:武晓燕 来源: 嵌入式专栏
相关推荐

2017-01-12 22:36:30

2020-12-14 08:48:45

C语言嵌入式gcc

2009-08-13 17:04:09

C#语言C#程序

2014-04-15 15:35:32

CC语言

2010-03-25 18:13:06

Python编程语言

2009-09-11 08:44:36

2022-02-19 22:47:46

编程语言开发C++

2015-03-19 09:46:32

程序员

2012-03-20 09:20:40

Go语言

2020-12-22 11:54:42

C语言Cortex-A9LED汇编

2014-08-22 16:29:12

应用汇游戏评级资源策略

2010-04-07 14:54:20

Unix操作系统

2011-01-14 14:08:17

Linux汇编语言

2022-03-25 21:57:49

汇编Go语言

2014-12-24 09:41:05

x86C#

2021-05-27 08:59:09

Go汇编命令

2011-01-14 14:39:32

Linux汇编语言

2009-06-15 11:03:10

Java语言C#语言

2010-07-13 10:21:19

2010-01-22 11:23:06

C++程序
点赞
收藏

51CTO技术栈公众号