about summary refs log tree commit diff stats
path: root/subx/066allocate.subx
diff options
context:
space:
mode:
authorKartik Agaram <vc@akkartik.com>2019-01-04 15:37:16 -0800
committerKartik Agaram <vc@akkartik.com>2019-01-04 15:37:16 -0800
commitbc20cc3d4561152e1cef98cccc23488e02979c34 (patch)
tree451618493aef569626b8f20726c77d689f7cbf9e /subx/066allocate.subx
parent7b548ff5c5792422f1cc05896adf2f63f5af41c7 (diff)
downloadmu-bc20cc3d4561152e1cef98cccc23488e02979c34.tar.gz
4906 - helper to allocate streams on the heap
Diffstat (limited to 'subx/066allocate.subx')
-rw-r--r--subx/066allocate.subx49
1 files changed, 49 insertions, 0 deletions
diff --git a/subx/066allocate.subx b/subx/066allocate.subx
index 0e3b54f6..a4ea687c 100644
--- a/subx/066allocate.subx
+++ b/subx/066allocate.subx
@@ -149,4 +149,53 @@ test-allocate-failure:
     5d/pop-to-EBP
     c3/return
 
+# helper: create a nested allocation descriptor (useful for tests)
+allocate-region:  # ad : (address allocation-descriptor), n : int -> new-ad : (address allocation-descriptor)
+    # . prolog
+    55/push-EBP
+    89/copy                         3/mod/direct    5/rm32/EBP    .           .             .           4/r32/ESP   .               .                 # copy ESP to EBP
+    # . save registers
+    51/push-ECX
+    # EAX = allocate(ad, n)
+    # . . push args
+    ff          6/subop/push        1/mod/*+disp8   5/rm32/EBP    .           .             .           .           0xc/disp8       .                 # push *(EBP+12)
+    ff          6/subop/push        1/mod/*+disp8   5/rm32/EBP    .           .             .           .           8/disp8         .                 # push *(EBP+8)
+    # . . call
+    e8/call  allocate/disp32
+    # . . discard args
+    81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               8/imm32           # add to ESP
+    # if EAX == 0 abort
+    81          7/subop/compare     3/mod/direct    0/rm32/EAX    .           .             .           .           .               0/imm32           # compare EAX
+    74/jump-if-equal  $allocate-region:abort/disp8
+    # earmark 8 bytes at the start for a new allocation descriptor
+    # . *EAX = EAX + 8
+    89/copy                         3/mod/direct    1/rm32/ECX    .           .             .           0/r32/EAX   .               .                 # copy EAX to ECX
+    81          0/subop/add         3/mod/direct    1/rm32/ECX    .           .             .           .           .               8/imm32           # add to ECX
+    89/copy                         0/mod/indirect  0/rm32/EAX    .           .             .           1/r32/ECX   .               .                 # copy ECX to *EAX
+    # . *(EAX+4) = EAX + n
+    89/copy                         3/mod/direct    1/rm32/ECX    .           .             .           0/r32/EAX   .               .                 # copy EAX to ECX
+    03/add                          1/mod/*+disp8   5/rm32/EBP    .           .             .           1/r32/ECX   0xc/disp8       .                 # add *(EBP+12) to ECX
+    89/copy                         1/mod/*+disp8   0/rm32/EAX    .           .             .           1/r32/ECX   4/disp8         .                 # copy ECX to *(EAX+4)
+    # . restore registers
+    59/pop-to-ECX
+    # . epilog
+    89/copy                         3/mod/direct    4/rm32/ESP    .           .             .           5/r32/EBP   .               .                 # copy EBP to ESP
+    5d/pop-to-EBP
+    c3/return
+
+$allocate-region:abort:
+    # . _write(2/stderr, error)
+    # . . push args
+    68/push  "allocate-region: failed to allocate"/imm32
+    68/push  2/imm32/stderr
+    # . . call
+    e8/call  _write/disp32
+    # . . discard args
+    81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               8/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
+
 # . . vim:nowrap:textwidth=0