diff options
| author | Irene Knapp <ireneista@irenes.space> | 2025-11-03 22:46:38 -0800 |
|---|---|---|
| committer | Irene Knapp <ireneista@irenes.space> | 2025-11-03 22:46:38 -0800 |
| commit | 5902fef2ec1ebb8b8d1040bbdbff537949025aaa (patch) | |
| tree | e38b9d40b937bcb2e93782cda28eb7accc1ae093 | |
| parent | e3299e135f4a137892db12e58bf3a6490871eaf4 (diff) | |
the variable words are fully defined on the heap now
not used for anything yet, but hey verifying this required a lot of time in the debugger Force-Push: yes Change-Id: I38a9536ce8efde236b1ed81ca94e0cf7e101413d
| -rw-r--r-- | quine.asm | 77 |
1 files changed, 66 insertions, 11 deletions
diff --git a/quine.asm b/quine.asm index 9be965d..5ecc29e 100644 --- a/quine.asm +++ b/quine.asm @@ -1900,12 +1900,15 @@ cold_start: ;;; on the stack ;;; Start defining some words that are allocated at runtime on the heap, ;;; beginning with the minimal set of words needed to define more words. - dq litstring, "heap", early_create - dq lit, 0x42, early_comma - dq litstring, "s0", early_create - dq litstring, "r0", early_create - dq litstring, "latest", early_create - dq litstring, "here", early_create + ;;; The first few are our variables, which hardcode the addresses they will + ;;; return - but since we're doing this at runtime, "hardcoding" can reflect + ;;; where our heap is. This is the fundamental trick that makes the heap + ;;; usable. + dq early_heap, litstring, "heap", early_defvar + dq early_s0, litstring, "s0", early_defvar + dq early_r0, litstring, "r0", early_defvar + dq early_latest, litstring, "latest", early_defvar + dq early_here, litstring, "here", early_defvar dq quit ;;;;;;;;;;;;;;;;;;;;;;;;;;; @@ -2700,7 +2703,8 @@ defword reg64, 0 dq dup, rbp, eq, zbranch, 5*8, drop, lit, 5, exit dq dup, rsi, eq, zbranch, 5*8, drop, lit, 6, exit dq dup, rdi, eq, zbranch, 5*8, drop, lit, 7, exit - dq sys_exit + dq litstring, "Parameter to reg64 is not a reg64.", emitstring + dq lit, 1, sys_exit ; Stack in: ; register name @@ -2716,7 +2720,8 @@ defword extrareg64, 0 dq dup, r13, eq, zbranch, 5*8, drop, lit, 5, exit dq dup, r14, eq, zbranch, 5*8, drop, lit, 6, exit dq dup, r15, eq, zbranch, 5*8, drop, lit, 7, exit - dq sys_exit + dq litstring, "Parameter to extrareg64 is not an extrareg64.", emitstring + dq lit, 1, sys_exit ; Stack: ; output point @@ -2770,6 +2775,21 @@ defword mov_reg64_reg64, 0 ; Stack: ; output point +; source register name +defword push_reg64, 0 + dq docol, reg64, lit, 0x50, opcodereg, exit + +defword lodsq, 0 + dq docol, rex_w, lit, 0xAD, pack8, exit + +defword jmp_abs_indirect_qreg, 0 + dq docol + dq swap, lit, 0xFF, pack8, swap + dq reg64, lit, 0, lit, 4, roll3, modrm + dq exit + +; Stack: +; output point defword syscall, 0 dq docol, lit, 0x0F, pack8, lit, 0x05, pack8, exit @@ -2895,6 +2915,32 @@ defword early_self_codeword, 0 defword early_here_store, 0 dq docol, swap, early_here, swap, unroll3, store, exit +; Notice that we've switched over to stuff that follows the pack* idioms. +; +; Stack in: +; base address +; Stack out: +; new base address +defword pack_next, 0 + dq docol, lodsq, rax, jmp_abs_indirect_qreg, exit + +; Stack in: +; heap address +; address for new variable word to return +; name string +; Stack out: +; heap address +defword early_defvar, 0 + dq docol + dq swap, unroll3, early_create, early_self_codeword + ; (address to return, heap address) + dq early_here, fetch, swap, unroll3, swap + ; (heap address, modified "here" value, address to return) + dq rax, mov_reg64_imm64, rax, push_reg64 + ; (heap address, modified "here" value) + dq pack_next, lit, 8, packalign, early_here_store + dq exit + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;; Now.... what was our original goal, again? ;;; @@ -2934,7 +2980,7 @@ defword quit, 0 ;;; If the repl ever exits, do it all again. ;;; ;dq branch, quit - $ - dq sys_exit + dq lit, 0, sys_exit ;;;;;;;;;;;;;;;;;;;; @@ -2952,13 +2998,14 @@ defword quit, 0 ;;; ;;; -;;; This does the Linux exit() system call, passing it exit code zero. +;;; This does the Linux exit() system call, passing it an exit code taken +;;; from the stack. ;;; defword sys_exit, 0 dq $ + 8 mov.qreg.qimm rax, 60 ; syscall number - mov.qreg.qimm rdi, 0 ; exit code + pop.qreg rdi ; exit code syscall ; In the event we're still here, let's minimize confusion. @@ -2988,6 +3035,14 @@ defword sys_write, 0 next +;;;;;;;;;;;;;;;;;;;;;;;; +;;; I/O conveniences ;;; +;;;;;;;;;;;;;;;;;;;;;;;; + + +defword emitstring, 0 + dq docol, dup, stringlen, swap, sys_write, exit + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;; (new) Implementation strategy ;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |