diff --git a/src/main/java/dk/camelot64/kickc/model/symbols/Scope.java b/src/main/java/dk/camelot64/kickc/model/symbols/Scope.java
index 3b7533f17..6bb5eed90 100644
--- a/src/main/java/dk/camelot64/kickc/model/symbols/Scope.java
+++ b/src/main/java/dk/camelot64/kickc/model/symbols/Scope.java
@@ -169,7 +169,8 @@ public abstract class Scope implements Symbol, Serializable {
 
    public Variable getVariable(String name) {
       Variable symbol = (Variable) getSymbol(name);
-      if(symbol!=null && !symbol.isVariable()) throw new InternalError("Symbol is not a variable! "+symbol.toString());
+      if(symbol!=null && !symbol.isVariable())
+         throw new InternalError("Symbol is not a variable! "+symbol.toString());
       return symbol;
    }
 
diff --git a/src/main/java/dk/camelot64/kickc/passes/Pass3AssertConstants.java b/src/main/java/dk/camelot64/kickc/passes/Pass3AssertConstants.java
index 1faef40c6..347457bcb 100644
--- a/src/main/java/dk/camelot64/kickc/passes/Pass3AssertConstants.java
+++ b/src/main/java/dk/camelot64/kickc/passes/Pass3AssertConstants.java
@@ -6,7 +6,13 @@ import dk.camelot64.kickc.model.Program;
 import dk.camelot64.kickc.model.statements.Statement;
 import dk.camelot64.kickc.model.statements.StatementAsm;
 import dk.camelot64.kickc.model.statements.StatementKickAsm;
-import dk.camelot64.kickc.model.values.*;
+import dk.camelot64.kickc.model.symbols.Procedure;
+import dk.camelot64.kickc.model.symbols.Symbol;
+import dk.camelot64.kickc.model.symbols.Variable;
+import dk.camelot64.kickc.model.values.ConstantRef;
+import dk.camelot64.kickc.model.values.ConstantValue;
+import dk.camelot64.kickc.model.values.RValue;
+import dk.camelot64.kickc.model.values.SymbolRef;
 
 import java.util.List;
 import java.util.Map;
@@ -39,7 +45,7 @@ public class Pass3AssertConstants extends Pass2SsaAssertion {
                   throw new CompileError("Error! KickAssembler bytes is not constant " + bytes.toString(), statement);
                }
                RValue cycles = ((StatementKickAsm) statement).getCycles();
-               if(cycles!= null && !(cycles instanceof ConstantValue)) {
+               if(cycles != null && !(cycles instanceof ConstantValue)) {
                   throw new CompileError("Error! KickAssembler cycles is not constant " + cycles.toString(), statement);
                }
             } else if(statement instanceof StatementAsm) {
@@ -47,9 +53,18 @@ public class Pass3AssertConstants extends Pass2SsaAssertion {
                Map<String, SymbolRef> referenced = statementAsm.getReferenced();
                for(String label : referenced.keySet()) {
                   SymbolRef symbolRef = referenced.get(label);
-                  if(!(symbolRef instanceof ConstantRef) && !(symbolRef instanceof ProcedureRef)) {
+                  Symbol symbol = getScope().getSymbol(symbolRef);
+                  if(symbol instanceof Procedure)
+                     // Referencing procedures are fine!
+                     continue;
+                  else if(symbol instanceof Variable && ((Variable) symbol).isKindConstant())
+                     // Referencing constants are fine!
+                     continue;
+                  else if(symbol instanceof Variable && ((Variable) symbol).isKindLoadStore())
+                     // Referencing load/store is fine!
+                     continue;
+                  else
                      throw new CompileError("Error! Inline ASM reference is not constant " + label, statement);
-                  }
                }
             } else if(statement instanceof StatementKickAsm) {
                StatementKickAsm statementAsm = (StatementKickAsm) statement;
diff --git a/src/main/java/dk/camelot64/kickc/passes/Pass4CodeGeneration.java b/src/main/java/dk/camelot64/kickc/passes/Pass4CodeGeneration.java
index 7b0364747..2a9712759 100644
--- a/src/main/java/dk/camelot64/kickc/passes/Pass4CodeGeneration.java
+++ b/src/main/java/dk/camelot64/kickc/passes/Pass4CodeGeneration.java
@@ -276,7 +276,10 @@ public class Pass4CodeGeneration {
          signature.append(param.getType().getTypeName()).append(" ");
          if(allocation instanceof Registers.RegisterZpMem) {
             Registers.RegisterZpMem registerZp = (Registers.RegisterZpMem) allocation;
-            signature.append("zeropage(").append(AsmFormat.getAsmNumber(registerZp.getZp())).append(")");
+            signature.append("zp(").append(AsmFormat.getAsmNumber(registerZp.getZp())).append(")");
+         } else if(allocation instanceof Registers.RegisterMainMem) {
+            Registers.RegisterMainMem registerMainMem = (Registers.RegisterMainMem) allocation;
+            signature.append("mem(").append(AsmFormat.getAsmNumber(registerMainMem.getAddress())).append(")");
          } else if(allocation instanceof Registers.RegisterAByte) {
             signature.append("register(A)");
          } else if(allocation instanceof Registers.RegisterXByte) {
diff --git a/src/test/java/dk/camelot64/kickc/test/TestPrograms.java b/src/test/java/dk/camelot64/kickc/test/TestPrograms.java
index 7db205b64..c1e348468 100644
--- a/src/test/java/dk/camelot64/kickc/test/TestPrograms.java
+++ b/src/test/java/dk/camelot64/kickc/test/TestPrograms.java
@@ -37,6 +37,21 @@ public class TestPrograms {
    public TestPrograms() {
    }
 
+   @Test
+   public void testRegister0() throws IOException, URISyntaxException {
+      compileAndCompare("register-0");
+   }
+
+   @Test
+   public void testAddress6() throws IOException, URISyntaxException {
+      compileAndCompare("address-6");
+   }
+
+   @Test
+   public void testAddress5() throws IOException, URISyntaxException {
+      compileAndCompare("address-5");
+   }
+
    @Test
    public void testAddress4() throws IOException, URISyntaxException {
       compileAndCompare("address-4");
diff --git a/src/test/kc/address-5.kc b/src/test/kc/address-5.kc
new file mode 100644
index 000000000..91ca7cece
--- /dev/null
+++ b/src/test/kc/address-5.kc
@@ -0,0 +1,21 @@
+// Test declaring a variable as at a hard-coded address
+// zero-page hard-coded address parameter
+
+void main() {
+    print('c');
+    print('m');
+    print('l');
+}
+
+const char* SCREEN = 0x0400;
+
+volatile char __address(0x03) idx;
+
+void print(char __address(0x02) ch) {
+    asm {
+        ldx idx
+        lda ch
+        sta SCREEN,x
+        inc idx
+    }
+}
diff --git a/src/test/kc/address-6.kc b/src/test/kc/address-6.kc
new file mode 100644
index 000000000..13bab1790
--- /dev/null
+++ b/src/test/kc/address-6.kc
@@ -0,0 +1,21 @@
+// Test declaring a variable as at a hard-coded address
+// mainmem-page hard-coded address parameter
+
+void main() {
+    print('c');
+    print('m');
+    print('l');
+}
+
+const char* SCREEN = 0x0400;
+
+volatile char __address(0x3000) idx;
+
+void print(char __address(0x3001) ch) {
+    asm {
+        ldx idx
+        lda ch
+        sta SCREEN,x
+        inc idx
+    }
+}
diff --git a/src/test/kc/register-0.kc b/src/test/kc/register-0.kc
new file mode 100644
index 000000000..f19e86883
--- /dev/null
+++ b/src/test/kc/register-0.kc
@@ -0,0 +1,22 @@
+// Test declaring a variable as at a hard-coded register
+// hard-coded register parameter
+
+void main() {
+    print('c');
+    print('m');
+    print('l');
+}
+
+const char* SCREEN = 0x0400;
+
+volatile char __address(0x03) idx;
+
+void print(char register(A) ch) {
+    // Force usage of ch
+    kickasm(uses ch) {{ }}
+    asm {
+        ldx idx
+        sta SCREEN,x
+        inc idx
+    }
+}
diff --git a/src/test/ref/address-5.asm b/src/test/ref/address-5.asm
new file mode 100644
index 000000000..3277a648b
--- /dev/null
+++ b/src/test/ref/address-5.asm
@@ -0,0 +1,33 @@
+// Test declaring a variable as at a hard-coded address
+// zero-page hard-coded address parameter
+.pc = $801 "Basic"
+:BasicUpstart(__b1)
+.pc = $80d "Program"
+  .label SCREEN = $400
+  .label idx = 3
+__b1:
+  lda #0
+  sta.z idx
+  jsr main
+  rts
+main: {
+    lda #'c'
+    sta.z print.ch
+    jsr print
+    lda #'m'
+    sta.z print.ch
+    jsr print
+    lda #'l'
+    sta.z print.ch
+    jsr print
+    rts
+}
+// print(byte zeropage(2) ch)
+print: {
+    .label ch = 2
+    ldx idx
+    lda ch
+    sta SCREEN,x
+    inc idx
+    rts
+}
diff --git a/src/test/ref/address-5.cfg b/src/test/ref/address-5.cfg
new file mode 100644
index 000000000..bfd51f44a
--- /dev/null
+++ b/src/test/ref/address-5.cfg
@@ -0,0 +1,37 @@
+@begin: scope:[]  from
+  [0] phi()
+  to:@1
+@1: scope:[]  from @begin
+  [1] (byte) idx ← (byte) 0
+  to:@2
+@2: scope:[]  from @1
+  [2] phi()
+  [3] call main 
+  to:@end
+@end: scope:[]  from @2
+  [4] phi()
+
+(void()) main()
+main: scope:[main]  from @2
+  [5] (byte) print::ch ← (byte) 'c'
+  [6] call print 
+  to:main::@1
+main::@1: scope:[main]  from main
+  [7] (byte) print::ch ← (byte) 'm'
+  [8] call print 
+  to:main::@2
+main::@2: scope:[main]  from main::@1
+  [9] (byte) print::ch ← (byte) 'l'
+  [10] call print 
+  to:main::@return
+main::@return: scope:[main]  from main::@2
+  [11] return 
+  to:@return
+
+(void()) print((byte) print::ch)
+print: scope:[print]  from main main::@1 main::@2
+  asm { ldxidx ldach staSCREEN,x incidx  }
+  to:print::@return
+print::@return: scope:[print]  from print
+  [13] return 
+  to:@return
diff --git a/src/test/ref/address-5.log b/src/test/ref/address-5.log
new file mode 100644
index 000000000..9588b4b7a
--- /dev/null
+++ b/src/test/ref/address-5.log
@@ -0,0 +1,421 @@
+
+CONTROL FLOW GRAPH SSA
+@begin: scope:[]  from
+  to:@1
+
+(void()) main()
+main: scope:[main]  from @2
+  (byte) print::ch ← (byte) 'c'
+  call print 
+  to:main::@1
+main::@1: scope:[main]  from main
+  (byte) print::ch ← (byte) 'm'
+  call print 
+  to:main::@2
+main::@2: scope:[main]  from main::@1
+  (byte) print::ch ← (byte) 'l'
+  call print 
+  to:main::@3
+main::@3: scope:[main]  from main::@2
+  to:main::@return
+main::@return: scope:[main]  from main::@3
+  return 
+  to:@return
+@1: scope:[]  from @begin
+  (byte) idx ← (byte) 0
+  to:@2
+
+(void()) print((byte) print::ch)
+print: scope:[print]  from main main::@1 main::@2
+  asm { ldxidx ldach staSCREEN,x incidx  }
+  to:print::@return
+print::@return: scope:[print]  from print
+  return 
+  to:@return
+@2: scope:[]  from @1
+  call main 
+  to:@3
+@3: scope:[]  from @2
+  to:@end
+@end: scope:[]  from @3
+
+SYMBOL TABLE SSA
+(label) @1
+(label) @2
+(label) @3
+(label) @begin
+(label) @end
+(const byte*) SCREEN = (byte*)(number) $400
+(byte) idx loadstore !zp[-1]:3
+(void()) main()
+(label) main::@1
+(label) main::@2
+(label) main::@3
+(label) main::@return
+(void()) print((byte) print::ch)
+(label) print::@return
+(byte) print::ch loadstore !zp[-1]:2
+
+Simplifying constant pointer cast (byte*) 1024
+Successful SSA optimization PassNCastSimplification
+Adding NOP phi() at start of @begin
+Adding NOP phi() at start of @2
+Adding NOP phi() at start of @3
+Adding NOP phi() at start of @end
+Adding NOP phi() at start of main::@3
+CALL GRAPH
+Calls in [] to main:3 
+Calls in [main] to print:7 print:9 print:11 
+
+Created 0 initial phi equivalence classes
+Coalesced down to 0 phi equivalence classes
+Culled Empty Block (label) @3
+Culled Empty Block (label) main::@3
+Adding NOP phi() at start of @begin
+Adding NOP phi() at start of @2
+Adding NOP phi() at start of @end
+
+FINAL CONTROL FLOW GRAPH
+@begin: scope:[]  from
+  [0] phi()
+  to:@1
+@1: scope:[]  from @begin
+  [1] (byte) idx ← (byte) 0
+  to:@2
+@2: scope:[]  from @1
+  [2] phi()
+  [3] call main 
+  to:@end
+@end: scope:[]  from @2
+  [4] phi()
+
+(void()) main()
+main: scope:[main]  from @2
+  [5] (byte) print::ch ← (byte) 'c'
+  [6] call print 
+  to:main::@1
+main::@1: scope:[main]  from main
+  [7] (byte) print::ch ← (byte) 'm'
+  [8] call print 
+  to:main::@2
+main::@2: scope:[main]  from main::@1
+  [9] (byte) print::ch ← (byte) 'l'
+  [10] call print 
+  to:main::@return
+main::@return: scope:[main]  from main::@2
+  [11] return 
+  to:@return
+
+(void()) print((byte) print::ch)
+print: scope:[print]  from main main::@1 main::@2
+  asm { ldxidx ldach staSCREEN,x incidx  }
+  to:print::@return
+print::@return: scope:[print]  from print
+  [13] return 
+  to:@return
+
+
+VARIABLE REGISTER WEIGHTS
+(byte) idx loadstore !zp[-1]:3 0.2222222222222222
+(void()) main()
+(void()) print((byte) print::ch)
+(byte) print::ch loadstore !zp[-1]:2 2.0
+
+Initial phi equivalence classes
+Added variable idx to live range equivalence class [ idx ]
+Added variable print::ch to live range equivalence class [ print::ch ]
+Complete equivalence classes
+[ idx ]
+[ print::ch ]
+
+INITIAL ASM
+Target platform is c64basic / MOS6502X
+  // File Comments
+// Test declaring a variable as at a hard-coded address
+// zero-page hard-coded address parameter
+  // Upstart
+.pc = $801 "Basic"
+:BasicUpstart(__bbegin)
+.pc = $80d "Program"
+  // Global Constants & labels
+  .label SCREEN = $400
+  .label idx = 3
+  // @begin
+__bbegin:
+  jmp __b1
+  // @1
+__b1:
+  // [1] (byte) idx ← (byte) 0 -- vbuz1=vbuc1 
+  lda #0
+  sta.z idx
+  // [2] phi from @1 to @2 [phi:@1->@2]
+__b2_from___b1:
+  jmp __b2
+  // @2
+__b2:
+  // [3] call main 
+  jsr main
+  // [4] phi from @2 to @end [phi:@2->@end]
+__bend_from___b2:
+  jmp __bend
+  // @end
+__bend:
+  // main
+main: {
+    // [5] (byte) print::ch ← (byte) 'c' -- vbuz1=vbuc1 
+    lda #'c'
+    sta.z print.ch
+    // [6] call print 
+    jsr print
+    jmp __b1
+    // main::@1
+  __b1:
+    // [7] (byte) print::ch ← (byte) 'm' -- vbuz1=vbuc1 
+    lda #'m'
+    sta.z print.ch
+    // [8] call print 
+    jsr print
+    jmp __b2
+    // main::@2
+  __b2:
+    // [9] (byte) print::ch ← (byte) 'l' -- vbuz1=vbuc1 
+    lda #'l'
+    sta.z print.ch
+    // [10] call print 
+    jsr print
+    jmp __breturn
+    // main::@return
+  __breturn:
+    // [11] return 
+    rts
+}
+  // print
+// print(byte zeropage(2) ch)
+print: {
+    .label ch = 2
+    // asm { ldxidx ldach staSCREEN,x incidx  }
+    ldx idx
+    lda ch
+    sta SCREEN,x
+    inc idx
+    jmp __breturn
+    // print::@return
+  __breturn:
+    // [13] return 
+    rts
+}
+  // File Data
+
+REGISTER UPLIFT POTENTIAL REGISTERS
+Statement [1] (byte) idx ← (byte) 0 [ idx ] (  [ idx ] ) always clobbers reg byte a 
+Statement [5] (byte) print::ch ← (byte) 'c' [ idx print::ch ] ( main:3 [ idx print::ch ] ) always clobbers reg byte a 
+Statement [7] (byte) print::ch ← (byte) 'm' [ idx print::ch ] ( main:3 [ idx print::ch ] ) always clobbers reg byte a 
+Statement [9] (byte) print::ch ← (byte) 'l' [ idx print::ch ] ( main:3 [ idx print::ch ] ) always clobbers reg byte a 
+Statement asm { ldxidx ldach staSCREEN,x incidx  } always clobbers reg byte a reg byte x 
+Potential registers zp[1]:3 [ idx ] : zp[1]:3 , 
+Potential registers zp[1]:2 [ print::ch ] : zp[1]:2 , 
+
+REGISTER UPLIFT SCOPES
+Uplift Scope [print] 2: zp[1]:2 [ print::ch ] 
+Uplift Scope [] 0.22: zp[1]:3 [ idx ] 
+Uplift Scope [main] 
+
+Uplifting [print] best 123 combination zp[1]:2 [ print::ch ] 
+Uplifting [] best 123 combination zp[1]:3 [ idx ] 
+Uplifting [main] best 123 combination 
+Attempting to uplift remaining variables inzp[1]:2 [ print::ch ]
+Uplifting [print] best 123 combination zp[1]:2 [ print::ch ] 
+Attempting to uplift remaining variables inzp[1]:3 [ idx ]
+Uplifting [] best 123 combination zp[1]:3 [ idx ] 
+
+ASSEMBLER BEFORE OPTIMIZATION
+  // File Comments
+// Test declaring a variable as at a hard-coded address
+// zero-page hard-coded address parameter
+  // Upstart
+.pc = $801 "Basic"
+:BasicUpstart(__bbegin)
+.pc = $80d "Program"
+  // Global Constants & labels
+  .label SCREEN = $400
+  .label idx = 3
+  // @begin
+__bbegin:
+  jmp __b1
+  // @1
+__b1:
+  // [1] (byte) idx ← (byte) 0 -- vbuz1=vbuc1 
+  lda #0
+  sta.z idx
+  // [2] phi from @1 to @2 [phi:@1->@2]
+__b2_from___b1:
+  jmp __b2
+  // @2
+__b2:
+  // [3] call main 
+  jsr main
+  // [4] phi from @2 to @end [phi:@2->@end]
+__bend_from___b2:
+  jmp __bend
+  // @end
+__bend:
+  // main
+main: {
+    // [5] (byte) print::ch ← (byte) 'c' -- vbuz1=vbuc1 
+    lda #'c'
+    sta.z print.ch
+    // [6] call print 
+    jsr print
+    jmp __b1
+    // main::@1
+  __b1:
+    // [7] (byte) print::ch ← (byte) 'm' -- vbuz1=vbuc1 
+    lda #'m'
+    sta.z print.ch
+    // [8] call print 
+    jsr print
+    jmp __b2
+    // main::@2
+  __b2:
+    // [9] (byte) print::ch ← (byte) 'l' -- vbuz1=vbuc1 
+    lda #'l'
+    sta.z print.ch
+    // [10] call print 
+    jsr print
+    jmp __breturn
+    // main::@return
+  __breturn:
+    // [11] return 
+    rts
+}
+  // print
+// print(byte zeropage(2) ch)
+print: {
+    .label ch = 2
+    // asm { ldxidx ldach staSCREEN,x incidx  }
+    ldx idx
+    lda ch
+    sta SCREEN,x
+    inc idx
+    jmp __breturn
+    // print::@return
+  __breturn:
+    // [13] return 
+    rts
+}
+  // File Data
+
+ASSEMBLER OPTIMIZATIONS
+Removing instruction jmp __b1
+Removing instruction jmp __b2
+Removing instruction jmp __bend
+Removing instruction jmp __b1
+Removing instruction jmp __b2
+Removing instruction jmp __breturn
+Removing instruction jmp __breturn
+Succesful ASM optimization Pass5NextJumpElimination
+Replacing label __bbegin with __b1
+Removing instruction __bbegin:
+Removing instruction __b2_from___b1:
+Removing instruction __bend_from___b2:
+Succesful ASM optimization Pass5RedundantLabelElimination
+Removing instruction __b2:
+Removing instruction __bend:
+Removing instruction __b1:
+Removing instruction __b2:
+Removing instruction __breturn:
+Removing instruction __breturn:
+Succesful ASM optimization Pass5UnusedLabelElimination
+Adding RTS to root block 
+Succesful ASM optimization Pass5AddMainRts
+
+FINAL SYMBOL TABLE
+(label) @1
+(label) @2
+(label) @begin
+(label) @end
+(const byte*) SCREEN = (byte*) 1024
+(byte) idx loadstore !zp[-1]:3 zp[1]:3 0.2222222222222222
+(void()) main()
+(label) main::@1
+(label) main::@2
+(label) main::@return
+(void()) print((byte) print::ch)
+(label) print::@return
+(byte) print::ch loadstore !zp[-1]:2 zp[1]:2 2.0
+
+zp[1]:3 [ idx ]
+zp[1]:2 [ print::ch ]
+
+
+FINAL ASSEMBLER
+Score: 81
+
+  // File Comments
+// Test declaring a variable as at a hard-coded address
+// zero-page hard-coded address parameter
+  // Upstart
+.pc = $801 "Basic"
+:BasicUpstart(__b1)
+.pc = $80d "Program"
+  // Global Constants & labels
+  .label SCREEN = $400
+  .label idx = 3
+  // @begin
+  // @1
+__b1:
+  // idx
+  // [1] (byte) idx ← (byte) 0 -- vbuz1=vbuc1 
+  lda #0
+  sta.z idx
+  // [2] phi from @1 to @2 [phi:@1->@2]
+  // @2
+  // [3] call main 
+  jsr main
+  rts
+  // [4] phi from @2 to @end [phi:@2->@end]
+  // @end
+  // main
+main: {
+    // print('c')
+    // [5] (byte) print::ch ← (byte) 'c' -- vbuz1=vbuc1 
+    lda #'c'
+    sta.z print.ch
+    // [6] call print 
+    jsr print
+    // main::@1
+    // print('m')
+    // [7] (byte) print::ch ← (byte) 'm' -- vbuz1=vbuc1 
+    lda #'m'
+    sta.z print.ch
+    // [8] call print 
+    jsr print
+    // main::@2
+    // print('l')
+    // [9] (byte) print::ch ← (byte) 'l' -- vbuz1=vbuc1 
+    lda #'l'
+    sta.z print.ch
+    // [10] call print 
+    jsr print
+    // main::@return
+    // }
+    // [11] return 
+    rts
+}
+  // print
+// print(byte zeropage(2) ch)
+print: {
+    .label ch = 2
+    // asm
+    // asm { ldxidx ldach staSCREEN,x incidx  }
+    ldx idx
+    lda ch
+    sta SCREEN,x
+    inc idx
+    // print::@return
+    // }
+    // [13] return 
+    rts
+}
+  // File Data
+
diff --git a/src/test/ref/address-5.sym b/src/test/ref/address-5.sym
new file mode 100644
index 000000000..d22044338
--- /dev/null
+++ b/src/test/ref/address-5.sym
@@ -0,0 +1,16 @@
+(label) @1
+(label) @2
+(label) @begin
+(label) @end
+(const byte*) SCREEN = (byte*) 1024
+(byte) idx loadstore !zp[-1]:3 zp[1]:3 0.2222222222222222
+(void()) main()
+(label) main::@1
+(label) main::@2
+(label) main::@return
+(void()) print((byte) print::ch)
+(label) print::@return
+(byte) print::ch loadstore !zp[-1]:2 zp[1]:2 2.0
+
+zp[1]:3 [ idx ]
+zp[1]:2 [ print::ch ]
diff --git a/src/test/ref/address-6.asm b/src/test/ref/address-6.asm
new file mode 100644
index 000000000..213bcf965
--- /dev/null
+++ b/src/test/ref/address-6.asm
@@ -0,0 +1,33 @@
+// Test declaring a variable as at a hard-coded address
+// mainmem-page hard-coded address parameter
+.pc = $801 "Basic"
+:BasicUpstart(__b1)
+.pc = $80d "Program"
+  .label SCREEN = $400
+  .label idx = $3000
+__b1:
+  lda #0
+  sta idx
+  jsr main
+  rts
+main: {
+    lda #'c'
+    sta print.ch
+    jsr print
+    lda #'m'
+    sta print.ch
+    jsr print
+    lda #'l'
+    sta print.ch
+    jsr print
+    rts
+}
+// print(byte mem($3001) ch)
+print: {
+    .label ch = $3001
+    ldx idx
+    lda ch
+    sta SCREEN,x
+    inc idx
+    rts
+}
diff --git a/src/test/ref/address-6.cfg b/src/test/ref/address-6.cfg
new file mode 100644
index 000000000..bfd51f44a
--- /dev/null
+++ b/src/test/ref/address-6.cfg
@@ -0,0 +1,37 @@
+@begin: scope:[]  from
+  [0] phi()
+  to:@1
+@1: scope:[]  from @begin
+  [1] (byte) idx ← (byte) 0
+  to:@2
+@2: scope:[]  from @1
+  [2] phi()
+  [3] call main 
+  to:@end
+@end: scope:[]  from @2
+  [4] phi()
+
+(void()) main()
+main: scope:[main]  from @2
+  [5] (byte) print::ch ← (byte) 'c'
+  [6] call print 
+  to:main::@1
+main::@1: scope:[main]  from main
+  [7] (byte) print::ch ← (byte) 'm'
+  [8] call print 
+  to:main::@2
+main::@2: scope:[main]  from main::@1
+  [9] (byte) print::ch ← (byte) 'l'
+  [10] call print 
+  to:main::@return
+main::@return: scope:[main]  from main::@2
+  [11] return 
+  to:@return
+
+(void()) print((byte) print::ch)
+print: scope:[print]  from main main::@1 main::@2
+  asm { ldxidx ldach staSCREEN,x incidx  }
+  to:print::@return
+print::@return: scope:[print]  from print
+  [13] return 
+  to:@return
diff --git a/src/test/ref/address-6.log b/src/test/ref/address-6.log
new file mode 100644
index 000000000..134be8ae5
--- /dev/null
+++ b/src/test/ref/address-6.log
@@ -0,0 +1,421 @@
+
+CONTROL FLOW GRAPH SSA
+@begin: scope:[]  from
+  to:@1
+
+(void()) main()
+main: scope:[main]  from @2
+  (byte) print::ch ← (byte) 'c'
+  call print 
+  to:main::@1
+main::@1: scope:[main]  from main
+  (byte) print::ch ← (byte) 'm'
+  call print 
+  to:main::@2
+main::@2: scope:[main]  from main::@1
+  (byte) print::ch ← (byte) 'l'
+  call print 
+  to:main::@3
+main::@3: scope:[main]  from main::@2
+  to:main::@return
+main::@return: scope:[main]  from main::@3
+  return 
+  to:@return
+@1: scope:[]  from @begin
+  (byte) idx ← (byte) 0
+  to:@2
+
+(void()) print((byte) print::ch)
+print: scope:[print]  from main main::@1 main::@2
+  asm { ldxidx ldach staSCREEN,x incidx  }
+  to:print::@return
+print::@return: scope:[print]  from print
+  return 
+  to:@return
+@2: scope:[]  from @1
+  call main 
+  to:@3
+@3: scope:[]  from @2
+  to:@end
+@end: scope:[]  from @3
+
+SYMBOL TABLE SSA
+(label) @1
+(label) @2
+(label) @3
+(label) @begin
+(label) @end
+(const byte*) SCREEN = (byte*)(number) $400
+(byte) idx loadstore !mem[-1]:12288
+(void()) main()
+(label) main::@1
+(label) main::@2
+(label) main::@3
+(label) main::@return
+(void()) print((byte) print::ch)
+(label) print::@return
+(byte) print::ch loadstore !mem[-1]:12289
+
+Simplifying constant pointer cast (byte*) 1024
+Successful SSA optimization PassNCastSimplification
+Adding NOP phi() at start of @begin
+Adding NOP phi() at start of @2
+Adding NOP phi() at start of @3
+Adding NOP phi() at start of @end
+Adding NOP phi() at start of main::@3
+CALL GRAPH
+Calls in [] to main:3 
+Calls in [main] to print:7 print:9 print:11 
+
+Created 0 initial phi equivalence classes
+Coalesced down to 0 phi equivalence classes
+Culled Empty Block (label) @3
+Culled Empty Block (label) main::@3
+Adding NOP phi() at start of @begin
+Adding NOP phi() at start of @2
+Adding NOP phi() at start of @end
+
+FINAL CONTROL FLOW GRAPH
+@begin: scope:[]  from
+  [0] phi()
+  to:@1
+@1: scope:[]  from @begin
+  [1] (byte) idx ← (byte) 0
+  to:@2
+@2: scope:[]  from @1
+  [2] phi()
+  [3] call main 
+  to:@end
+@end: scope:[]  from @2
+  [4] phi()
+
+(void()) main()
+main: scope:[main]  from @2
+  [5] (byte) print::ch ← (byte) 'c'
+  [6] call print 
+  to:main::@1
+main::@1: scope:[main]  from main
+  [7] (byte) print::ch ← (byte) 'm'
+  [8] call print 
+  to:main::@2
+main::@2: scope:[main]  from main::@1
+  [9] (byte) print::ch ← (byte) 'l'
+  [10] call print 
+  to:main::@return
+main::@return: scope:[main]  from main::@2
+  [11] return 
+  to:@return
+
+(void()) print((byte) print::ch)
+print: scope:[print]  from main main::@1 main::@2
+  asm { ldxidx ldach staSCREEN,x incidx  }
+  to:print::@return
+print::@return: scope:[print]  from print
+  [13] return 
+  to:@return
+
+
+VARIABLE REGISTER WEIGHTS
+(byte) idx loadstore !mem[-1]:12288 0.2222222222222222
+(void()) main()
+(void()) print((byte) print::ch)
+(byte) print::ch loadstore !mem[-1]:12289 2.0
+
+Initial phi equivalence classes
+Added variable idx to live range equivalence class [ idx ]
+Added variable print::ch to live range equivalence class [ print::ch ]
+Complete equivalence classes
+[ idx ]
+[ print::ch ]
+
+INITIAL ASM
+Target platform is c64basic / MOS6502X
+  // File Comments
+// Test declaring a variable as at a hard-coded address
+// mainmem-page hard-coded address parameter
+  // Upstart
+.pc = $801 "Basic"
+:BasicUpstart(__bbegin)
+.pc = $80d "Program"
+  // Global Constants & labels
+  .label SCREEN = $400
+  .label idx = $3000
+  // @begin
+__bbegin:
+  jmp __b1
+  // @1
+__b1:
+  // [1] (byte) idx ← (byte) 0 -- vbum1=vbuc1 
+  lda #0
+  sta idx
+  // [2] phi from @1 to @2 [phi:@1->@2]
+__b2_from___b1:
+  jmp __b2
+  // @2
+__b2:
+  // [3] call main 
+  jsr main
+  // [4] phi from @2 to @end [phi:@2->@end]
+__bend_from___b2:
+  jmp __bend
+  // @end
+__bend:
+  // main
+main: {
+    // [5] (byte) print::ch ← (byte) 'c' -- vbum1=vbuc1 
+    lda #'c'
+    sta print.ch
+    // [6] call print 
+    jsr print
+    jmp __b1
+    // main::@1
+  __b1:
+    // [7] (byte) print::ch ← (byte) 'm' -- vbum1=vbuc1 
+    lda #'m'
+    sta print.ch
+    // [8] call print 
+    jsr print
+    jmp __b2
+    // main::@2
+  __b2:
+    // [9] (byte) print::ch ← (byte) 'l' -- vbum1=vbuc1 
+    lda #'l'
+    sta print.ch
+    // [10] call print 
+    jsr print
+    jmp __breturn
+    // main::@return
+  __breturn:
+    // [11] return 
+    rts
+}
+  // print
+// print(byte mem($3001) ch)
+print: {
+    .label ch = $3001
+    // asm { ldxidx ldach staSCREEN,x incidx  }
+    ldx idx
+    lda ch
+    sta SCREEN,x
+    inc idx
+    jmp __breturn
+    // print::@return
+  __breturn:
+    // [13] return 
+    rts
+}
+  // File Data
+
+REGISTER UPLIFT POTENTIAL REGISTERS
+Statement [1] (byte) idx ← (byte) 0 [ idx ] (  [ idx ] ) always clobbers reg byte a 
+Statement [5] (byte) print::ch ← (byte) 'c' [ idx print::ch ] ( main:3 [ idx print::ch ] ) always clobbers reg byte a 
+Statement [7] (byte) print::ch ← (byte) 'm' [ idx print::ch ] ( main:3 [ idx print::ch ] ) always clobbers reg byte a 
+Statement [9] (byte) print::ch ← (byte) 'l' [ idx print::ch ] ( main:3 [ idx print::ch ] ) always clobbers reg byte a 
+Statement asm { ldxidx ldach staSCREEN,x incidx  } always clobbers reg byte a reg byte x 
+Potential registers mem[1]:12288 [ idx ] : mem[1]:12288 , 
+Potential registers mem[1]:12289 [ print::ch ] : mem[1]:12289 , 
+
+REGISTER UPLIFT SCOPES
+Uplift Scope [print] 2: mem[1]:12289 [ print::ch ] 
+Uplift Scope [] 0.22: mem[1]:12288 [ idx ] 
+Uplift Scope [main] 
+
+Uplifting [print] best 127 combination mem[1]:12289 [ print::ch ] 
+Uplifting [] best 127 combination mem[1]:12288 [ idx ] 
+Uplifting [main] best 127 combination 
+Attempting to uplift remaining variables inmem[1]:12289 [ print::ch ]
+Uplifting [print] best 127 combination mem[1]:12289 [ print::ch ] 
+Attempting to uplift remaining variables inmem[1]:12288 [ idx ]
+Uplifting [] best 127 combination mem[1]:12288 [ idx ] 
+
+ASSEMBLER BEFORE OPTIMIZATION
+  // File Comments
+// Test declaring a variable as at a hard-coded address
+// mainmem-page hard-coded address parameter
+  // Upstart
+.pc = $801 "Basic"
+:BasicUpstart(__bbegin)
+.pc = $80d "Program"
+  // Global Constants & labels
+  .label SCREEN = $400
+  .label idx = $3000
+  // @begin
+__bbegin:
+  jmp __b1
+  // @1
+__b1:
+  // [1] (byte) idx ← (byte) 0 -- vbum1=vbuc1 
+  lda #0
+  sta idx
+  // [2] phi from @1 to @2 [phi:@1->@2]
+__b2_from___b1:
+  jmp __b2
+  // @2
+__b2:
+  // [3] call main 
+  jsr main
+  // [4] phi from @2 to @end [phi:@2->@end]
+__bend_from___b2:
+  jmp __bend
+  // @end
+__bend:
+  // main
+main: {
+    // [5] (byte) print::ch ← (byte) 'c' -- vbum1=vbuc1 
+    lda #'c'
+    sta print.ch
+    // [6] call print 
+    jsr print
+    jmp __b1
+    // main::@1
+  __b1:
+    // [7] (byte) print::ch ← (byte) 'm' -- vbum1=vbuc1 
+    lda #'m'
+    sta print.ch
+    // [8] call print 
+    jsr print
+    jmp __b2
+    // main::@2
+  __b2:
+    // [9] (byte) print::ch ← (byte) 'l' -- vbum1=vbuc1 
+    lda #'l'
+    sta print.ch
+    // [10] call print 
+    jsr print
+    jmp __breturn
+    // main::@return
+  __breturn:
+    // [11] return 
+    rts
+}
+  // print
+// print(byte mem($3001) ch)
+print: {
+    .label ch = $3001
+    // asm { ldxidx ldach staSCREEN,x incidx  }
+    ldx idx
+    lda ch
+    sta SCREEN,x
+    inc idx
+    jmp __breturn
+    // print::@return
+  __breturn:
+    // [13] return 
+    rts
+}
+  // File Data
+
+ASSEMBLER OPTIMIZATIONS
+Removing instruction jmp __b1
+Removing instruction jmp __b2
+Removing instruction jmp __bend
+Removing instruction jmp __b1
+Removing instruction jmp __b2
+Removing instruction jmp __breturn
+Removing instruction jmp __breturn
+Succesful ASM optimization Pass5NextJumpElimination
+Replacing label __bbegin with __b1
+Removing instruction __bbegin:
+Removing instruction __b2_from___b1:
+Removing instruction __bend_from___b2:
+Succesful ASM optimization Pass5RedundantLabelElimination
+Removing instruction __b2:
+Removing instruction __bend:
+Removing instruction __b1:
+Removing instruction __b2:
+Removing instruction __breturn:
+Removing instruction __breturn:
+Succesful ASM optimization Pass5UnusedLabelElimination
+Adding RTS to root block 
+Succesful ASM optimization Pass5AddMainRts
+
+FINAL SYMBOL TABLE
+(label) @1
+(label) @2
+(label) @begin
+(label) @end
+(const byte*) SCREEN = (byte*) 1024
+(byte) idx loadstore !mem[-1]:12288 mem[1]:12288 0.2222222222222222
+(void()) main()
+(label) main::@1
+(label) main::@2
+(label) main::@return
+(void()) print((byte) print::ch)
+(label) print::@return
+(byte) print::ch loadstore !mem[-1]:12289 mem[1]:12289 2.0
+
+mem[1]:12288 [ idx ]
+mem[1]:12289 [ print::ch ]
+
+
+FINAL ASSEMBLER
+Score: 85
+
+  // File Comments
+// Test declaring a variable as at a hard-coded address
+// mainmem-page hard-coded address parameter
+  // Upstart
+.pc = $801 "Basic"
+:BasicUpstart(__b1)
+.pc = $80d "Program"
+  // Global Constants & labels
+  .label SCREEN = $400
+  .label idx = $3000
+  // @begin
+  // @1
+__b1:
+  // idx
+  // [1] (byte) idx ← (byte) 0 -- vbum1=vbuc1 
+  lda #0
+  sta idx
+  // [2] phi from @1 to @2 [phi:@1->@2]
+  // @2
+  // [3] call main 
+  jsr main
+  rts
+  // [4] phi from @2 to @end [phi:@2->@end]
+  // @end
+  // main
+main: {
+    // print('c')
+    // [5] (byte) print::ch ← (byte) 'c' -- vbum1=vbuc1 
+    lda #'c'
+    sta print.ch
+    // [6] call print 
+    jsr print
+    // main::@1
+    // print('m')
+    // [7] (byte) print::ch ← (byte) 'm' -- vbum1=vbuc1 
+    lda #'m'
+    sta print.ch
+    // [8] call print 
+    jsr print
+    // main::@2
+    // print('l')
+    // [9] (byte) print::ch ← (byte) 'l' -- vbum1=vbuc1 
+    lda #'l'
+    sta print.ch
+    // [10] call print 
+    jsr print
+    // main::@return
+    // }
+    // [11] return 
+    rts
+}
+  // print
+// print(byte mem($3001) ch)
+print: {
+    .label ch = $3001
+    // asm
+    // asm { ldxidx ldach staSCREEN,x incidx  }
+    ldx idx
+    lda ch
+    sta SCREEN,x
+    inc idx
+    // print::@return
+    // }
+    // [13] return 
+    rts
+}
+  // File Data
+
diff --git a/src/test/ref/address-6.sym b/src/test/ref/address-6.sym
new file mode 100644
index 000000000..97e2daeb9
--- /dev/null
+++ b/src/test/ref/address-6.sym
@@ -0,0 +1,16 @@
+(label) @1
+(label) @2
+(label) @begin
+(label) @end
+(const byte*) SCREEN = (byte*) 1024
+(byte) idx loadstore !mem[-1]:12288 mem[1]:12288 0.2222222222222222
+(void()) main()
+(label) main::@1
+(label) main::@2
+(label) main::@return
+(void()) print((byte) print::ch)
+(label) print::@return
+(byte) print::ch loadstore !mem[-1]:12289 mem[1]:12289 2.0
+
+mem[1]:12288 [ idx ]
+mem[1]:12289 [ print::ch ]
diff --git a/src/test/ref/register-0.asm b/src/test/ref/register-0.asm
new file mode 100644
index 000000000..1c2f799df
--- /dev/null
+++ b/src/test/ref/register-0.asm
@@ -0,0 +1,30 @@
+// Test declaring a variable as at a hard-coded register
+// hard-coded register parameter
+.pc = $801 "Basic"
+:BasicUpstart(__b1)
+.pc = $80d "Program"
+  .label SCREEN = $400
+  .label idx = 3
+__b1:
+  lda #0
+  sta.z idx
+  jsr main
+  rts
+main: {
+    lda #'c'
+    jsr print
+    lda #'m'
+    jsr print
+    lda #'l'
+    jsr print
+    rts
+}
+// print(byte register(A) ch)
+print: {
+    // Force usage of ch
+    
+    ldx idx
+    sta SCREEN,x
+    inc idx
+    rts
+}
diff --git a/src/test/ref/register-0.cfg b/src/test/ref/register-0.cfg
new file mode 100644
index 000000000..dc24ff2b9
--- /dev/null
+++ b/src/test/ref/register-0.cfg
@@ -0,0 +1,39 @@
+@begin: scope:[]  from
+  [0] phi()
+  to:@1
+@1: scope:[]  from @begin
+  [1] (byte) idx ← (byte) 0
+  to:@2
+@2: scope:[]  from @1
+  [2] phi()
+  [3] call main 
+  to:@end
+@end: scope:[]  from @2
+  [4] phi()
+
+(void()) main()
+main: scope:[main]  from @2
+  [5] phi()
+  [6] call print 
+  to:main::@1
+main::@1: scope:[main]  from main
+  [7] phi()
+  [8] call print 
+  to:main::@2
+main::@2: scope:[main]  from main::@1
+  [9] phi()
+  [10] call print 
+  to:main::@return
+main::@return: scope:[main]  from main::@2
+  [11] return 
+  to:@return
+
+(void()) print((byte) print::ch)
+print: scope:[print]  from main main::@1 main::@2
+  [12] (byte) print::ch#3 ← phi( main/(byte) 'c' main::@1/(byte) 'm' main::@2/(byte) 'l' )
+  kickasm( uses print::ch#3) {{  }}
+  asm { ldxidx staSCREEN,x incidx  }
+  to:print::@return
+print::@return: scope:[print]  from print
+  [15] return 
+  to:@return
diff --git a/src/test/ref/register-0.log b/src/test/ref/register-0.log
new file mode 100644
index 000000000..786473398
--- /dev/null
+++ b/src/test/ref/register-0.log
@@ -0,0 +1,474 @@
+
+CONTROL FLOW GRAPH SSA
+@begin: scope:[]  from
+  to:@1
+
+(void()) main()
+main: scope:[main]  from @2
+  (byte) print::ch#0 ← (byte) 'c'
+  call print 
+  to:main::@1
+main::@1: scope:[main]  from main
+  (byte) print::ch#1 ← (byte) 'm'
+  call print 
+  to:main::@2
+main::@2: scope:[main]  from main::@1
+  (byte) print::ch#2 ← (byte) 'l'
+  call print 
+  to:main::@3
+main::@3: scope:[main]  from main::@2
+  to:main::@return
+main::@return: scope:[main]  from main::@3
+  return 
+  to:@return
+@1: scope:[]  from @begin
+  (byte) idx ← (byte) 0
+  to:@2
+
+(void()) print((byte) print::ch)
+print: scope:[print]  from main main::@1 main::@2
+  (byte) print::ch#3 ← phi( main/(byte) print::ch#0 main::@1/(byte) print::ch#1 main::@2/(byte) print::ch#2 )
+  kickasm( uses print::ch#3) {{  }}
+  asm { ldxidx staSCREEN,x incidx  }
+  to:print::@return
+print::@return: scope:[print]  from print
+  return 
+  to:@return
+@2: scope:[]  from @1
+  call main 
+  to:@3
+@3: scope:[]  from @2
+  to:@end
+@end: scope:[]  from @3
+
+SYMBOL TABLE SSA
+(label) @1
+(label) @2
+(label) @3
+(label) @begin
+(label) @end
+(const byte*) SCREEN = (byte*)(number) $400
+(byte) idx loadstore !zp[-1]:3
+(void()) main()
+(label) main::@1
+(label) main::@2
+(label) main::@3
+(label) main::@return
+(void()) print((byte) print::ch)
+(label) print::@return
+(byte) print::ch !reg byte a
+(byte) print::ch#0 !reg byte a
+(byte) print::ch#1 !reg byte a
+(byte) print::ch#2 !reg byte a
+(byte) print::ch#3 !reg byte a
+
+Simplifying constant pointer cast (byte*) 1024
+Successful SSA optimization PassNCastSimplification
+Constant (const byte) print::ch#0 = 'c'
+Constant (const byte) print::ch#1 = 'm'
+Constant (const byte) print::ch#2 = 'l'
+Successful SSA optimization Pass2ConstantIdentification
+Inlining constant with var siblings (const byte) print::ch#0
+Inlining constant with var siblings (const byte) print::ch#1
+Inlining constant with var siblings (const byte) print::ch#2
+Constant inlined print::ch#2 = (byte) 'l'
+Constant inlined print::ch#1 = (byte) 'm'
+Constant inlined print::ch#0 = (byte) 'c'
+Successful SSA optimization Pass2ConstantInlining
+Adding NOP phi() at start of @begin
+Adding NOP phi() at start of @2
+Adding NOP phi() at start of @3
+Adding NOP phi() at start of @end
+Adding NOP phi() at start of main
+Adding NOP phi() at start of main::@1
+Adding NOP phi() at start of main::@2
+Adding NOP phi() at start of main::@3
+CALL GRAPH
+Calls in [] to main:3 
+Calls in [main] to print:7 print:9 print:11 
+
+Created 1 initial phi equivalence classes
+Coalesced down to 1 phi equivalence classes
+Culled Empty Block (label) @3
+Culled Empty Block (label) main::@3
+Adding NOP phi() at start of @begin
+Adding NOP phi() at start of @2
+Adding NOP phi() at start of @end
+Adding NOP phi() at start of main
+Adding NOP phi() at start of main::@1
+Adding NOP phi() at start of main::@2
+
+FINAL CONTROL FLOW GRAPH
+@begin: scope:[]  from
+  [0] phi()
+  to:@1
+@1: scope:[]  from @begin
+  [1] (byte) idx ← (byte) 0
+  to:@2
+@2: scope:[]  from @1
+  [2] phi()
+  [3] call main 
+  to:@end
+@end: scope:[]  from @2
+  [4] phi()
+
+(void()) main()
+main: scope:[main]  from @2
+  [5] phi()
+  [6] call print 
+  to:main::@1
+main::@1: scope:[main]  from main
+  [7] phi()
+  [8] call print 
+  to:main::@2
+main::@2: scope:[main]  from main::@1
+  [9] phi()
+  [10] call print 
+  to:main::@return
+main::@return: scope:[main]  from main::@2
+  [11] return 
+  to:@return
+
+(void()) print((byte) print::ch)
+print: scope:[print]  from main main::@1 main::@2
+  [12] (byte) print::ch#3 ← phi( main/(byte) 'c' main::@1/(byte) 'm' main::@2/(byte) 'l' )
+  kickasm( uses print::ch#3) {{  }}
+  asm { ldxidx staSCREEN,x incidx  }
+  to:print::@return
+print::@return: scope:[print]  from print
+  [15] return 
+  to:@return
+
+
+VARIABLE REGISTER WEIGHTS
+(byte) idx loadstore !zp[-1]:3 0.18181818181818182
+(void()) main()
+(void()) print((byte) print::ch)
+(byte) print::ch !reg byte a
+(byte) print::ch#3 !reg byte a
+
+Initial phi equivalence classes
+[ print::ch#3 ]
+Added variable idx to live range equivalence class [ idx ]
+Complete equivalence classes
+[ print::ch#3 ]
+[ idx ]
+
+INITIAL ASM
+Target platform is c64basic / MOS6502X
+  // File Comments
+// Test declaring a variable as at a hard-coded register
+// hard-coded register parameter
+  // Upstart
+.pc = $801 "Basic"
+:BasicUpstart(__bbegin)
+.pc = $80d "Program"
+  // Global Constants & labels
+  .label SCREEN = $400
+  .label idx = 3
+  // @begin
+__bbegin:
+  jmp __b1
+  // @1
+__b1:
+  // [1] (byte) idx ← (byte) 0 -- vbuz1=vbuc1 
+  lda #0
+  sta.z idx
+  // [2] phi from @1 to @2 [phi:@1->@2]
+__b2_from___b1:
+  jmp __b2
+  // @2
+__b2:
+  // [3] call main 
+  // [5] phi from @2 to main [phi:@2->main]
+main_from___b2:
+  jsr main
+  // [4] phi from @2 to @end [phi:@2->@end]
+__bend_from___b2:
+  jmp __bend
+  // @end
+__bend:
+  // main
+main: {
+    // [6] call print 
+    // [12] phi from main to print [phi:main->print]
+  print_from_main:
+    // [12] phi (byte) print::ch#3 = (byte) 'c' [phi:main->print#0] -- vbuaa=vbuc1 
+    lda #'c'
+    jsr print
+    // [7] phi from main to main::@1 [phi:main->main::@1]
+  __b1_from_main:
+    jmp __b1
+    // main::@1
+  __b1:
+    // [8] call print 
+    // [12] phi from main::@1 to print [phi:main::@1->print]
+  print_from___b1:
+    // [12] phi (byte) print::ch#3 = (byte) 'm' [phi:main::@1->print#0] -- vbuaa=vbuc1 
+    lda #'m'
+    jsr print
+    // [9] phi from main::@1 to main::@2 [phi:main::@1->main::@2]
+  __b2_from___b1:
+    jmp __b2
+    // main::@2
+  __b2:
+    // [10] call print 
+    // [12] phi from main::@2 to print [phi:main::@2->print]
+  print_from___b2:
+    // [12] phi (byte) print::ch#3 = (byte) 'l' [phi:main::@2->print#0] -- vbuaa=vbuc1 
+    lda #'l'
+    jsr print
+    jmp __breturn
+    // main::@return
+  __breturn:
+    // [11] return 
+    rts
+}
+  // print
+// print(byte register(A) ch)
+print: {
+    // kickasm( uses print::ch#3) {{  }}
+    // Force usage of ch
+    
+    // asm { ldxidx staSCREEN,x incidx  }
+    ldx idx
+    sta SCREEN,x
+    inc idx
+    jmp __breturn
+    // print::@return
+  __breturn:
+    // [15] return 
+    rts
+}
+  // File Data
+
+REGISTER UPLIFT POTENTIAL REGISTERS
+Statement [1] (byte) idx ← (byte) 0 [ idx ] (  [ idx ] ) always clobbers reg byte a 
+Statement asm { ldxidx staSCREEN,x incidx  } always clobbers reg byte x 
+Potential registers reg byte a [ print::ch#3 ] : reg byte a , 
+Potential registers zp[1]:3 [ idx ] : zp[1]:3 , 
+
+REGISTER UPLIFT SCOPES
+Uplift Scope [] 0.18: zp[1]:3 [ idx ] 
+Uplift Scope [main] 
+Uplift Scope [print] 0: reg byte a [ print::ch#3 ] 
+
+Uplifting [] best 366 combination zp[1]:3 [ idx ] 
+Uplifting [main] best 366 combination 
+Uplifting [print] best 366 combination reg byte a [ print::ch#3 ] 
+Attempting to uplift remaining variables inzp[1]:3 [ idx ]
+Uplifting [] best 366 combination zp[1]:3 [ idx ] 
+
+ASSEMBLER BEFORE OPTIMIZATION
+  // File Comments
+// Test declaring a variable as at a hard-coded register
+// hard-coded register parameter
+  // Upstart
+.pc = $801 "Basic"
+:BasicUpstart(__bbegin)
+.pc = $80d "Program"
+  // Global Constants & labels
+  .label SCREEN = $400
+  .label idx = 3
+  // @begin
+__bbegin:
+  jmp __b1
+  // @1
+__b1:
+  // [1] (byte) idx ← (byte) 0 -- vbuz1=vbuc1 
+  lda #0
+  sta.z idx
+  // [2] phi from @1 to @2 [phi:@1->@2]
+__b2_from___b1:
+  jmp __b2
+  // @2
+__b2:
+  // [3] call main 
+  // [5] phi from @2 to main [phi:@2->main]
+main_from___b2:
+  jsr main
+  // [4] phi from @2 to @end [phi:@2->@end]
+__bend_from___b2:
+  jmp __bend
+  // @end
+__bend:
+  // main
+main: {
+    // [6] call print 
+    // [12] phi from main to print [phi:main->print]
+  print_from_main:
+    // [12] phi (byte) print::ch#3 = (byte) 'c' [phi:main->print#0] -- vbuaa=vbuc1 
+    lda #'c'
+    jsr print
+    // [7] phi from main to main::@1 [phi:main->main::@1]
+  __b1_from_main:
+    jmp __b1
+    // main::@1
+  __b1:
+    // [8] call print 
+    // [12] phi from main::@1 to print [phi:main::@1->print]
+  print_from___b1:
+    // [12] phi (byte) print::ch#3 = (byte) 'm' [phi:main::@1->print#0] -- vbuaa=vbuc1 
+    lda #'m'
+    jsr print
+    // [9] phi from main::@1 to main::@2 [phi:main::@1->main::@2]
+  __b2_from___b1:
+    jmp __b2
+    // main::@2
+  __b2:
+    // [10] call print 
+    // [12] phi from main::@2 to print [phi:main::@2->print]
+  print_from___b2:
+    // [12] phi (byte) print::ch#3 = (byte) 'l' [phi:main::@2->print#0] -- vbuaa=vbuc1 
+    lda #'l'
+    jsr print
+    jmp __breturn
+    // main::@return
+  __breturn:
+    // [11] return 
+    rts
+}
+  // print
+// print(byte register(A) ch)
+print: {
+    // kickasm( uses print::ch#3) {{  }}
+    // Force usage of ch
+    
+    // asm { ldxidx staSCREEN,x incidx  }
+    ldx idx
+    sta SCREEN,x
+    inc idx
+    jmp __breturn
+    // print::@return
+  __breturn:
+    // [15] return 
+    rts
+}
+  // File Data
+
+ASSEMBLER OPTIMIZATIONS
+Removing instruction jmp __b1
+Removing instruction jmp __b2
+Removing instruction jmp __bend
+Removing instruction jmp __b1
+Removing instruction jmp __b2
+Removing instruction jmp __breturn
+Removing instruction jmp __breturn
+Succesful ASM optimization Pass5NextJumpElimination
+Replacing label __bbegin with __b1
+Removing instruction __bbegin:
+Removing instruction __b2_from___b1:
+Removing instruction main_from___b2:
+Removing instruction __bend_from___b2:
+Removing instruction __b1_from_main:
+Removing instruction print_from___b1:
+Removing instruction __b2_from___b1:
+Removing instruction print_from___b2:
+Succesful ASM optimization Pass5RedundantLabelElimination
+Removing instruction __b2:
+Removing instruction __bend:
+Removing instruction print_from_main:
+Removing instruction __b1:
+Removing instruction __b2:
+Removing instruction __breturn:
+Removing instruction __breturn:
+Succesful ASM optimization Pass5UnusedLabelElimination
+Adding RTS to root block 
+Succesful ASM optimization Pass5AddMainRts
+
+FINAL SYMBOL TABLE
+(label) @1
+(label) @2
+(label) @begin
+(label) @end
+(const byte*) SCREEN = (byte*) 1024
+(byte) idx loadstore !zp[-1]:3 zp[1]:3 0.18181818181818182
+(void()) main()
+(label) main::@1
+(label) main::@2
+(label) main::@return
+(void()) print((byte) print::ch)
+(label) print::@return
+(byte) print::ch !reg byte a
+(byte) print::ch#3 !reg byte a
+
+reg byte a [ print::ch#3 ]
+zp[1]:3 [ idx ]
+
+
+FINAL ASSEMBLER
+Score: 324
+
+  // File Comments
+// Test declaring a variable as at a hard-coded register
+// hard-coded register parameter
+  // Upstart
+.pc = $801 "Basic"
+:BasicUpstart(__b1)
+.pc = $80d "Program"
+  // Global Constants & labels
+  .label SCREEN = $400
+  .label idx = 3
+  // @begin
+  // @1
+__b1:
+  // idx
+  // [1] (byte) idx ← (byte) 0 -- vbuz1=vbuc1 
+  lda #0
+  sta.z idx
+  // [2] phi from @1 to @2 [phi:@1->@2]
+  // @2
+  // [3] call main 
+  // [5] phi from @2 to main [phi:@2->main]
+  jsr main
+  rts
+  // [4] phi from @2 to @end [phi:@2->@end]
+  // @end
+  // main
+main: {
+    // print('c')
+    // [6] call print 
+    // [12] phi from main to print [phi:main->print]
+    // [12] phi (byte) print::ch#3 = (byte) 'c' [phi:main->print#0] -- vbuaa=vbuc1 
+    lda #'c'
+    jsr print
+    // [7] phi from main to main::@1 [phi:main->main::@1]
+    // main::@1
+    // print('m')
+    // [8] call print 
+    // [12] phi from main::@1 to print [phi:main::@1->print]
+    // [12] phi (byte) print::ch#3 = (byte) 'm' [phi:main::@1->print#0] -- vbuaa=vbuc1 
+    lda #'m'
+    jsr print
+    // [9] phi from main::@1 to main::@2 [phi:main::@1->main::@2]
+    // main::@2
+    // print('l')
+    // [10] call print 
+    // [12] phi from main::@2 to print [phi:main::@2->print]
+    // [12] phi (byte) print::ch#3 = (byte) 'l' [phi:main::@2->print#0] -- vbuaa=vbuc1 
+    lda #'l'
+    jsr print
+    // main::@return
+    // }
+    // [11] return 
+    rts
+}
+  // print
+// print(byte register(A) ch)
+print: {
+    // kickasm
+    // kickasm( uses print::ch#3) {{  }}
+    // Force usage of ch
+    
+    // asm
+    // asm { ldxidx staSCREEN,x incidx  }
+    ldx idx
+    sta SCREEN,x
+    inc idx
+    // print::@return
+    // }
+    // [15] return 
+    rts
+}
+  // File Data
+
diff --git a/src/test/ref/register-0.sym b/src/test/ref/register-0.sym
new file mode 100644
index 000000000..8bc4b1852
--- /dev/null
+++ b/src/test/ref/register-0.sym
@@ -0,0 +1,17 @@
+(label) @1
+(label) @2
+(label) @begin
+(label) @end
+(const byte*) SCREEN = (byte*) 1024
+(byte) idx loadstore !zp[-1]:3 zp[1]:3 0.18181818181818182
+(void()) main()
+(label) main::@1
+(label) main::@2
+(label) main::@return
+(void()) print((byte) print::ch)
+(label) print::@return
+(byte) print::ch !reg byte a
+(byte) print::ch#3 !reg byte a
+
+reg byte a [ print::ch#3 ]
+zp[1]:3 [ idx ]