diff --git a/src/main/fragment/mos6502-common/_stackpushword_=vwuz1.asm b/src/main/fragment/mos6502-common/_stackpushword_=vwuz1.asm
new file mode 100644
index 000000000..e2bfb1cdf
--- /dev/null
+++ b/src/main/fragment/mos6502-common/_stackpushword_=vwuz1.asm
@@ -0,0 +1,4 @@
+lda {z1}+1
+pha
+lda {z1}
+pha
diff --git a/src/main/fragment/mos6502-common/vwuz1=vwuz2_minus_2.asm b/src/main/fragment/mos6502-common/vwuz1=vwuz2_minus_2.asm
new file mode 100644
index 000000000..0ccfb8c08
--- /dev/null
+++ b/src/main/fragment/mos6502-common/vwuz1=vwuz2_minus_2.asm
@@ -0,0 +1,7 @@
+lda {z2}
+sec
+sbc #2
+sta {z1}
+lda {z2}+1
+sbc #0
+sta {z1}+1
diff --git a/src/main/java/dk/camelot64/kickc/passes/Pass1AssertNoRecursion.java b/src/main/java/dk/camelot64/kickc/passes/Pass1AssertNoRecursion.java
index 461808a21..85dc3da2e 100644
--- a/src/main/java/dk/camelot64/kickc/passes/Pass1AssertNoRecursion.java
+++ b/src/main/java/dk/camelot64/kickc/passes/Pass1AssertNoRecursion.java
@@ -21,7 +21,7 @@ public class Pass1AssertNoRecursion extends Pass1Base {
       Collection<Procedure> procedures = getScope().getAllProcedures(true);
       for(Procedure procedure : procedures) {
          Collection<ScopeRef> recursiveCalls = callGraph.getRecursiveCalls(procedure.getRef());
-         if(recursiveCalls.contains(procedure.getRef())) {
+         if(recursiveCalls.contains(procedure.getRef()) && !procedure.getCallingConvension().equals(Procedure.CallingConvension.STACK_CALL)) {
             throw new CompileError("ERROR! Recursion not allowed! Occurs in " + procedure.getRef());
          }
       }
diff --git a/src/main/java/dk/camelot64/kickc/passes/Pass1ModifiedVarsAnalysis.java b/src/main/java/dk/camelot64/kickc/passes/Pass1ModifiedVarsAnalysis.java
index 4c9c02865..a81461cdb 100644
--- a/src/main/java/dk/camelot64/kickc/passes/Pass1ModifiedVarsAnalysis.java
+++ b/src/main/java/dk/camelot64/kickc/passes/Pass1ModifiedVarsAnalysis.java
@@ -26,7 +26,7 @@ public class Pass1ModifiedVarsAnalysis extends Pass1Base {
       Map<ProcedureRef, Set<VariableRef>> modified = new LinkedHashMap<>();
       Collection<Procedure> allProcedures = getScope().getAllProcedures(true);
       for(Procedure procedure : allProcedures) {
-         Set<VariableRef> modifiedVars = getModifiedVars(procedure);
+         Set<VariableRef> modifiedVars = getModifiedVars(procedure, new HashSet<>());
          modified.put(procedure.getRef(), modifiedVars);
       }
       getProgram().setProcedureModifiedVars(new ProcedureModifiedVars(modified));
@@ -39,7 +39,12 @@ public class Pass1ModifiedVarsAnalysis extends Pass1Base {
     * @param procedure The procedure to examine
     * @return All variables declared outside the procedure modified inside the procedure.
     */
-   public Set<VariableRef> getModifiedVars(Procedure procedure) {
+   private Set<VariableRef> getModifiedVars(Procedure procedure, Set<ProcedureRef> visited) {
+      // Avoid recursion
+      if(visited.contains(procedure.getRef()))
+         return new LinkedHashSet<>();
+      visited.add(procedure.getRef());
+
       Set<VariableRef> modified = new LinkedHashSet<>();
       ScopeRef procScope = procedure.getRef();
       List<ControlFlowBlock> procBlocks = getProgram().getGraph().getScopeBlocks(procScope);
@@ -56,7 +61,7 @@ public class Pass1ModifiedVarsAnalysis extends Pass1Base {
                if(statement instanceof StatementCalling) {
                   ProcedureRef called = ((StatementCalling) statement).getProcedure();
                   Procedure calledProc = getScope().getProcedure(called);
-                  modified.addAll(getModifiedVars(calledProc));
+                  modified.addAll(getModifiedVars(calledProc, visited));
                }
             }
          }
diff --git a/src/main/java/dk/camelot64/kickc/passes/Pass3LoopDepthAnalysis.java b/src/main/java/dk/camelot64/kickc/passes/Pass3LoopDepthAnalysis.java
index 5c4d8c701..9d9e54770 100644
--- a/src/main/java/dk/camelot64/kickc/passes/Pass3LoopDepthAnalysis.java
+++ b/src/main/java/dk/camelot64/kickc/passes/Pass3LoopDepthAnalysis.java
@@ -54,12 +54,17 @@ public class Pass3LoopDepthAnalysis extends Pass2Base {
             }
          }
          // Find the scope blocks calling the current scope block - and the loop depth of the blocks where the call statement is
-         int callingDepth = getCallingDepth(currentScope);
+         int callingDepth = getCallingDepth(currentScope, new HashSet<>());
          findLoopDepth(currentScope, callingDepth);
       }
    }
 
-   private int getCallingDepth(ScopeRef currentScope) {
+   private int getCallingDepth(ScopeRef currentScope, Set<ScopeRef> visited) {
+
+      if(visited.contains(currentScope))
+         return 10;
+      visited.add(currentScope);
+
       int callingDepth = 1;
       Collection<ScopeRef> callingScopes = callGraph.getCallingBlocks(currentScope);
       for(ScopeRef callingScope : callingScopes) {
@@ -82,7 +87,7 @@ public class Pass3LoopDepthAnalysis extends Pass2Base {
                }
             }
             // Also look through all callers
-            int superCallingDepth = getCallingDepth(callingScope);
+            int superCallingDepth = getCallingDepth(callingScope, visited);
             if(superCallingDepth>callingDepth)  {
                callingDepth= superCallingDepth;
             }
diff --git a/src/main/java/dk/camelot64/kickc/passes/calcs/PassNCalcLiveRangesEffective.java b/src/main/java/dk/camelot64/kickc/passes/calcs/PassNCalcLiveRangesEffective.java
index 24566147b..2b9458391 100644
--- a/src/main/java/dk/camelot64/kickc/passes/calcs/PassNCalcLiveRangesEffective.java
+++ b/src/main/java/dk/camelot64/kickc/passes/calcs/PassNCalcLiveRangesEffective.java
@@ -52,11 +52,16 @@ public class PassNCalcLiveRangesEffective extends PassNCalcBase<LiveRangeVariabl
       this.procedureCallPaths = new LinkedHashMap<>();
       Collection<Procedure> procedures = getProgram().getScope().getAllProcedures(true);
       for(Procedure procedure : procedures) {
-         populateProcedureCallPaths(procedure);
+         populateProcedureCallPaths(procedure, new HashSet<>());
       }
    }
 
-   private void populateProcedureCallPaths(Procedure procedure) {
+   private void populateProcedureCallPaths(Procedure procedure, Set<ProcedureRef> visited) {
+      // Avoid recursion
+      if(visited.contains(procedure.getRef()))
+         return;
+      visited.add(procedure.getRef());
+
       ProcedureRef procedureRef = procedure.getRef();
       LiveRangeVariablesEffective.CallPaths callPaths = procedureCallPaths.get(procedureRef);
       if(callPaths == null) {
@@ -84,11 +89,12 @@ public class PassNCalcLiveRangesEffective extends PassNCalcBase<LiveRangeVariabl
                // Found calling procedure!
                Procedure callerProcedure = (Procedure) callScope;
                // Make sure we have populated the call-paths of the calling procedure
-               populateProcedureCallPaths(callerProcedure);
+               populateProcedureCallPaths(callerProcedure, visited);
                // Find variables referenced in caller procedure
                Collection<VariableRef> referencedInCaller = referenceInfo.getReferencedVars(callerProcedure.getRef().getLabelRef());
                // For each caller path - create a new call-path
                LiveRangeVariablesEffective.CallPaths callerPaths = procedureCallPaths.get(callerProcedure.getRef());
+               if(callerPaths!=null) 
                for(LiveRangeVariablesEffective.CallPath callerPath : callerPaths.getCallPaths()) {
                   ArrayList<CallGraph.CallBlock.Call> path = new ArrayList<>(callerPath.getPath());
                   path.add(caller);
diff --git a/src/test/java/dk/camelot64/kickc/test/TestPrograms.java b/src/test/java/dk/camelot64/kickc/test/TestPrograms.java
index 2d5b8b773..42716283d 100644
--- a/src/test/java/dk/camelot64/kickc/test/TestPrograms.java
+++ b/src/test/java/dk/camelot64/kickc/test/TestPrograms.java
@@ -35,6 +35,13 @@ public class TestPrograms {
    public TestPrograms() {
    }
 
+   /*
+   @Test
+   public void testProcedureCallingConventionStack6() throws IOException, URISyntaxException {
+      compileAndCompare("procedure-callingconvention-stack-6", log()); //, log().verboseCreateSsa().verboseParse().verboseStatementSequence());
+   }
+   */
+
    @Test
    public void testProcedureCallingConventionStack5() throws IOException, URISyntaxException {
       compileAndCompare("procedure-callingconvention-stack-5"); //, log().verboseCreateSsa().verboseParse().verboseStatementSequence());
diff --git a/src/test/kc/procedure-callingconvention-stack-6.kc b/src/test/kc/procedure-callingconvention-stack-6.kc
new file mode 100644
index 000000000..5d4edb94e
--- /dev/null
+++ b/src/test/kc/procedure-callingconvention-stack-6.kc
@@ -0,0 +1,15 @@
+// Test a procedure with calling convention stack
+// Recursive fibonacci
+
+const char* SCREEN = 0x0400;
+
+void main(void) {
+    *SCREEN = fib(5);
+}
+
+char __stackcall fib(char n) {
+  if (n == 0 || n == 1)
+    return n;
+  else
+    return (fib(n-1) + fib(n-2));
+}
\ No newline at end of file