为什么要写51汇编教程?
由于最近接触嵌入式操作系统,比如代码量比较小的RT-thread, tiny os,catiki,freertos等,但是很多教程对于我这样的门外汉实在是难以看懂,也没耐心看进去。刚好看到RTX51 TINY,能在51上运行的嵌入式操作系统,挺有趣的,而且代码是汇编写的,感觉学习这个更能快速了解操作系统的本质,刚好会一点8086汇编,于是写一点关于51的汇编。
51汇编概述
任何一种汇编,无论是51,arm,8086等,指令集都是由三部分组成:
1.数据传送指令
2.数学运算指令
3.跳转指令
但是需要注意,单片机和经典的8086 cpu寄存器不太一样。8086 cpu寄存器是位于cpu内部的严格意义上的寄存器,单片机的寄存器是RAM地址的映射。所以单片机对寄存器的操作实际上就是对RAM地址的操作,你可以MOV R1 ,#12H
也可以MOV 01H ,#12H,两者是等价的。因为R0对应的就是RAM地址的01H,之所以用符号R1,SP等,我个人认为目的只是便于程序员容易使用,汇编器编译时会自动把R1转成01H,SP转成81H。
但是PC指针寄存器是严格意义上的寄存器,没有RAM映射,不可读,只能通过跳转指令间接去改变PC。
1.数据传送指令
对于现代微机系统,内部传送的数据分为:ROM中的数据,RAM中的数据,寄存器的数据,立即数。
(1) 立即数转移到RAM:
MOV R1,#50 --------直接给R1赋十进制的50
MOV R1,#50 --------直接给R1赋十进制的50
(2)RAM中的数据转移到RAM:(注意RAM区域有些是可以这样直接寻址的,有些是不可以的)
MOV R1,50H ---------将50H单元的内容传给R1
MOV R1,50 ---------50是十进制数,对应于十六进制数是32H
(3)ROM中的数据转移到RAM:
MOVC A,@A
(4)RAM中的数据到ROM //此种方式在51中是被禁止的
虽然51单片机指令有111条之多,但其实只使用3条即可完成51中所有的数据传送操作。
注意:很多指令使用时要注意操作的有效性,比如:
堆栈的数据不能保存在80H以上,这是特殊功能寄存器映射区,如果你把SP设为89H,然后PUSH入栈,
MOV 81H,#89H
MOV 23H,#40
PUSH 23H
编译时没有报错和警告,但是调试时PUSH操作是没有效果的。
特殊功能寄存器仅占用了21个单元,其余单元单片机不能对它们进行读/写操作(即不能作内部数据存储器使用),这也是为了防止程序混乱。
3.跳转指令
无非就是某一结果(RAM数据)=0,跳转;
某一结果(RAM数据)<0,跳转;
某一结果(RAM数据)>0,跳转;
无条件跳转;LJMP或AJMP
通过跳转加上操作堆栈就能实现对子函数的调用,LCALL 和RET相当于对跳转和堆栈操作的封装。