STM8汇编学习1

STM8与汇编语言

 

第一次打开STM8的手册时发现,CPU中的寄存器只有6个,即A、X、Y、SP、PC和CC。这几个寄存器,看上去特象早年苹果机使用的微处理器6502。在眼下都是多寄存器的RISC潮流下,不知ST推出的这种CPU架构有什么意图?这样的芯片能否与Microchip或者Atmel的RISC结构的MCU竞争呢?在此我无意做评论,我只想了解这颗芯片。

 

通过仔细研究,我发现由于STM8采用了32位宽度的程序存储器结构,使得大部分的指令都能在一个周期内取出,并且采用了哈佛结构和流水线,相当多的指令也都是单周期完成的。这样的话,虽然CPU是CISC架构的,但也基本上达到了单周期指令的效果,就像手册上说的,CPU的性能达到了20MISP◎24MHZ。就这一点来说,我个人感觉STM8还真不错。

 

举个例子来说,如果我们要完成内存中的2个8位无符号数相加,结果还保存到内存中,用C语言描述成:

 

 

unsigned char a,b,c; 

c = a+b;

 

这一段程序,用STM8汇编可以写成如下代码:

         LD    A, $1000

        ADD  A, $1001

         LD   $1002, A

 

 

这里假设a,b,c这3个变量分别存储在内存中,地址为1000,1001和1002。从STM8的手册上可以查到,这3条指令都是单周期的,完成一个加法,只需要3个时钟周期,可见STM8的CPU执行速度还是相当快的。

 

在这种传统的所谓CISC架构中,我特别关心累加器A与内存的访问速度,因为如果累加器与内存的访问速度是单周期的话,实际上我们就可以将内存当寄存器来看,这样写程序时就相当于拥有了一个大的寄存器阵列,或者说我们也就没必要再去考虑变量在内存中还是在寄存器中。也正是因为这一点,我对STM8越来越感兴趣了。

的开发环境用起来还是不错的,可以到ST的网站上下载安装程序ST_Toolset.exe。利用该环境可以开发用汇编语言写的程序,而且与ST的三合一开发板配合起来,确实非常方便。

 

不过如果要想用C语言来开发,稍微有点麻烦,得去别的公司下载C的编译器(CXSTM8_16K.exe),而且下载完以后,还得去注册,等待许可文件。实际上,我也按照ST介绍的方法做了,但始终都没有收到许可文件,也许本人实在愚笨。但不管怎么说,我觉得ST这一点做得相当不好,实在有点抠门。既然是免费的,为什么不一起打包提供给客户,这么麻烦,多耽误客户使用,得少卖多少STM8的芯片。

 

 

 

STM8与汇编语言(3)

 

言归正传,还回到正题。

用汇编语言开发程序,最简单的就是利用ST开发环境中提供的汇编程序框架自动生成功能。

 

打开开发环境后,在File菜单中选择New Workspace,点击Create workspace and project图标,然后就可以建立项目,在工具链中选ST Assembler Linker,最后选择MCU的型号,点击OK,就完成了一个项目的建立。

 

这个环境与微软的VC6开发环境很象,点开项目文件中的Source Files,能看到系统自动生成好了一个汇编语言的框架,我们编写程序只要在这框架基础上就可以了。其实不用编写任何一条指令,这个框架程序是能够编译通过,并下载运行的。

 

 

自动生成的项目中包含3个重要的文件:mapping.inc,mapping.asm和main.asm。

.inc文件中定义的是一些常量,mapping.asm文件中定义的是一些内存的分配,主要的汇编代码都在main.asm。

 

下面是main.asm中的汇编代码及注释。

 

 
  1. #include "mapping.inc"

  2. segment 'rom'

  3.  
  4. ; 下面是定义一个标号,ST汇编的写法,有点不习惯

  5.  
  6. ; 这里的main标号是复位后的第一条指令,与后面的中断向量表中 ; 的名字是对应的.l

  7. ; initialize SP

  8. ldw X,#stack_end

  9. ldw SP,X

  10. ; 设置堆栈指针

  11.  
  12. #ifdef RAM0

  13.  
  14. ; 如果定义了RAM0,则要汇编以下代码

  15. ; clear RAM0

  16. ram0_start.b EQU $ram0_segment_start

  17. ram0_end.b EQU $ram0_segment_end

  18. ldwX,#ram0_start ;寄存器X指向要清除的内存起始地址

  19.  
  20. clear_ram0.l ;这是一个标号定义,用于后面的跳转指令

  21. clr (X) ;对应的内存单元清0

  22. X ;寄存器X 1,指向下一个单元

  23. cpw X,#ram0_end ;比较寄存器X是否等于内存的最后一个地址

  24. jrule clear_ram0 ;若不等于,则循环

  25. #endif

  26.  
  27. #ifdef RAM1

  28.  
  29. ; 如果定义了RAM1,则要汇编以下代码,代码含义与上面完全一样

  30. ; clear RAM1

  31. arram1_start.w EQU $ram1_segment_start

  32. ram1_end.w EQU $ram1_segment_end

  33. ldwX,#ram1_start

  34. _ram1.l

  35. clr (X)

  36. incw X cpw X,#ram1_end

  37. jrule clear_ram1

  38. #endif

  39. ; clear stack

  40.  
  41. ; 将堆栈区的内存单元清0,代码含义与上面完全一样

  42. _start.w EQU $stack_segment_start

  43. stack_end.w EQU $stack_segment_end

  44. ldwX,#stack_start

  45. clear_stack.l

  46. clr(X)

  47. incw X

  48. cpw X,#stack_end

  49. jrule clear_stack

  50. _loop.l ; 定义一个标号

  51.  
  52. ;由于是一个框架,初始化内存后,进入一个死循环

  53. jra infinite_loop

  54.  
  55. ;下面代码写的是一段中断服务程序,不过也是空的

  56. interrupt NonHandledInterruptNonHandledInterrupt.l

  57.  
  58. ; 当进入中断服务程序后,无其它动作,直接返回

  59. iret

  60.  
  61. segment 'vectit'

  62. dc.l {$82000000+main} ; reset

  63. dc.l {$82000000+NonHandledInterrupt} ; trap

  64. dc.l {$82000000+NonHandledInterrupt} ; irq0

  65. dc.l {$82000000+NonHandledInterrupt} ; irq1

  66. dc.l {$82000000+NonHandledInterrupt} ; irq2

  67. dc.l {$82000000+NonHandledInterrupt} ; irq3

  68. dc.l {$82000000+NonHandledInterrupt} ; irq4

  69. dc.l {$82000000+NonHandledInterrupt} ; irq5

  70. dc.l {$82000000+NonHandledInterrupt} ; irq6

  71. dc.l {$82000000+NonHandledInterrupt} ; irq7

  72. dc.l {$82000000+NonHandledInterrupt} ; irq8

  73. dc.l {$82000000+NonHandledInterrupt} ; irq9

  74. dc.l {$82000000+NonHandledInterrupt} ; irq10

  75. dc.l {$82000000+NonHandledInterrupt} ; irq11

  76. dc.l {$82000000+NonHandledInterrupt} ; irq12

  77. dc.l {$82000000+NonHandledInterrupt} ; irq13

  78. dc.l {$82000000+NonHandledInterrupt} ; irq14

  79. dc.l {$82000000+NonHandledInterrupt} ; irq15

  80. dc.l {$82000000+NonHandledInterrupt} ; irq16

  81. dc.l {$82000000+NonHandledInterrupt} ; irq17

  82. dc.l {$82000000+NonHandledInterrupt} ; irq18

  83. dc.l {$82000000+NonHandledInterrupt} ; irq19

  84. dc.l {$82000000+NonHandledInterrupt} ; irq20

  85. dc.l {$82000000+NonHandledInterrupt} ; irq21

  86. dc.l {$82000000+NonHandledInterrupt} ; irq22

  87. dc.l {$82000000+NonHandledInterrupt} ; irq23

  88. dc.l {$82000000+NonHandledInterrupt} ; irq24

  89. dc.l {$82000000+NonHandledInterrupt} ; irq25

  90. dc.l {$82000000+NonHandledInterrupt} ; irq26

  91. dc.l {$82000000+NonHandledInterrupt} ; irq27

  92. dc.l {$82000000+NonHandledInterrupt} ; irq28

  93. dc.l {$82000000+NonHandledInterrupt} ; irq29

  94. end

 

 

 

把这个项目Build后,点击Debug中的Start Debugging就可以将程序下载到ST的三合一板上了,然后点击Run,程序就运行起来了,不过由于框架程序是一个空程序,初始化内存后就进入死循环了,因此什么效果也看不见。因此我们必须在框架程序的基础上,编写自己的程序。后面的程序例子都是在这个框架程序的基础上编写的。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值