- UID
- 872339
|
引言
汇编语言是一种用助记符表示的面向机器的程序设计语言。助记符使得原来的机器语言变得相对较为直观、易懂、易用,并且汇编语言与机器语言具有一一对应的关系,因此它继承了机器语言直接、快速、高效的特点,是一种底层语言。但是汇编语言的劣势也十分明显,如对于编写较大的程序需要考虑诸多硬件存储器的分配以及中断程序的处理等非常细节的问题,否则容易出现寄存器冲突,从而导致程序崩溃。为了简化汇编语言的编写过程,本文提出了一种结构化的汇编编程思路,并以基于AT89C51芯片(以下对汇编语言的讨论针对51单片机系统)的俄罗斯方块游戏为例,来展现在51单片机中汇编语言结构化编写的优势。
1 汇编语言的结构化设计思想
1.1 变量定义
汇编语言中无需变量的声明,因为汇编语言是直接对具体的内存单元操作,而每个单元有16进制的地址码,因此所有变量都可人为地由该地址码表示。但是汇编语言提供了EQU伪指令,可以将特定的内存空间标记为特定的名称,这就为变量定义提供了可能。而使用EQU伪指令的好处就是将抽象的物理内存分化为具体的变量名,避免了内存冲突,同时又增加了程序可读性。
1.2 子函数设计
子函数对程序结构化的作用是其可简化主函数的编写,使得程序主干的编写思路清晰化,而一些复杂的算法与功能则放在一层层的子函数中实现。但是,汇编语言在调用子函数的过程中如果处理不当,极其容易造成堆栈错误、内存冲突等问题。本文提出了一种优化的子函数设计方案。
图1 工作寄存器区临时变量存放层次结构
首先,把51单片机内存的4组工作寄存器区(00H~1FH),用作子函数的临时变量存放区,如图1所示;另一部分是用户区(20H~7FH),用作主函数变量与堆栈区域。其次,4组工作寄存器区的每一组用作同一层次的子函数的临时变量,低层次的子函数只能被高层次的子函数调用,同一层次的子函数不允许相互嵌套调用。所有的子函数在编写时需要声明其使用的工作寄存器组编号,以防止冲突。在函数嵌套时,用RS1、RS0两个标志位的切换来实现工作寄存器组的切换,如此就可以方便可靠地实现子函数的调用和嵌套。
1.3 中断函数设计
与顺序设计的程序不同,51系列单片机还需考虑中断函数的设计。51单片机的中断有外部中断、定时器中断、串口中断等。中断程序在中断源触发后即起作用,换句话说,中断程序可能随时中止主程序的运行。如果在这个时候,中断函数与主程序中的主函数或子函数享用相同的临时变量,那么在中断发生时,这些临时变量就会被改写,从而导致内存冲突。因此,中断函数的临时变量体系应与主程序有别,以下是三种可选方案:
第一种方案是将工作寄存器区分为两类,一类用作主程序函数的临时变量,另一类用作中断函数的临时变量。这种方案中,单片机工作寄存器的组数对函数设计起限制作用。
第二种方案允许中断函数与主程序的子函数共用工作寄存器区,但是代价是在调用中断时必须保护和恢复现场,即在中断函数的开始、结尾必须将中断函数及其子函数使用的工作寄存器的数据压入、弹出堆栈,从而保证中断前后主程序函数临时变量的一致。
第三种方法是通过设置标志变量,避免在中断函数中插入子函数。在中断程序中,根据状态修改标志变量后即返回主函数。在主函数中,判断相应的中断标志执行相应的子程序。这种编程方法的优点是中断程序十分简单,能在很短的时间内完成,减少了中断出错的可能性;其缺点是中断执行的反应速度会有所降低,因为主函数对中断标志位一定是滞后于中断发生的,且如果主函数的结构是大循环型的,那么一次循环中只能处理若干次中断(大多数情况往往只为一次),这种编程方法对需要高频中断的功能是不合适的。2.5 实验测试与结果
开机测试与结果:开机全速运行程序,LED双色显示器上显示的“Hello”欢迎界面如图3所示。按任意键可进入难度选择界面。
难度选择界面测试:进入难度选择界面,双色LED上显示红色的“123”字样,并在‘3’下有一绿色小圆点,如图4所示。按数字键1、2、3键,用于选择相应的等级,同时绿色小圆点会移到相应等级的下方;按“enter”键结束难度选择,进入游戏界面。
图3 开机界面 图4 难度选择界面
游戏流程测试:进入游戏主界面。LED上方产生方块,不操作时方块可以自由下落,此时方块为红色。按动‘7’键,方块改变其角度,再次按动,角度可以继续改变;按动‘6’键,方块下移一格,并且不影响其自由下落,表现为方块下移速度加快;按动‘2’键,方块向左移动一位,当移动到左边边界时,无法再移动;按动‘A’键,方块向右移动一位,当移动到右边边界时,无法再移动。方块移动到无法再向下时,颜色变为绿色,并且在LED上方产生新的方块,如图5所示。满足消行条件时,该行闪烁后即消失,同时在数码管上显示分数增加10分;多行消除时,为每行依次消除,增加相应分数,如图6所示。随着分数的增加,方块的自由下落速度加快。按动‘8’键,游戏暂停,此时按动除‘8’键的其他键均无效。当再次按动‘8’,游戏继续进行。游戏进入、按键、消行时,均有音乐产生,并且两者同步。
游戏结束测试:按‘C’键或者游戏结束时,屏幕所有LED灯从底端到上端逐行点亮,再从上端到底端逐行熄灭,此时伴随着音乐产生,然后进入欢迎界面。
图5 游戏流程
图6 加分显示
结语
本文以俄罗斯方块游戏的程序编写为例子,提出、分析并具体说明了在功能复杂的汇编程序设计过程中,采用的结构化编程思路。并从变量定义、子函数设计、中断函数设计等方面探讨了汇编语言结构化设计的具体方法,从而有效解决了汇编程序编写中易发生的寄存器内存冲突等问题。这种汇编语言编程的结构化思维,对于运用编写汇编大程序具有重要的指导和借鉴作用。 |
|