summary refs log tree commit diff
path: root/quine.asm
diff options
context:
space:
mode:
Diffstat (limited to 'quine.asm')
-rw-r--r--quine.asm76
1 files changed, 55 insertions, 21 deletions
diff --git a/quine.asm b/quine.asm
index 9e33bbc..5c4357b 100644
--- a/quine.asm
+++ b/quine.asm
@@ -269,7 +269,7 @@ macro mov.indirect.qreg.qreg target, source
     qwordreg sreg, source
     qwordreg treg, target
     rex.w
-    rb 0x89
+    db 0x89
     modrm 1, sreg, treg
     db 0
   end match
@@ -532,12 +532,31 @@ end macro
 ; of doing anything with the memory, just store the address itself into a
 ; register.
 macro lea.qreg.qreg.disp8 target, offset, source
-  rex.w
-  db 0x8D
-  qwordreg treg, target
-  qwordreg sreg, source
-  modrm 1, treg, sreg
-  db offset
+  match =rsp, target
+    ; This is the SIB case
+    assert 0
+  else
+    qwordreg treg, target
+    qwordreg sreg, source
+    rex.w
+    db 0x8D
+    modrm 1, treg, sreg
+    db offset
+  end match
+end macro
+
+macro lea.qreg.qreg.disp32 target, offset, source
+  match =rsp, target
+    ; This is the SIB case
+    assert 0
+  else
+    qwordreg treg, target
+    qwordreg sreg, source
+    rex.w
+    db 0x8D
+    modrm 2, treg, sreg
+    dd offset
+  end match
 end macro
 
 ; Clear the DF flag. This makes string instructions increment RSI.
@@ -590,7 +609,7 @@ end macro
 macro jmp.abs.indirect.qreg location
   qwordreg lreg, location
   db 0xFF
-  modrm 0, lreg, 4
+  modrm 0, 4, lreg
 end macro
 
 ; There in no 64-bit immediate "near" jump, so we use 32-bit. It's relatve,
@@ -898,8 +917,8 @@ DOCOL:
   NEXT
 
 ;;;
-;;; Routine start
-;;; -------------
+;;; Routine _start
+;;; --------------
 ;;;
 ;;;   This is the entry point of the whole program, the very first code we
 ;;; actually execute. Linkers traditionally call this _start, and on balance
@@ -1017,6 +1036,19 @@ _start:
   mov.qreg.qreg rdi, rax
 
   ;;;
+  ;;;   We also initialize rbp. We could hold off and let QUIT do this, but
+  ;;; doing it now is the easiest way to initialize the R0 variable, since
+  ;;; there's no instruction that moves a 64-bit immediate to memory.
+  ;;;
+  ;;;   This is the moment at which we decide where the control stack starts!
+  ;;; Fun, right? "Allocation" is just a fancy word for picking where we want
+  ;;; something, then being consistent about it - like placing furniture in
+  ;;; your home. See below for a little more thought about why here in
+  ;;; particular.
+  ;;;
+  lea.qreg.qreg.disp32 rbp, control_stack_size, rdi
+
+  ;;;
   ;;;   Now we save some stuff onto the heap. These are the locations that
   ;;; will eventually be the backing stores of the Forth variables, but we
   ;;; don't create the word headers yet, since there's no requirement that
@@ -1077,17 +1109,10 @@ _start:
   push.qreg rdi
 
   ;;;
-  ;;;   Notice that, although we are about to set up rsi, and rsp came to us
-  ;;; already valid, rbp is still uninitialized. This is because we're about
-  ;;; to hand off to QUIT, which will do that for us.
+  ;;;   We are about to set up rsi, we did rbp already, and rsp came to us
+  ;;; already set up. That's all that NEXT needs, so take it away!
   ;;;
   mov.qreg.qimm rsi, cold_start
-
-  ;;;
-  ;;;   That's all that NEXT needs, so, take it away!
-  ;;;
-  jmp.rel.dimm old_code - skip_from_here ; TODO placeholder
-skip_from_here:
   NEXT
 
 ;;;
@@ -1104,7 +1129,13 @@ cold_start:
 ;;;
 QUIT:
   dq DOCOL                       ; codeword
+  dq OLD_CODE
+  ; TODO this is more like what it should be
+  ; Although we initialized rbp already, we do so again because we'll want
+  ; that on subsequent visits to this word - it's the main thing it's for.
   ;dq R0, CONTROL!                ; overwrite rbp to reset the control stack
+    ; Keep in mind that rsi is the actual "instruction pointer", and we're
+    ; leaving it unchanged, we just get rid of everything above it.
   ;dq INTERPRET                   ; run the repl
   ;dq BRANCH, QUIT - $            ; if the repl ever exits, start again
 
@@ -1129,9 +1160,12 @@ QUIT:
 ;;;   chunks, this size must be equal to the buffer size; within a chunk it
 ;;;   may be less.
 ;;;
-;;; * rsp points to the bottom of the buffer.
+;;; * ~~~~rsp points to the bottom of the buffer.~~~~
+;;; TODO WRONG this is all just scribbling where it shouldn't
 ;;;
-old_code:
+OLD_CODE:
+  dq $ + 0x8                               ; The codeword
+
   mov.dreg.dimm rdx, 0                     ; store running file size here
   ;sub.qreg.bimm rsp, 0xFF                  ; reserve stack space