76 of 158
70 ' initialize the jump buffer Select Case SetJmp(jmpBuf1) Case 0 ' control came back from SetJmp() debug.print "calling foo()" Call foo(jmpBuf1) debug.print "normal return from foo()" Case 1 ' control came back from LongJmp() debug.print "SetJmp() returned 1 via LongJmp()" End Select debug.print "end test" End Sub Sub foo(ByRef jb() as Byte) debug.print "in foo()" Call bar(jb) debug.print "returning from foo()" End Sub Sub bar(ByRef jb() as Byte) debug.print "in bar()" Call LongJmp(jb, 1) debug.print "returning from bar()" End Sub 3.11 Run Time Stack Checking On VM mode devices (e.g. the ZX-24a), the control program on the ZX implements optional run-time stack overflow detection. You can enable and disable the checking at any time using the System Library subroutine StackCheck(). There is a small performance penalty for the stack check although the checking is only done after operations that add data to the stack. When stack checking is enabled the stack pointer is compared against the “end of stack” value in the current task’s Task Control Block less the current setting of Register.StackMargin. If the stack pointer exceeds the limit a stack fault is generated and the processor is reset. When the processor begins running again Register.ResetFlags will indicate that a WatchDog reset occurred and Register.FaultType will have the value 1 indicating a stack fault condition occurred. Also, Register.FaultData will contain the address of the Task Control Block of the task that was running when the stack fault was detected. Register.FaultData2 will contain the address of the instruction that was executing at the time of the fault. Note that Register.FaultType is a persistent value. If you add code to your application to respond to the fault condition you’ll want to reset Register.FaultType to zero after responding to it. Register.FaultData and Register.FaultData2 are also persistent but it will usually not be necessary to reset its value. 3.12 Conditional Compilation Directives The ZBasic compiler supports conditional compilation. This means that you can add conditional constructs to your code to specify that a portion of the code should be or should not be processed by the compiler. This is useful in order to create source code that can be compiled in different ways. Such flexibility can be used to create special versions of your application for different markets or for different customers, etc. It also provides a fast way to logically remove blocks of code from your program while leaving the source code intact so that it can be easily restored. A key element of conditional compilation is the ability to define special identifiers and to give them values. These identifiers can then be used in conditional expressions that control whether or not a block of code