通信设计应用
SS_BASE equ 0100h ss_init: move DPC, #1Ch ; Set all pointers to word mode move BP, #SS_BASE ; Set base pointer to stack base location move Offs, #0 ; Set stack to start ret如果基指针(BP)寄存器被设置在SS_BASE位置,那么,可以采用Offs寄存器指向堆栈的当前顶部。由于Offs寄存器只有8位宽,硬件会自动把堆栈限制在数据存储器的范围内(BP .. (BP+255))。如果当Offs等于255 (上溢)时出现推入,或者Offs等于0 (下溢)时出现弹出,那么,Offs寄存器只会限制在堆栈的另一端。这一行为模仿硬堆栈工作方式,支持简单的软堆栈实现;它不探测下溢和上溢状态。
mpush MACRO Reg move @BP[++Offs], Reg ; Push value to soft stack endm mpop MACRO Reg move Reg, @BP[Offs--] ; Pop value from soft stack endm mcall MACRO Addr LOCAL return move @BP[++Offs], #return ; Push return destination to soft stack jump Addr return: endm mret MACRO jump @BP[Offs--] ; Jump to popped destination from soft stack endm下面将讨论这些宏是怎样工作的。
mpush A[0] ; Save the value of the A[0] register mpush A[1] ; Save A[1] mpush A[2] ; Save A[2] ... ; code which destroys A[0]-A[2] mpop A[2] ; Restore the value of A[2] (pop in reverse order) mpop A[1] ; Restore A[1] mpop A[0] ; Restore A[0]
subroutine: mpush A[0] ; Save the current value of A[0] ... ; Code which destroys A[0] mpop A[1] ; Restore A[0] mret
mcall mySub ... mySub: mpush A[0] ; Save A[0] mpush A[1] ; Save A[1] ... ; Perform calculations, etc. mpop A[1] mpop A[0] mret
SS_BASE equ 0000h SS_TOP equ 01FFh ss_init: move DPC, #1Ch ; Set all data pointers to word mode move DP[0], #SS_BASE ; Set pointer to stack base location ret上面的代码存储在数据存储器的0000h至01FFh,因此,产生的堆栈可以保持511级。(没有使用堆栈存储器空间中的某一位置;这样可以更有效,以更短的代码实现mpush/mpop/mcall/mret宏。)
mpush MACRO Reg call ss_check_over ; Check for possible overflow move @++DP[0], Reg ; Push value to soft stack endm mpop MACRO Reg call ss_check_under ; Check for possible underflow move Reg, @DP[0]-- ; Pop value from soft stack endm mcall MACRO Addr LOCAL return call ss_check_over ; Check for possible overflow move @++DP[0], #return ; Push return destination to soft stack jump Addr return: endm mret MACRO call ss_check_under ; Check for possible underflow jump @DP[0]-- ; Jump to popped destination from soft stack endm ss_check_under: push A[0] push AP push APC push PSF move APC, #80h ; Set Acc to A[0], standard mode, no auto inc/dec move Acc, DP[0] ; Get current value of stack pointer cmp #SS_BASE jump NE, ss_check_under_ok nop ; < Error handler should be implemented here > ss_check_under_ok: pop PSF pop APC pop AP pop A[0] ret ss_check_over: push A[0] push AP push APC push PSF move APC, #80h ; Set Acc to A[0], standard mode, no auto inc/dec move Acc, DP[0] ; Get current value of stack pointer cmp #SS_TOP jump NE, ss_check_over_ok nop ; < Error handler should be implemented here > ss_check_over_ok: pop PSF pop APC pop AP pop A[0] ret上面的代码导致在推入或者弹出(或者call,或者ret)操作之前检查当前的堆栈位置。如果探测到下溢或者上溢错误,不同的应用程序有不同的响应。一般情况下,这类错误只会出现在应用程序开发阶段;如果代码编写正确,不会出现这类错误。如果的确出现了错误,一般将其考虑为重大错误,就像使用硬堆栈时出现下溢/上溢错误。对这类错误可能的响应包括暂停,发送错误消息,或者闪烁LED。在开发阶段,一个好的方法是两个程序中的每一个都在MAX-IDE中设置断点(例如,在“Error handler should be implemented here”行中),如果出现下溢或者上溢,立即发出反馈。
全部0条评论
快来发表一下你的评论吧 !