]> git.sur5r.net Git - cc65/commitdiff
Added code to check the 6502 stack
authorcuz <cuz@b7a2c559-68d2-44c3-8de9-860c34a00d81>
Tue, 20 Mar 2001 22:34:08 +0000 (22:34 +0000)
committercuz <cuz@b7a2c559-68d2-44c3-8de9-860c34a00d81>
Tue, 20 Mar 2001 22:34:08 +0000 (22:34 +0000)
git-svn-id: svn://svn.cc65.org/cc65/trunk@638 b7a2c559-68d2-44c3-8de9-860c34a00d81

libsrc/runtime/stkchk.s
src/cc65/codegen.c
src/cc65/codegen.h
src/cc65/function.c
src/cc65/locals.c

index 53f9e1487a3906223bf9a222206034dd4d9837f7..712da3094564b14e4b87623ffef178fdf335342d 100644 (file)
@@ -1,9 +1,10 @@
 ;
 ; Ullrich von Bassewitz, 19.03.2001
 ;
-; Stack checking code.
+; Stack checking code. These are actually two routines, one to check the C
+; stack, and the other one to check the 6502 hardware stack.
 ; For performance reasons (to avoid having to pass a parameter), the compiler
-; calls the stkchk routine *after* allocating space on the stack. So the
+; calls the cstkchk routine *after* allocating space on the stack. So the
 ; stackpointer may already be invalid if this routine is called. In addition
 ; to that, pushs and pops that are needed for expression evaluation are not
 ; checked (this would be way too much overhead). As a consequence we will
@@ -12,7 +13,7 @@
 ; its' bounds.
 ;
 
-       .export         stkchk
+       .export         stkchk, cstkchk
        .constructor    initstkchk, 25
        .import         __STACKSIZE__                   ; Linker defined
                .import         pusha0, _exit
 
 .proc  initstkchk
 
-       lda     sp
-       sta     initialsp
-       sub     #<__STACKSIZE__
-       sta     lowwater
-       lda     sp+1
-       sta     initialsp+1
-       sbc     #>__STACKSIZE__
-       add     #1                      ; Add 256 bytes safety area
-       sta     lowwater+1
+       lda     sp
+       sta     initialsp
+       sub     #<__STACKSIZE__
+       sta     lowwater
+       lda     sp+1
+       sta     initialsp+1
+       sbc     #>__STACKSIZE__
+       add     #1                      ; Add 256 bytes safety area
+       sta     lowwater+1
        rts
 
 .endproc
 
 ; ----------------------------------------------------------------------------
-; Stack checking routine. Does not need to save any registers.
+; 6502 stack checking routine. Does not need to save any registers.
+; Safety zone for the hardware stack is 10 bytes.
 
-.proc  stkchk
+stkchk:        tsx
+               cpx     #10
+               bcc     Fail            ; Jump on stack overflow
+       rts                     ; Return if ok
 
-       lda     lowwater+1
-       cmp     sp+1
-       bcs     @L1
-       rts
+; ----------------------------------------------------------------------------
+; C stack checking routine. Does not need to save any registers.
+
+cstkchk:
+
+; Check the high byte of the software stack
+
+@L0:           lda     lowwater+1
+               cmp     sp+1
+               bcs     @L1
+               rts
 
 ; Check low byte
 
-@L1:   bne     @Overflow
-       lda     lowwater
-       cmp     sp
-       bcs     @Overflow
-       rts
+@L1:   bne     CStackOverflow
+       lda     lowwater
+       cmp     sp
+       bcs     CStackOverflow
+Done:  rts
 
-; We have a stack overflow. Set the stack pointer to the initial value, so
+; We have a stack overflow. Set the stack pointer to the initial value, so
 ; we can continue without worrying about stack issues.
 
-@Overflow:
+CStackOverflow:
        lda     initialsp
        sta     sp
        lda     initialsp+1
        sta     sp+1
-       lda     #4
+
+; Generic abort entry. We should output a diagnostic here, but this is
+; difficult, since we're operating at a lower level here.
+
+Fail:  lda     #4
        jsr     pusha0
        jmp     _exit
 
-.endproc
-
 ; ----------------------------------------------------------------------------
 ; Data
 
index b04ac4b38f3498ee5777b9d16c67528030fe21b0..58595df904c4296c6c74d45d4c6380a839a89cb6 100644 (file)
@@ -2515,6 +2515,14 @@ void g_space (int space)
 
 
 
+void g_cstackcheck (void)
+/* Check for a C stack overflow */
+{
+    AddCodeLine ("\tjsr\tcstkchk");
+}
+
+
+
 void g_stackcheck (void)
 /* Check for a stack overflow */
 {
index f568e815291541635ee7552ec87d51681800a82b..977b868b7e0e4d09d630e44d7a363c687ff6529d 100644 (file)
@@ -371,6 +371,9 @@ void g_falsejump (unsigned flags, unsigned label);
 void g_space (int space);
 /* Create or drop space on the stack */
 
+void g_cstackcheck (void);
+/* Check for a C stack overflow */
+
 void g_stackcheck (void);
 /* Check for a stack overflow */
 
index 393679b778492f8a190111783a18039fd5b7c182..d15fe7262e3d0bf57ff01d7d81d3babbc6b5f48e 100644 (file)
@@ -42,6 +42,7 @@
 #include "codegen.h"
 #include "error.h"
 #include "funcdesc.h"
+#include "global.h"
 #include "litpool.h"
 #include "locals.h"
 #include "scanner.h"
@@ -229,6 +230,11 @@ void NewFunc (SymEntry* Func)
     g_usecode ();
     g_defgloblabel (Func->Name);
 
+    /* If stack cehcking code is requested, emit a call to the helper routine */
+    if (CheckStack) {
+       g_stackcheck ();
+    }
+
     /* Generate function entry code if needed */
     g_enter (TypeOf (Func->Type), GetParamSize (CurrentFunc));
 
@@ -254,7 +260,7 @@ void NewFunc (SymEntry* Func)
        RestoreRegVars (0);
 
        Flags = HasVoidReturn (CurrentFunc)? CF_NONE : CF_REG;
-        g_leave (Flags, 0);                                  
+        g_leave (Flags, 0);
     }
 
     /* Dump literal data created by the function */
index c0083ac286bd48995476251b753a73d61752abc8..c0a62c9f0df95f7f8d2c346eacd2da4c0a0d73aa 100644 (file)
@@ -378,7 +378,7 @@ void DeclareLocals (void)
      * the stack checking routine if stack checks are enabled.
      */
     if (CheckStack && InitialStack != oursp) {
-       g_stackcheck ();
+               g_cstackcheck ();
     }
 }