about summary refs log tree commit diff stats
path: root/095stack.subx
diff options
context:
space:
mode:
authorKartik Agaram <vc@akkartik.com>2020-01-14 00:35:44 -0800
committerKartik Agaram <vc@akkartik.com>2020-01-14 01:52:54 -0800
commit51858e5d46ed152fd61178e7014dcb02c6c7c08a (patch)
treef1598c4ea882c9660aa119a89cad10b880225718 /095stack.subx
parent730e6894671c2dbaa37fc7caaa376ccf77b0fc85 (diff)
downloadmu-51858e5d46ed152fd61178e7014dcb02c6c7c08a.tar.gz
5887 - reorganize library
Layers 0-89 are used in self-hosting SubX.
Layers 90-99 are not needed for self-hosting SubX, and therefore could
use transitional levels of syntax sugar.
Layers 100 and up use all SubX syntax sugar.
Diffstat (limited to '095stack.subx')
-rw-r--r--095stack.subx413
1 files changed, 0 insertions, 413 deletions
diff --git a/095stack.subx b/095stack.subx
deleted file mode 100644
index fdc4fa95..00000000
--- a/095stack.subx
+++ /dev/null
@@ -1,413 +0,0 @@
-# A stack looks like this:
-#   top: int
-#   data: (array byte)  # prefixed by length as usual
-
-== code
-#   instruction                     effective address                                                   register    displacement    immediate
-# . op          subop               mod             rm32          base        index         scale       r32
-# . 1-3 bytes   3 bits              2 bits          3 bits        3 bits      3 bits        2 bits      2 bits      0/1/2/4 bytes   0/1/2/4 bytes
-
-clear-stack:  # s : (addr stack)
-    # . prologue
-    55/push-ebp
-    89/copy                         3/mod/direct    5/rm32/ebp    .           .             .           4/r32/esp   .               .                 # copy esp to ebp
-    # . save registers
-    50/push-eax
-    51/push-ecx
-    # eax = s
-    8b/copy                         1/mod/*+disp8   5/rm32/ebp    .           .             .           0/r32/eax   8/disp8         .                 # copy *(ebp+8) to eax
-    # var max/ecx : (addr byte) = &s->data[s->length]
-    8b/copy                         1/mod/*+disp8   0/rm32/eax    .           .             .           1/r32/ecx   4/disp8         .                 # copy *(eax+4) to eax
-    8d/copy-address                 1/mod/*+disp8   4/rm32/sib    0/base/eax  1/index/ecx   .           1/r32/ecx   8/disp8         .                 # copy eax+ecx+8 to ecx
-    # s->top = 0
-    c7          0/subop/copy        0/mod/direct    0/rm32/eax    .           .             .           .           .               0/imm32           # copy to *eax
-    # var curr/eax : (addr byte) = s->data
-    81          0/subop/add         3/mod/direct    0/rm32/eax    .           .             .           .           .               8/imm32           # add to eax
-$clear-stack:loop:
-    # if (curr >= max) break
-    39/compare                      3/mod/direct    0/rm32/eax    .           .             .           1/r32/ecx   .               .                 # compare eax with ecx
-    73/jump-if-greater-or-equal-unsigned  $clear-stack:end/disp8
-    # *curr = 0
-    c6          0/subop/copy        0/mod/direct    0/rm32/eax    .           .             .           .           .               0/imm8            # copy byte to *eax
-    # ++curr
-    40/increment-eax
-    eb/jump $clear-stack:loop/disp8
-$clear-stack:end:
-    # . restore registers
-    59/pop-to-ecx
-    58/pop-to-eax
-    # . epilogue
-    89/copy                         3/mod/direct    4/rm32/esp    .           .             .           5/r32/ebp   .               .                 # copy ebp to esp
-    5d/pop-to-ebp
-    c3/return
-
-test-clear-stack:
-    # . prologue
-    55/push-ebp
-    89/copy                         3/mod/direct    5/rm32/ebp    .           .             .           4/r32/esp   .               .                 # copy esp to ebp
-    # var stack/ecx = stack of size 8 with random data in it
-    68/push 34/imm32
-    68/push 35/imm32
-    68/push 8/imm32/length
-    68/push 14/imm32/top
-    89/copy                         3/mod/direct    1/rm32/ecx    .           .             .           4/r32/esp   .               .                 # copy esp to ecx
-    # clear(stack)
-    # . . push args
-    51/push-ecx
-    # . . call
-    e8/call  clear-stack/disp32
-    # . . discard args
-    81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               4/imm32           # add to esp
-    # top should be 0
-    58/pop-to-eax
-    # . check-ints-equal(eax, 0, msg)
-    # . . push args
-    68/push  "F - test-clear-stack: top"/imm32
-    68/push  0/imm32
-    50/push-eax
-    # . . call
-    e8/call  check-ints-equal/disp32
-    # . . discard args
-    81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               0xc/imm32         # add to esp
-    # length should remain 8
-    58/pop-to-eax
-    # . check-ints-equal(eax, 8, msg)
-    # . . push args
-    68/push  "F - test-clear-stack: length"/imm32
-    68/push  8/imm32
-    50/push-eax
-    # . . call
-    e8/call  check-ints-equal/disp32
-    # . . discard args
-    81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               0xc/imm32         # add to esp
-    # first word is 0
-    58/pop-to-eax
-    # . check-ints-equal(eax, 0, msg)
-    # . . push args
-    68/push  "F - test-clear-stack: data[0..3]"/imm32
-    68/push  0/imm32
-    50/push-eax
-    # . . call
-    e8/call  check-ints-equal/disp32
-    # . . discard args
-    81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               0xc/imm32         # add to esp
-    # second word is 0
-    58/pop-to-eax
-    # . check-ints-equal(eax, 0, msg)
-    # . . push args
-    68/push  "F - test-clear-stack: data[4..7]"/imm32
-    68/push  0/imm32
-    50/push-eax
-    # . . call
-    e8/call  check-ints-equal/disp32
-    # . . discard args
-    81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               0xc/imm32         # add to esp
-    # . epilogue
-    89/copy                         3/mod/direct    4/rm32/esp    .           .             .           5/r32/ebp   .               .                 # copy ebp to esp
-    5d/pop-to-ebp
-    c3/return
-
-push:  # s : (addr stack), n : int
-    # . prologue
-    55/push-ebp
-    89/copy                         3/mod/direct    5/rm32/ebp    .           .             .           4/r32/esp   .               .                 # copy esp to ebp
-    # . save registers
-    50/push-eax
-    51/push-ecx
-    56/push-esi
-    # esi = s
-    8b/copy                         1/mod/*+disp8   5/rm32/ebp    .           .             .           6/r32/esi   8/disp8         .                 # copy *(ebp+8) to esi
-    # ecx = s->top
-    8b/copy                         0/mod/indirect  6/rm32/esi    .           .             .           1/r32/ecx   .               .                 # copy *esi to ecx
-    # if (s->top >= s->length) abort
-    39/compare                      1/mod/*+disp8   6/rm32/esi    .           .             .           1/r32/ecx   4/disp8         .                 # compare *(esi+4) and ecx
-    7e/jump-if-lesser-or-equal  $push:abort/disp8
-    # s->data[s->top] = n
-    8b/copy                         1/mod/*+disp8   5/rm32/ebp    .           .             .           0/r32/eax   0xc/disp8       .                 # copy *(ebp+12) to eax
-    89/copy                         1/mod/*+disp8   4/rm32/sib    6/base/esi  1/index/ecx   .           0/r32/eax   8/disp8         .                 # copy eax to *(esi+ecx+8)
-    # s->top += 4
-    81          0/subop/add         0/mod/direct    6/rm32/esi    .           .             .           .           .               4/imm32           # subtract from *esi
-$push:end:
-    # . restore registers
-    5e/pop-to-esi
-    59/pop-to-ecx
-    58/pop-to-eax
-    # . epilogue
-    89/copy                         3/mod/direct    4/rm32/esp    .           .             .           5/r32/ebp   .               .                 # copy ebp to esp
-    5d/pop-to-ebp
-    c3/return
-
-$push:abort:
-    # print(stderr, "error: push: no space left")
-    # . write-buffered(Stderr, "error: push: no space left")
-    # . . push args
-    68/push  "error: push: no space left"/imm32
-    68/push  Stderr/imm32
-    # . . call
-    e8/call  write-buffered/disp32
-    # . . discard args
-    81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               8/imm32           # add to esp
-    # . flush(Stderr)
-    # . . push args
-    68/push  Stderr/imm32
-    # . . call
-    e8/call  flush/disp32
-    # . . discard args
-    81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               4/imm32           # add to esp
-    # . syscall(exit, 1)
-    bb/copy-to-ebx  1/imm32
-    b8/copy-to-eax  1/imm32/exit
-    cd/syscall  0x80/imm8
-    # never gets here
-
-test-push:
-    # . prologue
-    55/push-ebp
-    89/copy                         3/mod/direct    5/rm32/ebp    .           .             .           4/r32/esp   .               .                 # copy esp to ebp
-    # var stack/ecx = empty stack of size 8
-    68/push 0/imm32
-    68/push 0/imm32
-    68/push 8/imm32/length
-    68/push 0/imm32/top
-    89/copy                         3/mod/direct    1/rm32/ecx    .           .             .           4/r32/esp   .               .                 # copy esp to ecx
-    # push(stack, 0x42)
-    # . . push args
-    68/push  0x42/imm32
-    51/push-ecx
-    # . . call
-    e8/call  push/disp32
-    # . . discard args
-    81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               8/imm32           # add to esp
-    # check top
-    58/pop-to-eax
-    # . check-ints-equal(eax, 4, msg)
-    # . . push args
-    68/push  "F - test-push: top"/imm32
-    68/push  4/imm32
-    50/push-eax
-    # . . call
-    e8/call  check-ints-equal/disp32
-    # . . discard args
-    81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               0xc/imm32         # add to esp
-    # check length
-    58/pop-to-eax
-    # . check-ints-equal(eax, 8, msg)
-    # . . push args
-    68/push  "F - test-push: length"/imm32
-    68/push  8/imm32
-    50/push-eax
-    # . . call
-    e8/call  check-ints-equal/disp32
-    # . . discard args
-    81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               0xc/imm32         # add to esp
-    # first word is 0x42
-    58/pop-to-eax
-    # . check-ints-equal(eax, 0x42, msg)
-    # . . push args
-    68/push  "F - test-push: data[0..3]"/imm32
-    68/push  0x42/imm32
-    50/push-eax
-    # . . call
-    e8/call  check-ints-equal/disp32
-    # . . discard args
-    81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               0xc/imm32         # add to esp
-    # second word is 0
-    58/pop-to-eax
-    # . check-ints-equal(eax, 0, msg)
-    # . . push args
-    68/push  "F - test-push: data[4..7]"/imm32
-    68/push  0/imm32
-    50/push-eax
-    # . . call
-    e8/call  check-ints-equal/disp32
-    # . . discard args
-    81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               0xc/imm32         # add to esp
-    # . epilogue
-    89/copy                         3/mod/direct    4/rm32/esp    .           .             .           5/r32/ebp   .               .                 # copy ebp to esp
-    5d/pop-to-ebp
-    c3/return
-
-pop:  # s : (addr stack) -> n/eax : int
-    # . prologue
-    55/push-ebp
-    89/copy                         3/mod/direct    5/rm32/ebp    .           .             .           4/r32/esp   .               .                 # copy esp to ebp
-    # . save registers
-    51/push-ecx
-    56/push-esi
-    # esi = s
-    8b/copy                         1/mod/*+disp8   5/rm32/ebp    .           .             .           6/r32/esi   8/disp8         .                 # copy *(ebp+8) to esi
-    # if (s->top <= 0) abort
-    81          7/subop/compare     0/mod/indirect  6/rm32/esi    .           .             .           .           .               0/imm32           # compare *esi
-    7e/jump-if-lesser-or-equal  $pop:abort/disp8
-    # s->top -= 4
-    81          5/subop/subtract    0/mod/direct    6/rm32/esi    .           .             .           .           .               4/imm32           # subtract from *esi
-    # eax = s->data[s->top]
-    8b/copy                         0/mod/indirect  6/rm32/esi    .           .             .           1/r32/ecx   .               .                 # copy *esi to ecx
-    8b/copy                         1/mod/*+disp8   4/rm32/sib    6/base/esi  1/index/ecx   .           0/r32/eax   8/disp8         .                 # copy *(esi+ecx+8) to eax
-    # s->data[s->top] = 0
-    c7          0/subop/copy        1/mod/*+disp8   4/rm32/sib    6/base/esi  1/index/ecx   .           0/r32/eax   8/disp8         0/imm32           # copy to *(esi+ecx+8)
-$pop:end:
-    # . restore registers
-    5e/pop-to-esi
-    59/pop-to-ecx
-    # . epilogue
-    89/copy                         3/mod/direct    4/rm32/esp    .           .             .           5/r32/ebp   .               .                 # copy ebp to esp
-    5d/pop-to-ebp
-    c3/return
-
-$pop:abort:
-    # print(stderr, "error: pop: nothing left in stack")
-    # . write-buffered(Stderr, "error: pop: nothing left in stack")
-    # . . push args
-    68/push  "error: pop: nothing left in stack"/imm32
-    68/push  Stderr/imm32
-    # . . call
-    e8/call  write-buffered/disp32
-    # . . discard args
-    81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               8/imm32           # add to esp
-    # . flush(Stderr)
-    # . . push args
-    68/push  Stderr/imm32
-    # . . call
-    e8/call  flush/disp32
-    # . . discard args
-    81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               4/imm32           # add to esp
-    # . syscall(exit, 1)
-    bb/copy-to-ebx  1/imm32
-    b8/copy-to-eax  1/imm32/exit
-    cd/syscall  0x80/imm8
-    # never gets here
-
-test-pop:
-    # . prologue
-    55/push-ebp
-    89/copy                         3/mod/direct    5/rm32/ebp    .           .             .           4/r32/esp   .               .                 # copy esp to ebp
-    # var stack/ecx = stack of size 8 containing just 0x42
-    68/push 0/imm32
-    68/push 0x42/imm32
-    68/push 8/imm32/length
-    68/push 4/imm32/top
-    89/copy                         3/mod/direct    1/rm32/ecx    .           .             .           4/r32/esp   .               .                 # copy esp to ecx
-    # eax = pop(stack)
-    # . . push args
-    51/push-ecx
-    # . . call
-    e8/call  pop/disp32
-    # . . discard args
-    81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               4/imm32           # add to esp
-    # check-ints-equal(eax, 0x42, msg)
-    # . . push args
-    68/push  "F - test-pop: result"/imm32
-    68/push  0x42/imm32
-    50/push-eax
-    # . . call
-    e8/call  check-ints-equal/disp32
-    # . . discard args
-    81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               0xc/imm32         # add to esp
-    # check top
-    58/pop-to-eax
-    # . check-ints-equal(eax, 0, msg)
-    # . . push args
-    68/push  "F - test-pop: top"/imm32
-    68/push  0/imm32
-    50/push-eax
-    # . . call
-    e8/call  check-ints-equal/disp32
-    # . . discard args
-    81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               0xc/imm32         # add to esp
-    # check length
-    58/pop-to-eax
-    # . check-ints-equal(eax, 8, msg)
-    # . . push args
-    68/push  "F - test-pop: length"/imm32
-    68/push  8/imm32
-    50/push-eax
-    # . . call
-    e8/call  check-ints-equal/disp32
-    # . . discard args
-    81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               0xc/imm32         # add to esp
-    # . epilogue
-    89/copy                         3/mod/direct    4/rm32/esp    .           .             .           5/r32/ebp   .               .                 # copy ebp to esp
-    5d/pop-to-ebp
-    c3/return
-
-top:  # s : (addr stack) -> n/eax : int
-    # . prologue
-    55/push-ebp
-    89/copy                         3/mod/direct    5/rm32/ebp    .           .             .           4/r32/esp   .               .                 # copy esp to ebp
-    # . save registers
-    51/push-ecx
-    56/push-esi
-    # esi = s
-    8b/copy                         1/mod/*+disp8   5/rm32/ebp    .           .             .           6/r32/esi   8/disp8         .                 # copy *(ebp+8) to esi
-    # if (s->top <= 0) abort
-    81          7/subop/compare     0/mod/indirect  6/rm32/esi    .           .             .           .           .               0/imm32           # compare *esi
-    7e/jump-if-lesser-or-equal  $top:abort/disp8
-    # n = s->data[s->top - 4]
-    8b/copy                         0/mod/indirect  6/rm32/esi    .           .             .           1/r32/ecx   .               .                 # copy *esi to ecx
-    81          5/subop/subtract    3/mod/direct    1/rm32/ecx    .           .             .           .           .               4/imm32           # subtract from ecx
-    8b/copy                         1/mod/*+disp8   4/rm32/sib    6/base/esi  1/index/ecx   .           0/r32/eax   8/disp8         .                 # copy *(esi+ecx+8) to eax
-$top:end:
-    # . restore registers
-    5e/pop-to-esi
-    59/pop-to-ecx
-    # . epilogue
-    89/copy                         3/mod/direct    4/rm32/esp    .           .             .           5/r32/ebp   .               .                 # copy ebp to esp
-    5d/pop-to-ebp
-    c3/return
-
-$top:abort:
-    # print(stderr, "error: top: nothing left in stack")
-    # . write-buffered(Stderr, "error: top: nothing left in stack")
-    # . . push args
-    68/push  "error: top: nothing left in stack"/imm32
-    68/push  Stderr/imm32
-    # . . call
-    e8/call  write-buffered/disp32
-    # . . discard args
-    81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               8/imm32           # add to esp
-    # . flush(Stderr)
-    # . . push args
-    68/push  Stderr/imm32
-    # . . call
-    e8/call  flush/disp32
-    # . . discard args
-    81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               4/imm32           # add to esp
-    # . syscall(exit, 1)
-    bb/copy-to-ebx  1/imm32
-    b8/copy-to-eax  1/imm32/exit
-    cd/syscall  0x80/imm8
-    # never gets here
-
-test-top:
-    # . prologue
-    55/push-ebp
-    89/copy                         3/mod/direct    5/rm32/ebp    .           .             .           4/r32/esp   .               .                 # copy esp to ebp
-    # var stack/ecx = stack of size 8 containing just 0x42
-    68/push  0/imm32
-    68/push  0x42/imm32
-    68/push  8/imm32/length
-    68/push  4/imm32/top
-    89/copy                         3/mod/direct    1/rm32/ecx    .           .             .           4/r32/esp   .               .                 # copy esp to ecx
-    # eax = top(stack)
-    # . . push args
-    51/push-ecx
-    # . . call
-    e8/call  top/disp32
-    # . . discard args
-    81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               4/imm32           # add to esp
-    # check-ints-equal(eax, 42, msg")
-    # . . push args
-    68/push  "F - test-top: result"/imm32
-    68/push  0x42/imm32
-    50/push-eax
-    # . . call
-    e8/call  check-ints-equal/disp32
-    # . . discard args
-    81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               0xc/imm32         # add to esp
-    # . epilogue
-    89/copy                         3/mod/direct    4/rm32/esp    .           .             .           5/r32/ebp   .               .                 # copy ebp to esp
-    5d/pop-to-ebp
-    c3/return
-
-# . . vim:nowrap:textwidth=0