From fbc21293299f1d5b2d108e3ee98ea4e9083965b5 Mon Sep 17 00:00:00 2001 From: Kartik Agaram Date: Thu, 9 May 2019 09:25:01 -0700 Subject: 5148 Snapshot of incomplete work to have the memory allocator use `mmap` rather than `brk`. C tests pass, but the SubX layers are still broken. --- subx/012elf.cc | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) (limited to 'subx/012elf.cc') diff --git a/subx/012elf.cc b/subx/012elf.cc index 0f058504..6a31826e 100644 --- a/subx/012elf.cc +++ b/subx/012elf.cc @@ -129,15 +129,13 @@ void load_segment_from_program_header(uint8_t* elf_contents, int segment_index, } :(before "End Includes") -// Very primitive/fixed/insecure ELF segments for now: just consecutive VMAs. -// code: 0x09000000 -> 0x09ffffff -// data/heap: 0x0a000000 -> 0x0affffff -// stack: 0x0b000ffc -> 0x0b000000 (downward) -const int CODE_SEGMENT = 0x09000000; -const int DATA_SEGMENT = 0x0a000000; // keep sync'd with `Heap.limit` in allocate.subx -const int STACK_SEGMENT = 0x0b000000; -const int AFTER_STACK = 0x0c000000; -const int ARGV_DATA_SEGMENT = 0x0c000000; +// Very primitive/fixed/insecure ELF segments for now. +// code: 0x09000000 -> 0x09ffffff +// stack: 0xbe000000 -> 0xb0000000 (downward) +const int CODE_SEGMENT = 0x09000000; +const int STACK_SEGMENT = 0xb0000000; +const int AFTER_STACK = 0xbe000000; +const int ARGV_DATA_SEGMENT = 0xbf000000; :(before "End Dump Info for Instruction") //? dump_stack(); // slow :(code) -- cgit 1.4.1-2-gfad0 From a1305217980a75ed5534daa7016a83f2d5602b43 Mon Sep 17 00:00:00 2001 From: Kartik Agaram Date: Fri, 10 May 2019 10:24:24 -0700 Subject: 5149 Tests still broken. --- subx/012elf.cc | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) (limited to 'subx/012elf.cc') diff --git a/subx/012elf.cc b/subx/012elf.cc index 6a31826e..11e0e4bc 100644 --- a/subx/012elf.cc +++ b/subx/012elf.cc @@ -66,6 +66,7 @@ void load_elf_contents(uint8_t* elf_contents, size_t size, int argc, char* argv[ assert(overlap.find(STACK_SEGMENT) == overlap.end()); Mem.push_back(vma(STACK_SEGMENT)); assert(overlap.find(AFTER_STACK) == overlap.end()); + // The stack grows downward. Reg[ESP].u = AFTER_STACK; Reg[EBP].u = 0; EIP = e_entry; @@ -130,10 +131,14 @@ void load_segment_from_program_header(uint8_t* elf_contents, int segment_index, :(before "End Includes") // Very primitive/fixed/insecure ELF segments for now. -// code: 0x09000000 -> 0x09ffffff -// stack: 0xbe000000 -> 0xb0000000 (downward) +// code: 0x09000000 -> 0x09ffffff (specified in ELF binary) +// data: 0x0a000000 -> 0x0affffff (specified in ELF binary) +// --- heap gets mmap'd somewhere here --- +// stack: 0xbdffffff -> 0xbd000000 (downward; not in ELF binary) +// argv hack: 0xbf000000 -> 0xc0000000 (not in ELF binary) const int CODE_SEGMENT = 0x09000000; -const int STACK_SEGMENT = 0xb0000000; +const int DATA_SEGMENT = 0x0a000000; +const int STACK_SEGMENT = 0xbd000000; const int AFTER_STACK = 0xbe000000; const int ARGV_DATA_SEGMENT = 0xbf000000; :(before "End Dump Info for Instruction") -- cgit 1.4.1-2-gfad0 From c88b9e31259d433c7e63fcb19d430daf9b1c723c Mon Sep 17 00:00:00 2001 From: Kartik Agaram Date: Fri, 10 May 2019 16:45:22 -0700 Subject: 5151 - use mmap everywhere we need a heap All tests passing now. Things are very explicit; before a program can `allocate` memory, it has to first obtain a segment from the OS using `new-segment`. --- subx/012elf.cc | 17 +++++++---- subx/020syscalls.cc | 21 ++++++++------ subx/070new-stream.subx | 15 +++++----- subx/072slice.subx | 16 +++++++++-- subx/apps/assort | Bin 21414 -> 21492 bytes subx/apps/assort.subx | 24 ++++++++++++++++ subx/apps/crenshaw2-1 | Bin 18602 -> 18651 bytes subx/apps/crenshaw2-1b | Bin 19161 -> 19210 bytes subx/apps/dquotes | Bin 20916 -> 21106 bytes subx/apps/dquotes.subx | 24 ++++++++++++++++ subx/apps/factorial | Bin 17518 -> 17567 bytes subx/apps/handle | Bin 18292 -> 18394 bytes subx/apps/handle.subx | 74 +++++++++++++++++++++++++++++++++--------------- subx/apps/hex | Bin 21611 -> 21660 bytes subx/apps/pack | Bin 36203 -> 36252 bytes 15 files changed, 146 insertions(+), 45 deletions(-) (limited to 'subx/012elf.cc') diff --git a/subx/012elf.cc b/subx/012elf.cc index 11e0e4bc..d0a3fbd2 100644 --- a/subx/012elf.cc +++ b/subx/012elf.cc @@ -134,13 +134,20 @@ void load_segment_from_program_header(uint8_t* elf_contents, int segment_index, // code: 0x09000000 -> 0x09ffffff (specified in ELF binary) // data: 0x0a000000 -> 0x0affffff (specified in ELF binary) // --- heap gets mmap'd somewhere here --- -// stack: 0xbdffffff -> 0xbd000000 (downward; not in ELF binary) -// argv hack: 0xbf000000 -> 0xc0000000 (not in ELF binary) +// stack: 0x7dffffff -> 0x7d000000 (downward; not in ELF binary) +// argv hack: 0x7f000000 -> 0x7fffffff (not in ELF binary) +// +// For now we avoid addresses with the most significant bit set; SubX doesn't +// support unsigned comparison yet (https://github.com/akkartik/mu/issues/30) +// Once we do, we can go up to 0xc0000000; higher addresses are reserved for +// the Linux kernel. const int CODE_SEGMENT = 0x09000000; const int DATA_SEGMENT = 0x0a000000; -const int STACK_SEGMENT = 0xbd000000; -const int AFTER_STACK = 0xbe000000; -const int ARGV_DATA_SEGMENT = 0xbf000000; +const int STACK_SEGMENT = 0x7d000000; +const int AFTER_STACK = 0x7e000000; +const int ARGV_DATA_SEGMENT = 0x7f000000; +// When updating the above memory map, don't forget to update `mmap`'s +// implementation in the 'syscalls' layer. :(before "End Dump Info for Instruction") //? dump_stack(); // slow :(code) diff --git a/subx/020syscalls.cc b/subx/020syscalls.cc index a17e9525..6b9faa2c 100644 --- a/subx/020syscalls.cc +++ b/subx/020syscalls.cc @@ -24,14 +24,14 @@ void process_int80() { trace(Callstack_depth+1, "run") << "read: " << Reg[EBX].u << ' ' << Reg[ECX].u << ' ' << Reg[EDX].u << end(); Reg[EAX].i = read(/*file descriptor*/Reg[EBX].u, /*memory buffer*/mem_addr_u8(Reg[ECX].u), /*size*/Reg[EDX].u); trace(Callstack_depth+1, "run") << "result: " << Reg[EAX].i << end(); - if (Reg[EAX].i == -1) raise << strerror(errno) << '\n' << end(); + if (Reg[EAX].i == -1) raise << "read: " << strerror(errno) << '\n' << end(); break; case 4: trace(Callstack_depth+1, "run") << "write: " << Reg[EBX].u << ' ' << Reg[ECX].u << ' ' << Reg[EDX].u << end(); trace(Callstack_depth+1, "run") << Reg[ECX].u << " => " << mem_addr_string(Reg[ECX].u, Reg[EDX].u) << end(); Reg[EAX].i = write(/*file descriptor*/Reg[EBX].u, /*memory buffer*/mem_addr_u8(Reg[ECX].u), /*size*/Reg[EDX].u); trace(Callstack_depth+1, "run") << "result: " << Reg[EAX].i << end(); - if (Reg[EAX].i == -1) raise << strerror(errno) << '\n' << end(); + if (Reg[EAX].i == -1) raise << "write: " << strerror(errno) << '\n' << end(); break; case 5: { check_flags(ECX); @@ -40,14 +40,14 @@ void process_int80() { trace(Callstack_depth+1, "run") << Reg[EBX].u << " => " << mem_addr_kernel_string(Reg[EBX].u) << end(); Reg[EAX].i = open(/*filename*/mem_addr_kernel_string(Reg[EBX].u), /*flags*/Reg[ECX].u, /*mode*/0640); trace(Callstack_depth+1, "run") << "result: " << Reg[EAX].i << end(); - if (Reg[EAX].i == -1) raise << strerror(errno) << '\n' << end(); + if (Reg[EAX].i == -1) raise << "open: " << strerror(errno) << '\n' << end(); break; } case 6: trace(Callstack_depth+1, "run") << "close: " << Reg[EBX].u << end(); Reg[EAX].i = close(/*file descriptor*/Reg[EBX].u); trace(Callstack_depth+1, "run") << "result: " << Reg[EAX].i << end(); - if (Reg[EAX].i == -1) raise << strerror(errno) << '\n' << end(); + if (Reg[EAX].i == -1) raise << "close: " << strerror(errno) << '\n' << end(); break; case 8: check_mode(ECX); @@ -55,14 +55,14 @@ void process_int80() { trace(Callstack_depth+1, "run") << Reg[EBX].u << " => " << mem_addr_kernel_string(Reg[EBX].u) << end(); Reg[EAX].i = creat(/*filename*/mem_addr_kernel_string(Reg[EBX].u), /*mode*/0640); trace(Callstack_depth+1, "run") << "result: " << Reg[EAX].i << end(); - if (Reg[EAX].i == -1) raise << strerror(errno) << '\n' << end(); + if (Reg[EAX].i == -1) raise << "creat: " << strerror(errno) << '\n' << end(); break; case 10: trace(Callstack_depth+1, "run") << "unlink: " << Reg[EBX].u << end(); trace(Callstack_depth+1, "run") << Reg[EBX].u << " => " << mem_addr_kernel_string(Reg[EBX].u) << end(); Reg[EAX].i = unlink(/*filename*/mem_addr_kernel_string(Reg[EBX].u)); trace(Callstack_depth+1, "run") << "result: " << Reg[EAX].i << end(); - if (Reg[EAX].i == -1) raise << strerror(errno) << '\n' << end(); + if (Reg[EAX].i == -1) raise << "unlink: " << strerror(errno) << '\n' << end(); break; case 38: trace(Callstack_depth+1, "run") << "rename: " << Reg[EBX].u << " -> " << Reg[ECX].u << end(); @@ -70,7 +70,7 @@ void process_int80() { trace(Callstack_depth+1, "run") << Reg[ECX].u << " => " << mem_addr_kernel_string(Reg[ECX].u) << end(); Reg[EAX].i = rename(/*old filename*/mem_addr_kernel_string(Reg[EBX].u), /*new filename*/mem_addr_kernel_string(Reg[ECX].u)); trace(Callstack_depth+1, "run") << "result: " << Reg[EAX].i << end(); - if (Reg[EAX].i == -1) raise << strerror(errno) << '\n' << end(); + if (Reg[EAX].i == -1) raise << "rename: " << strerror(errno) << '\n' << end(); break; case 45: // brk: modify size of data segment trace(Callstack_depth+1, "run") << "grow data segment to " << Reg[EBX].u << end(); @@ -110,7 +110,12 @@ void check_mode(int reg) { } :(before "End Globals") -uint32_t Next_segment = 0xb0000000; // 0xc0000000 and up is reserved for Linux kernel +// Very primitive/fixed/insecure mmap segments for now. +// For now we avoid addresses with the most significant bit set; SubX doesn't +// support unsigned comparison yet (https://github.com/akkartik/mu/issues/30) +// Once we do, we can go up to 0xc0000000; higher addresses are reserved for +// the Linux kernel. +uint32_t Next_segment = 0x7c000000; const uint32_t SPACE_FOR_SEGMENT = 0x01000000; :(code) uint32_t new_segment(uint32_t length) { diff --git a/subx/070new-stream.subx b/subx/070new-stream.subx index ad6ab68d..8a833581 100644 --- a/subx/070new-stream.subx +++ b/subx/070new-stream.subx @@ -68,20 +68,21 @@ test-new-stream: # . prolog 55/push-EBP 89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP - # var ad/ECX : (address allocation-descriptor) = allocate-region(Heap, 512) - # . EAX = allocate-region(Heap, 512) + # var heap/ECX : (address allocation-descriptor) = {0, 0} + 68/push 0/imm32/limit + 68/push 0/imm32/curr + 89/copy 3/mod/direct 1/rm32/ECX . . . 4/r32/ESP . . # copy ESP to ECX + # heap = new-segment(512) # . . push args + 51/push-ECX 68/push 0x200/imm32 - 68/push Heap/imm32 # . . call - e8/call allocate-region/disp32 + e8/call new-segment/disp32 # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP - # . ECX = EAX - 89/copy 3/mod/direct 1/rm32/ECX . . . 0/r32/EAX . . # copy EAX to ECX # var start/EDX = ad->curr 8b/copy 0/mod/indirect 1/rm32/ECX . . . 2/r32/EDX . . # copy *ECX to EDX - # EAX = new-stream(ad, 3, 2) + # EAX = new-stream(heap, 3, 2) # . . push args 68/push 2/imm32 68/push 3/imm32 diff --git a/subx/072slice.subx b/subx/072slice.subx index 9c285097..683c4c7b 100644 --- a/subx/072slice.subx +++ b/subx/072slice.subx @@ -917,14 +917,26 @@ test-slice-to-string: # . prolog 55/push-EBP 89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP + # var heap/EDX : (address allocation-descriptor) = {0, 0} + 68/push 0/imm32/limit + 68/push 0/imm32/curr + 89/copy 3/mod/direct 2/rm32/EDX . . . 4/r32/ESP . . # copy ESP to EDX + # heap = new-segment(512) + # . . push args + 52/push-EDX + 68/push 0x200/imm32 + # . . call + e8/call new-segment/disp32 + # . . discard args + 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP # var slice/ECX = "Abc" 68/push _test-slice-data-3/imm32/end 68/push _test-slice-data-0/imm32/start 89/copy 3/mod/direct 1/rm32/ECX . . . 4/r32/ESP . . # copy ESP to ECX - # EAX = slice-to-string(Heap, slice) + # EAX = slice-to-string(heap, slice) # . . push args 51/push-ECX - 68/push Heap/imm32 + 52/push-EDX # . . call e8/call slice-to-string/disp32 # . . discard args diff --git a/subx/apps/assort b/subx/apps/assort index a0e89c63..e331ce8a 100755 Binary files a/subx/apps/assort and b/subx/apps/assort differ diff --git a/subx/apps/assort.subx b/subx/apps/assort.subx index ecb1c213..cfdef5e1 100644 --- a/subx/apps/assort.subx +++ b/subx/apps/assort.subx @@ -26,12 +26,30 @@ Entry: # run tests if necessary, convert stdin if not # for debugging: run a single test +#? # . Heap = new-segment(4096) +#? # . . push args +#? 68/push Heap/imm32 +#? 68/push 0x1000/imm32 +#? # . . call +#? e8/call new-segment/disp32 +#? # . . discard args +#? 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP +#? # . test() #? e8/call test-convert/disp32 #? 8b/copy 0/mod/indirect 5/rm32/.disp32 . . 3/r32/EBX Num-test-failures/disp32 # copy *Num-test-failures to EBX #? eb/jump $main:end/disp8 # . prolog 89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP + # initialize heap + # . Heap = new-segment(4096) + # . . push args + 68/push Heap/imm32 + 68/push 0x1000/imm32 + # . . call + e8/call new-segment/disp32 + # . . discard args + 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP # - if argc > 1 and argv[1] == "test", then return run_tests() # . argc > 1 81 7/subop/compare 1/mod/*+disp8 5/rm32/EBP . . . . 0/disp8 1/imm32 # compare *EBP @@ -1316,4 +1334,10 @@ Segment-size: 0x100/imm32 #? 0x1000/imm32/4KB +Heap: + # curr + 0/imm32 + # limit + 0/imm32 + # . . vim:nowrap:textwidth=0 diff --git a/subx/apps/crenshaw2-1 b/subx/apps/crenshaw2-1 index 9e07eb8d..eb187bb3 100755 Binary files a/subx/apps/crenshaw2-1 and b/subx/apps/crenshaw2-1 differ diff --git a/subx/apps/crenshaw2-1b b/subx/apps/crenshaw2-1b index 173ea621..e8d72937 100755 Binary files a/subx/apps/crenshaw2-1b and b/subx/apps/crenshaw2-1b differ diff --git a/subx/apps/dquotes b/subx/apps/dquotes index e1d12550..b63744d1 100644 Binary files a/subx/apps/dquotes and b/subx/apps/dquotes differ diff --git a/subx/apps/dquotes.subx b/subx/apps/dquotes.subx index b236ac2f..fcac2698 100644 --- a/subx/apps/dquotes.subx +++ b/subx/apps/dquotes.subx @@ -22,12 +22,30 @@ Entry: # run tests if necessary, convert stdin if not # for debugging: run a single test +#? # . Heap = new-segment(4096) +#? # . . push args +#? 68/push Heap/imm32 +#? 68/push 0x1000/imm32 +#? # . . call +#? e8/call new-segment/disp32 +#? # . . discard args +#? 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP +#? # . test() #? e8/call test-next-word-returns-string-with-escapes/disp32 #? 8b/copy 0/mod/indirect 5/rm32/.disp32 . . 3/r32/EBX Num-test-failures/disp32 # copy *Num-test-failures to EBX #? eb/jump $main:end/disp8 # . prolog 89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP + # initialize heap + # . Heap = new-segment(4096) + # . . push args + 68/push Heap/imm32 + 68/push 0x1000/imm32 + # . . call + e8/call new-segment/disp32 + # . . discard args + 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP # - if argc > 1 and argv[1] == "test", then return run_tests() # . argc > 1 81 7/subop/compare 1/mod/*+disp8 5/rm32/EBP . . . . 0/disp8 1/imm32 # compare *EBP @@ -1054,4 +1072,10 @@ Segment-size: Next-string-literal: # tracks the next auto-generated variable name 1/imm32 +Heap: + # curr + 0/imm32 + # limit + 0/imm32 + # . . vim:nowrap:textwidth=0 diff --git a/subx/apps/factorial b/subx/apps/factorial index 8313b27a..2c47ab8a 100755 Binary files a/subx/apps/factorial and b/subx/apps/factorial differ diff --git a/subx/apps/handle b/subx/apps/handle index fa345498..274677fe 100755 Binary files a/subx/apps/handle and b/subx/apps/handle differ diff --git a/subx/apps/handle.subx b/subx/apps/handle.subx index f866ea59..0ed12067 100644 --- a/subx/apps/handle.subx +++ b/subx/apps/handle.subx @@ -79,17 +79,29 @@ test-new: # . prolog 55/push-EBP 89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP + # var heap/EDX : (address allocation-descriptor) = {0, 0} + 68/push 0/imm32/limit + 68/push 0/imm32/curr + 89/copy 3/mod/direct 2/rm32/EDX . . . 4/r32/ESP . . # copy ESP to EDX + # heap = new-segment(512) + # . . push args + 52/push-EDX + 68/push 0x200/imm32 + # . . call + e8/call new-segment/disp32 + # . . discard args + 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP # *Next-alloc-id = 0x34 c7 0/subop/copy 0/mod/indirect 5/rm32/.disp32 . . . Next-alloc-id/disp32 0x34/imm32 # copy to *Next-alloc-id # var handle/ECX = {0, 0} 68/push 0/imm32/address 68/push 0/imm32/alloc-id 89/copy 3/mod/direct 1/rm32/ECX . . . 4/r32/ESP . . # copy ESP to ECX - # new(Heap, 2, handle/ECX) + # new(heap, 2, handle/ECX) # . . push args 51/push-ECX 68/push 2/imm32/size - 68/push Heap/imm32 + 52/push-EDX # . . call e8/call new/disp32 # . . discard args @@ -234,17 +246,29 @@ test-lookup-success: 55/push-EBP 89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP # . save registers + # var heap/EBX : (address allocation-descriptor) = {0, 0} + 68/push 0/imm32/limit + 68/push 0/imm32/curr + 89/copy 3/mod/direct 3/rm32/EBX . . . 4/r32/ESP . . # copy ESP to EBX + # heap = new-segment(512) + # . . push args + 53/push-EBX + 68/push 0x200/imm32 + # . . call + e8/call new-segment/disp32 + # . . discard args + 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP # var handle/ECX = {0, 0} 68/push 0/imm32/address 68/push 0/imm32/alloc-id 89/copy 3/mod/direct 1/rm32/ECX . . . 4/r32/ESP . . # copy ESP to ECX - # var old_top/EDX = Heap->curr - 8b/copy 0/mod/indirect 5/rm32/.disp32 . . 2/r32/EDX Heap/disp32 . # copy *Heap to EDX - # new(Heap, 2, handle) + # var old_top/EDX = heap->curr + 8b/copy 0/mod/indirect 3/rm32/EBX . . . 2/r32/EDX . . # copy *EBX to EDX + # new(heap, 2, handle) # . . push args 51/push-ECX 68/push 2/imm32/size - 68/push Heap/imm32 + 53/push-EBX # . . call e8/call new/disp32 # . . discard args @@ -256,7 +280,7 @@ test-lookup-success: e8/call lookup/disp32 # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP - # EAX contains old top of Heap, except skipping the alloc id in the payload + # EAX contains old top of heap, except skipping the alloc id in the payload # . check-ints-equal(EAX, old_top+4, msg) # . . push args 68/push "F - test-lookup-success"/imm32 @@ -282,38 +306,46 @@ test-lookup-failure: # . prolog 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 - 52/push-EDX + # var heap/ESI : (address allocation-descriptor) = {0, 0} + 68/push 0/imm32/limit + 68/push 0/imm32/curr + 89/copy 3/mod/direct 6/rm32/ESI . . . 4/r32/ESP . . # copy ESP to ESI + # heap = new-segment(512) + # . . push args + 56/push-ESI + 68/push 0x200/imm32 + # . . call + e8/call new-segment/disp32 + # . . discard args + 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP # var h1/ECX = {0, 0} 68/push 0/imm32/address 68/push 0/imm32/alloc-id 89/copy 3/mod/direct 1/rm32/ECX . . . 4/r32/ESP . . # copy ESP to ECX - # var old_top/EBX = Heap->curr - 8b/copy 0/mod/indirect 5/rm32/.disp32 . . 3/r32/EBX Heap/disp32 . # copy *Heap to EBX + # var old_top/EBX = heap->curr + 8b/copy 0/mod/indirect 6/rm32/ESI . . . 3/r32/EBX . . # copy *ESI to EBX # first allocation, to h1 - # . new(Heap, 2, h1) + # . new(heap, 2, h1) # . . push args 51/push-ECX 68/push 2/imm32/size - 68/push Heap/imm32 + 56/push-ESI # . . call e8/call new/disp32 # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP - # reset Heap->curr to mimic reclamation - 89/copy 0/mod/indirect 5/rm32/.disp32 . . 3/r32/EBX Heap/disp32 . # copy EBX to *Heap + # reset heap->curr to mimic reclamation + 89/copy 0/mod/indirect 6/rm32/ESI . . . 3/r32/EBX . . # copy EBX to *ESI # second allocation that returns the same address as the first # var h2/EDX = {0, 0} 68/push 0/imm32/address 68/push 0/imm32/alloc-id 89/copy 3/mod/direct 2/rm32/EDX . . . 4/r32/ESP . . # copy ESP to EDX - # . new(Heap, 2, h2) + # . new(heap, 2, h2) # . . push args 52/push-EDX 68/push 2/imm32/size - 68/push Heap/imm32 + 56/push-ESI # . . call e8/call new/disp32 # . . discard args @@ -338,10 +370,6 @@ test-lookup-failure: # clean up # . *Next-alloc-id = 1 c7 0/subop/copy 0/mod/indirect 5/rm32/.disp32 . . . Next-alloc-id/disp32 1/imm32 # copy to *Next-alloc-id - # . restore registers - 5a/pop-to-EDX - 59/pop-to-ECX - 58/pop-to-EAX # . epilog 89/copy 3/mod/direct 4/rm32/ESP . . . 5/r32/EBP . . # copy EBP to ESP 5d/pop-to-EBP diff --git a/subx/apps/hex b/subx/apps/hex index 8992e424..70734450 100755 Binary files a/subx/apps/hex and b/subx/apps/hex differ diff --git a/subx/apps/pack b/subx/apps/pack index 1da1a476..7e8cc761 100755 Binary files a/subx/apps/pack and b/subx/apps/pack differ -- cgit 1.4.1-2-gfad0