From e99038ea514a8703b170689d5a0730c8d2e542e7 Mon Sep 17 00:00:00 2001 From: Kartik Agaram Date: Mon, 18 Feb 2019 22:43:01 -0800 Subject: 4982 --- html/subx/apps/handle.subx.html | 663 ++++++++++++++++++++-------------------- 1 file changed, 329 insertions(+), 334 deletions(-) (limited to 'html/subx/apps/handle.subx.html') diff --git a/html/subx/apps/handle.subx.html b/html/subx/apps/handle.subx.html index 6f7728ea..6595c56c 100644 --- a/html/subx/apps/handle.subx.html +++ b/html/subx/apps/handle.subx.html @@ -86,340 +86,335 @@ if ('onhashchange' in window) { 25 # . op subop mod rm32 base index scale r32 26 # . 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 27 - 28 # main: - 29 e8/call run-tests/disp32 # 'run-tests' is a function created automatically by SubX. It calls all functions that start with 'test-'. - 30 # syscall(exit, Num-test-failures) - 31 8b/copy 0/mod/indirect 5/rm32/.disp32 . . 3/r32/EBX Num-test-failures/disp32 # copy *Num-test-failures to EBX - 32 b8/copy-to-EAX 1/imm32/exit - 33 cd/syscall 0x80/imm8 - 34 - 35 new: # ad : (address allocation-descriptor), n : int, out : (address handle) - 36 # . prolog - 37 55/push-EBP - 38 89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP - 39 # . save registers - 40 50/push-EAX - 41 51/push-ECX - 42 52/push-EDX - 43 # ECX = n+4 - 44 8b/copy 1/mod/*+disp8 5/rm32/EBP . . . 1/r32/ECX 0xc/disp8 . # copy *(EBP+12) to ECX - 45 81 0/subop/add 3/mod/direct 1/rm32/ECX . . . . . 4/imm32 # add to ECX - 46 # EAX = allocate(ad, ECX) - 47 # . . push args - 48 51/push-ECX - 49 ff 6/subop/push 1/mod/*+disp8 5/rm32/EBP . . . . 8/disp8 . # push *(EBP+8) - 50 # . . call - 51 e8/call allocate/disp32 - 52 # . . discard args - 53 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP - 54 # EDX = out - 55 8b/copy 1/mod/*+disp8 5/rm32/EBP . . . 2/r32/EDX 0x10/disp8 . # copy *(EBP+16) to EDX - 56 # out->address = EAX - 57 89/copy 1/mod/*+disp8 2/rm32/EDX . . . 0/r32/EAX 4/disp8 . # copy EAX to *(EDX+4) - 58 # if (EAX == 0) out->alloc_id = 0, return - 59 81 7/subop/compare 3/mod/direct 0/rm32/EAX . . . . . 0/imm32 # compare EAX - 60 75/jump-if-not-equal $new:continue/disp8 - 61 c7 0/subop/copy 0/mod/indirect 2/rm32/EDX . . . . . 0/imm32 # copy to *EDX - 62 eb/jump $new:end/disp8 - 63 $new:continue: - 64 # otherwise: - 65 # ECX = *Next-alloc-id - 66 8b/copy 0/mod/indirect 5/rm32/.disp32 . . 1/r32/ECX Next-alloc-id/disp32 # copy *Next-alloc-id to ECX - 67 # *EAX = *Next-alloc-id/ECX - 68 89/copy 0/mod/indirect 0/rm32/EAX . . . 1/r32/ECX . . # copy ECX to *EAX - 69 # out->alloc_id = *Next-alloc-id - 70 89/copy 0/mod/indirect 2/rm32/EDX . . . 1/r32/ECX . . # copy ECX to *EDX - 71 # increment *Next-alloc-id - 72 ff 0/subop/increment 0/mod/indirect 5/rm32/.disp32 . . . Next-alloc-id/disp32 # increment *Next-alloc-id - 73 $new:end: - 74 # . restore registers - 75 5a/pop-to-EDX - 76 59/pop-to-ECX - 77 58/pop-to-EAX - 78 # . epilog - 79 89/copy 3/mod/direct 4/rm32/ESP . . . 5/r32/EBP . . # copy EBP to ESP - 80 5d/pop-to-EBP - 81 c3/return - 82 - 83 test-new: - 84 # . prolog - 85 55/push-EBP - 86 89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP - 87 # *Next-alloc-id = 0x34 - 88 c7 0/subop/copy 0/mod/indirect 5/rm32/.disp32 . . . Next-alloc-id/disp32 0x34/imm32 # copy to *Next-alloc-id - 89 # var handle/ECX = {0, 0} - 90 68/push 0/imm32/address - 91 68/push 0/imm32/alloc-id - 92 89/copy 3/mod/direct 1/rm32/ECX . . . 4/r32/ESP . . # copy ESP to ECX - 93 # new(Heap, 2, handle/ECX) - 94 # . . push args - 95 51/push-ECX - 96 68/push 2/imm32/size - 97 68/push Heap/imm32 - 98 # . . call - 99 e8/call new/disp32 -100 # . . discard args -101 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP -102 # check-ints-equal(handle->alloc_id, 0x34, msg) -103 # . . push args -104 68/push "F - test-new: alloc id of handle"/imm32 -105 68/push 0x34/imm32 -106 ff 6/subop/push 0/mod/indirect 1/rm32/ECX . . . . . . # push *ECX -107 # . . call -108 e8/call check-ints-equal/disp32 -109 # . . discard args -110 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP -111 # check-ints-equal(*handle->address, 0x34, msg) -112 # . . push args -113 68/push "F - test-new: alloc id of payload"/imm32 -114 68/push 0x34/imm32 -115 8b/copy 1/mod/*+disp8 1/rm32/ECX . . . 2/r32/EDX 4/disp8 . # copy *(ECX+4) to EDX -116 ff 6/subop/push 0/mod/indirect 2/rm32/EDX . . . . . . # push *EDX -117 # . . call -118 e8/call check-ints-equal/disp32 -119 # . . discard args -120 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP -121 # check-ints-equal(*Next-alloc-id, 0x35) -122 # . . push args -123 68/push "F - test-new: next alloc id"/imm32 -124 68/push 0x35/imm32 -125 ff 6/subop/push 0/mod/indirect 5/rm32/.disp32 . . . Next-alloc-id/disp32 # copy to *Next-alloc-id -126 # . . call -127 e8/call check-ints-equal/disp32 -128 # . . discard args -129 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP -130 # clean up -131 # . *Next-alloc-id = 1 -132 c7 0/subop/copy 0/mod/indirect 5/rm32/.disp32 . . . Next-alloc-id/disp32 1/imm32 # copy to *Next-alloc-id -133 # . epilog -134 89/copy 3/mod/direct 4/rm32/ESP . . . 5/r32/EBP . . # copy EBP to ESP -135 5d/pop-to-EBP -136 c3/return -137 -138 test-new-failure: -139 # . prolog -140 55/push-EBP -141 89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP -142 # . *Next-alloc-id = 0x34 -143 c7 0/subop/copy 0/mod/indirect 5/rm32/.disp32 . . . Next-alloc-id/disp32 0x34/imm32 # copy to *Next-alloc-id -144 # define an allocation-descriptor with no space left -145 # . var ad/EAX : (address allocation-descriptor) = {0x10, 0x10} -146 68/push 0x10/imm32/limit -147 68/push 0x10/imm32/curr -148 89/copy 3/mod/direct 0/rm32/EAX . . . 4/r32/ESP . . # copy ESP to EAX -149 # . var handle/ECX = {random, random} -150 68/push 1234/imm32/address -151 68/push 5678/imm32/alloc-id -152 89/copy 3/mod/direct 1/rm32/ECX . . . 4/r32/ESP . . # copy ESP to ECX -153 # try to allocate -154 # . new(ad, 2, handle/ECX) -155 # . . push args -156 51/push-ECX -157 68/push 2/imm32/size -158 50/push-EAX -159 # . . call -160 e8/call new/disp32 -161 # . . discard args -162 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP -163 # handle should be cleared -164 # . check-ints-equal(handle->alloc_id, 0, msg) -165 # . . push args -166 68/push "F - test-new-failure: alloc id of handle"/imm32 -167 68/push 0/imm32 -168 ff 6/subop/push 0/mod/indirect 1/rm32/ECX . . . . . . # push *ECX -169 # . . call -170 e8/call check-ints-equal/disp32 -171 # . . discard args -172 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP -173 # . check-ints-equal(handle->address, 0, msg) -174 # . . push args -175 68/push "F - test-new-failure: address of handle"/imm32 -176 68/push 0/imm32 -177 ff 6/subop/push 1/mod/*+disp8 1/rm32/ECX . . . . 4/disp8 . # push *(ECX+4) -178 # . . call -179 e8/call check-ints-equal/disp32 -180 # . . discard args -181 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP -182 # Next-alloc-id should be unmodified -183 # . check-ints-equal(*Next-alloc-id, 0x34) -184 # . . push args -185 68/push "F - test-new-failure: next alloc id"/imm32 -186 68/push 0x34/imm32 -187 ff 6/subop/push 0/mod/indirect 5/rm32/.disp32 . . . Next-alloc-id/disp32 # copy to *Next-alloc-id -188 # . . call -189 e8/call check-ints-equal/disp32 -190 # . . discard args -191 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP -192 # clean up -193 # . *Next-alloc-id = 1 -194 c7 0/subop/copy 0/mod/indirect 5/rm32/.disp32 . . . Next-alloc-id/disp32 1/imm32 # copy to *Next-alloc-id -195 # . epilog -196 89/copy 3/mod/direct 4/rm32/ESP . . . 5/r32/EBP . . # copy EBP to ESP -197 5d/pop-to-EBP -198 c3/return -199 -200 lookup: # h : (handle T) -> EAX : (address T) -201 # . prolog -202 55/push-EBP -203 89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP -204 # - as a proof of concept for future inlining, uses no general-purpose registers besides the output (EAX) -205 # EAX = handle -206 8b/copy 1/mod/*+disp8 5/rm32/EBP . . . 0/r32/EAX 8/disp8 . # copy *(EBP+8) to EAX -207 # - inline { -208 # push handle->address -209 ff 6/subop/push 1/mod/*+disp8 1/rm32/ECX . . . . 4/disp8 . # push *(EAX+4) -210 # EAX = handle->alloc_id -211 8b/copy 0/mod/indirect 0/rm32/EAX . . . . . . # copy *EAX to EAX -212 # if (EAX != *ESP) abort -213 39/compare 0/mod/indirect 4/rm32/sib 4/base/ESP 4/index/none . 0/r32/EAX . . # compare *ESP and EAX -214 75/jump-if-not-equal $lookup:fail/disp8 -215 # return ESP+4 -216 58/pop-to-EAX -217 05/add-to-EAX 4/imm32 -218 # - } -219 # . epilog -220 89/copy 3/mod/direct 4/rm32/ESP . . . 5/r32/EBP . . # copy EBP to ESP -221 5d/pop-to-EBP -222 c3/return -223 $lookup:fail: -224 # . _write(2/stderr, msg) -225 # . . push args -226 68/push "lookup failed"/imm32 -227 68/push 2/imm32/stderr -228 # . . call -229 e8/call _write/disp32 -230 # . . discard args -231 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP -232 # . syscall(exit, 1) -233 bb/copy-to-EBX 1/imm32/exit-status -234 b8/copy-to-EAX 1/imm32/exit -235 cd/syscall 0x80/imm8 -236 -237 test-lookup-success: -238 # . prolog -239 55/push-EBP -240 89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP -241 # . save registers -242 # var handle/ECX = {0, 0} -243 68/push 0/imm32/address -244 68/push 0/imm32/alloc-id -245 89/copy 3/mod/direct 1/rm32/ECX . . . 4/r32/ESP . . # copy ESP to ECX -246 # var old_top/EDX = Heap->curr -247 8b/copy 0/mod/indirect 5/rm32/.disp32 . . 2/r32/EDX Heap/disp32 . # copy *Heap to EDX -248 # new(Heap, 2, handle) -249 # . . push args -250 51/push-ECX -251 68/push 2/imm32/size -252 68/push Heap/imm32 -253 # . . call -254 e8/call new/disp32 -255 # . . discard args -256 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP -257 # EAX = lookup(handle) -258 # . . push args -259 51/push-ECX -260 # . . call -261 e8/call lookup/disp32 -262 # . . discard args -263 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP -264 # EAX contains old top of Heap, except skipping the alloc id in the payload -265 # . check-ints-equal(EAX, old_top+4, msg) -266 # . . push args -267 68/push "F - test-lookup-success"/imm32 -268 81 0/subop/add 3/mod/direct 2/rm32/EDX . . . . . 4/imm32 # add to EDX -269 52/push-EDX -270 50/push-EAX -271 # . . call -272 e8/call check-ints-equal/disp32 -273 # . . discard args -274 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP -275 # clean up -276 # . *Next-alloc-id = 1 -277 c7 0/subop/copy 0/mod/indirect 5/rm32/.disp32 . . . Next-alloc-id/disp32 1/imm32 # copy to *Next-alloc-id -278 # . restore registers -279 5a/pop-to-EDX -280 59/pop-to-ECX -281 # . epilog -282 89/copy 3/mod/direct 4/rm32/ESP . . . 5/r32/EBP . . # copy EBP to ESP -283 5d/pop-to-EBP -284 c3/return -285 -286 test-lookup-failure: -287 # . prolog -288 55/push-EBP -289 89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP -290 # . save registers -291 50/push-EAX -292 51/push-ECX -293 52/push-EDX -294 # var h1/ECX = {0, 0} -295 68/push 0/imm32/address -296 68/push 0/imm32/alloc-id -297 89/copy 3/mod/direct 1/rm32/ECX . . . 4/r32/ESP . . # copy ESP to ECX -298 # var old_top/EBX = Heap->curr -299 8b/copy 0/mod/indirect 5/rm32/.disp32 . . 3/r32/EBX Heap/disp32 . # copy *Heap to EBX -300 # first allocation, to h1 -301 # . new(Heap, 2, h1) -302 # . . push args -303 51/push-ECX -304 68/push 2/imm32/size -305 68/push Heap/imm32 -306 # . . call -307 e8/call new/disp32 -308 # . . discard args -309 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP -310 # reset Heap->curr to mimic reclamation -311 89/copy 0/mod/indirect 5/rm32/.disp32 . . 3/r32/EBX Heap/disp32 . # copy EBX to *Heap -312 # second allocation that returns the same address as the first -313 # var h2/EDX = {0, 0} -314 68/push 0/imm32/address -315 68/push 0/imm32/alloc-id -316 89/copy 3/mod/direct 2/rm32/EDX . . . 4/r32/ESP . . # copy ESP to EDX -317 # . new(Heap, 2, h2) -318 # . . push args -319 52/push-EDX -320 68/push 2/imm32/size -321 68/push Heap/imm32 -322 # . . call -323 e8/call new/disp32 -324 # . . discard args -325 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP -326 # check-ints-equal(h1->address, h2->address, msg) -327 # . . push args -328 68/push "F - test-lookup-failure"/imm32 -329 ff 6/subop/push 1/mod/*+disp8 2/rm32/ECX . . . . 4/disp8 . # push *(EDX+4) -330 ff 6/subop/push 1/mod/*+disp8 1/rm32/ECX . . . . 4/disp8 . # push *(ECX+4) -331 # . . call -332 e8/call check-ints-equal/disp32 -333 # . . discard args -334 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP -335 # lookup(h1) should crash -336 # . . push args -337 51/push-ECX -338 # . . call -339 e8/call lookup/disp32 -340 # should never get past this point -341 # . . discard args -342 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP -343 # clean up -344 # . *Next-alloc-id = 1 -345 c7 0/subop/copy 0/mod/indirect 5/rm32/.disp32 . . . Next-alloc-id/disp32 1/imm32 # copy to *Next-alloc-id -346 # . restore registers -347 5a/pop-to-EDX -348 59/pop-to-ECX -349 58/pop-to-EAX -350 # . epilog -351 89/copy 3/mod/direct 4/rm32/ESP . . . 5/r32/EBP . . # copy EBP to ESP -352 5d/pop-to-EBP -353 c3/return -354 -355 == data -356 -357 # Monotonically increasing counter for calls to 'new' -358 Next-alloc-id: -359 01 00 00 00 # 1 -360 -361 # . . vim:nowrap:textwidth=0 + 28 # no Entry; the standard library runs all tests by default + 29 + 30 new: # ad : (address allocation-descriptor), n : int, out : (address handle) + 31 # . prolog + 32 55/push-EBP + 33 89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP + 34 # . save registers + 35 50/push-EAX + 36 51/push-ECX + 37 52/push-EDX + 38 # ECX = n+4 + 39 8b/copy 1/mod/*+disp8 5/rm32/EBP . . . 1/r32/ECX 0xc/disp8 . # copy *(EBP+12) to ECX + 40 81 0/subop/add 3/mod/direct 1/rm32/ECX . . . . . 4/imm32 # add to ECX + 41 # EAX = allocate(ad, ECX) + 42 # . . push args + 43 51/push-ECX + 44 ff 6/subop/push 1/mod/*+disp8 5/rm32/EBP . . . . 8/disp8 . # push *(EBP+8) + 45 # . . call + 46 e8/call allocate/disp32 + 47 # . . discard args + 48 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP + 49 # EDX = out + 50 8b/copy 1/mod/*+disp8 5/rm32/EBP . . . 2/r32/EDX 0x10/disp8 . # copy *(EBP+16) to EDX + 51 # out->address = EAX + 52 89/copy 1/mod/*+disp8 2/rm32/EDX . . . 0/r32/EAX 4/disp8 . # copy EAX to *(EDX+4) + 53 # if (EAX == 0) out->alloc_id = 0, return + 54 81 7/subop/compare 3/mod/direct 0/rm32/EAX . . . . . 0/imm32 # compare EAX + 55 75/jump-if-not-equal $new:continue/disp8 + 56 c7 0/subop/copy 0/mod/indirect 2/rm32/EDX . . . . . 0/imm32 # copy to *EDX + 57 eb/jump $new:end/disp8 + 58 $new:continue: + 59 # otherwise: + 60 # ECX = *Next-alloc-id + 61 8b/copy 0/mod/indirect 5/rm32/.disp32 . . 1/r32/ECX Next-alloc-id/disp32 # copy *Next-alloc-id to ECX + 62 # *EAX = *Next-alloc-id/ECX + 63 89/copy 0/mod/indirect 0/rm32/EAX . . . 1/r32/ECX . . # copy ECX to *EAX + 64 # out->alloc_id = *Next-alloc-id + 65 89/copy 0/mod/indirect 2/rm32/EDX . . . 1/r32/ECX . . # copy ECX to *EDX + 66 # increment *Next-alloc-id + 67 ff 0/subop/increment 0/mod/indirect 5/rm32/.disp32 . . . Next-alloc-id/disp32 # increment *Next-alloc-id + 68 $new:end: + 69 # . restore registers + 70 5a/pop-to-EDX + 71 59/pop-to-ECX + 72 58/pop-to-EAX + 73 # . epilog + 74 89/copy 3/mod/direct 4/rm32/ESP . . . 5/r32/EBP . . # copy EBP to ESP + 75 5d/pop-to-EBP + 76 c3/return + 77 + 78 test-new: + 79 # . prolog + 80 55/push-EBP + 81 89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP + 82 # *Next-alloc-id = 0x34 + 83 c7 0/subop/copy 0/mod/indirect 5/rm32/.disp32 . . . Next-alloc-id/disp32 0x34/imm32 # copy to *Next-alloc-id + 84 # var handle/ECX = {0, 0} + 85 68/push 0/imm32/address + 86 68/push 0/imm32/alloc-id + 87 89/copy 3/mod/direct 1/rm32/ECX . . . 4/r32/ESP . . # copy ESP to ECX + 88 # new(Heap, 2, handle/ECX) + 89 # . . push args + 90 51/push-ECX + 91 68/push 2/imm32/size + 92 68/push Heap/imm32 + 93 # . . call + 94 e8/call new/disp32 + 95 # . . discard args + 96 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP + 97 # check-ints-equal(handle->alloc_id, 0x34, msg) + 98 # . . push args + 99 68/push "F - test-new: alloc id of handle"/imm32 +100 68/push 0x34/imm32 +101 ff 6/subop/push 0/mod/indirect 1/rm32/ECX . . . . . . # push *ECX +102 # . . call +103 e8/call check-ints-equal/disp32 +104 # . . discard args +105 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP +106 # check-ints-equal(*handle->address, 0x34, msg) +107 # . . push args +108 68/push "F - test-new: alloc id of payload"/imm32 +109 68/push 0x34/imm32 +110 8b/copy 1/mod/*+disp8 1/rm32/ECX . . . 2/r32/EDX 4/disp8 . # copy *(ECX+4) to EDX +111 ff 6/subop/push 0/mod/indirect 2/rm32/EDX . . . . . . # push *EDX +112 # . . call +113 e8/call check-ints-equal/disp32 +114 # . . discard args +115 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP +116 # check-ints-equal(*Next-alloc-id, 0x35) +117 # . . push args +118 68/push "F - test-new: next alloc id"/imm32 +119 68/push 0x35/imm32 +120 ff 6/subop/push 0/mod/indirect 5/rm32/.disp32 . . . Next-alloc-id/disp32 # copy to *Next-alloc-id +121 # . . call +122 e8/call check-ints-equal/disp32 +123 # . . discard args +124 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP +125 # clean up +126 # . *Next-alloc-id = 1 +127 c7 0/subop/copy 0/mod/indirect 5/rm32/.disp32 . . . Next-alloc-id/disp32 1/imm32 # copy to *Next-alloc-id +128 # . epilog +129 89/copy 3/mod/direct 4/rm32/ESP . . . 5/r32/EBP . . # copy EBP to ESP +130 5d/pop-to-EBP +131 c3/return +132 +133 test-new-failure: +134 # . prolog +135 55/push-EBP +136 89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP +137 # . *Next-alloc-id = 0x34 +138 c7 0/subop/copy 0/mod/indirect 5/rm32/.disp32 . . . Next-alloc-id/disp32 0x34/imm32 # copy to *Next-alloc-id +139 # define an allocation-descriptor with no space left +140 # . var ad/EAX : (address allocation-descriptor) = {0x10, 0x10} +141 68/push 0x10/imm32/limit +142 68/push 0x10/imm32/curr +143 89/copy 3/mod/direct 0/rm32/EAX . . . 4/r32/ESP . . # copy ESP to EAX +144 # . var handle/ECX = {random, random} +145 68/push 1234/imm32/address +146 68/push 5678/imm32/alloc-id +147 89/copy 3/mod/direct 1/rm32/ECX . . . 4/r32/ESP . . # copy ESP to ECX +148 # try to allocate +149 # . new(ad, 2, handle/ECX) +150 # . . push args +151 51/push-ECX +152 68/push 2/imm32/size +153 50/push-EAX +154 # . . call +155 e8/call new/disp32 +156 # . . discard args +157 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP +158 # handle should be cleared +159 # . check-ints-equal(handle->alloc_id, 0, msg) +160 # . . push args +161 68/push "F - test-new-failure: alloc id of handle"/imm32 +162 68/push 0/imm32 +163 ff 6/subop/push 0/mod/indirect 1/rm32/ECX . . . . . . # push *ECX +164 # . . call +165 e8/call check-ints-equal/disp32 +166 # . . discard args +167 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP +168 # . check-ints-equal(handle->address, 0, msg) +169 # . . push args +170 68/push "F - test-new-failure: address of handle"/imm32 +171 68/push 0/imm32 +172 ff 6/subop/push 1/mod/*+disp8 1/rm32/ECX . . . . 4/disp8 . # push *(ECX+4) +173 # . . call +174 e8/call check-ints-equal/disp32 +175 # . . discard args +176 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP +177 # Next-alloc-id should be unmodified +178 # . check-ints-equal(*Next-alloc-id, 0x34) +179 # . . push args +180 68/push "F - test-new-failure: next alloc id"/imm32 +181 68/push 0x34/imm32 +182 ff 6/subop/push 0/mod/indirect 5/rm32/.disp32 . . . Next-alloc-id/disp32 # copy to *Next-alloc-id +183 # . . call +184 e8/call check-ints-equal/disp32 +185 # . . discard args +186 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP +187 # clean up +188 # . *Next-alloc-id = 1 +189 c7 0/subop/copy 0/mod/indirect 5/rm32/.disp32 . . . Next-alloc-id/disp32 1/imm32 # copy to *Next-alloc-id +190 # . epilog +191 89/copy 3/mod/direct 4/rm32/ESP . . . 5/r32/EBP . . # copy EBP to ESP +192 5d/pop-to-EBP +193 c3/return +194 +195 lookup: # h : (handle T) -> EAX : (address T) +196 # . prolog +197 55/push-EBP +198 89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP +199 # - as a proof of concept for future inlining, uses no general-purpose registers besides the output (EAX) +200 # EAX = handle +201 8b/copy 1/mod/*+disp8 5/rm32/EBP . . . 0/r32/EAX 8/disp8 . # copy *(EBP+8) to EAX +202 # - inline { +203 # push handle->address +204 ff 6/subop/push 1/mod/*+disp8 1/rm32/ECX . . . . 4/disp8 . # push *(EAX+4) +205 # EAX = handle->alloc_id +206 8b/copy 0/mod/indirect 0/rm32/EAX . . . . . . # copy *EAX to EAX +207 # if (EAX != *ESP) abort +208 39/compare 0/mod/indirect 4/rm32/sib 4/base/ESP 4/index/none . 0/r32/EAX . . # compare *ESP and EAX +209 75/jump-if-not-equal $lookup:fail/disp8 +210 # return ESP+4 +211 58/pop-to-EAX +212 05/add-to-EAX 4/imm32 +213 # - } +214 # . epilog +215 89/copy 3/mod/direct 4/rm32/ESP . . . 5/r32/EBP . . # copy EBP to ESP +216 5d/pop-to-EBP +217 c3/return +218 $lookup:fail: +219 # . _write(2/stderr, msg) +220 # . . push args +221 68/push "lookup failed"/imm32 +222 68/push 2/imm32/stderr +223 # . . call +224 e8/call _write/disp32 +225 # . . discard args +226 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP +227 # . syscall(exit, 1) +228 bb/copy-to-EBX 1/imm32/exit-status +229 b8/copy-to-EAX 1/imm32/exit +230 cd/syscall 0x80/imm8 +231 +232 test-lookup-success: +233 # . prolog +234 55/push-EBP +235 89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP +236 # . save registers +237 # var handle/ECX = {0, 0} +238 68/push 0/imm32/address +239 68/push 0/imm32/alloc-id +240 89/copy 3/mod/direct 1/rm32/ECX . . . 4/r32/ESP . . # copy ESP to ECX +241 # var old_top/EDX = Heap->curr +242 8b/copy 0/mod/indirect 5/rm32/.disp32 . . 2/r32/EDX Heap/disp32 . # copy *Heap to EDX +243 # new(Heap, 2, handle) +244 # . . push args +245 51/push-ECX +246 68/push 2/imm32/size +247 68/push Heap/imm32 +248 # . . call +249 e8/call new/disp32 +250 # . . discard args +251 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP +252 # EAX = lookup(handle) +253 # . . push args +254 51/push-ECX +255 # . . call +256 e8/call lookup/disp32 +257 # . . discard args +258 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP +259 # EAX contains old top of Heap, except skipping the alloc id in the payload +260 # . check-ints-equal(EAX, old_top+4, msg) +261 # . . push args +262 68/push "F - test-lookup-success"/imm32 +263 81 0/subop/add 3/mod/direct 2/rm32/EDX . . . . . 4/imm32 # add to EDX +264 52/push-EDX +265 50/push-EAX +266 # . . call +267 e8/call check-ints-equal/disp32 +268 # . . discard args +269 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP +270 # clean up +271 # . *Next-alloc-id = 1 +272 c7 0/subop/copy 0/mod/indirect 5/rm32/.disp32 . . . Next-alloc-id/disp32 1/imm32 # copy to *Next-alloc-id +273 # . restore registers +274 5a/pop-to-EDX +275 59/pop-to-ECX +276 # . epilog +277 89/copy 3/mod/direct 4/rm32/ESP . . . 5/r32/EBP . . # copy EBP to ESP +278 5d/pop-to-EBP +279 c3/return +280 +281 test-lookup-failure: +282 # . prolog +283 55/push-EBP +284 89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP +285 # . save registers +286 50/push-EAX +287 51/push-ECX +288 52/push-EDX +289 # var h1/ECX = {0, 0} +290 68/push 0/imm32/address +291 68/push 0/imm32/alloc-id +292 89/copy 3/mod/direct 1/rm32/ECX . . . 4/r32/ESP . . # copy ESP to ECX +293 # var old_top/EBX = Heap->curr +294 8b/copy 0/mod/indirect 5/rm32/.disp32 . . 3/r32/EBX Heap/disp32 . # copy *Heap to EBX +295 # first allocation, to h1 +296 # . new(Heap, 2, h1) +297 # . . push args +298 51/push-ECX +299 68/push 2/imm32/size +300 68/push Heap/imm32 +301 # . . call +302 e8/call new/disp32 +303 # . . discard args +304 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP +305 # reset Heap->curr to mimic reclamation +306 89/copy 0/mod/indirect 5/rm32/.disp32 . . 3/r32/EBX Heap/disp32 . # copy EBX to *Heap +307 # second allocation that returns the same address as the first +308 # var h2/EDX = {0, 0} +309 68/push 0/imm32/address +310 68/push 0/imm32/alloc-id +311 89/copy 3/mod/direct 2/rm32/EDX . . . 4/r32/ESP . . # copy ESP to EDX +312 # . new(Heap, 2, h2) +313 # . . push args +314 52/push-EDX +315 68/push 2/imm32/size +316 68/push Heap/imm32 +317 # . . call +318 e8/call new/disp32 +319 # . . discard args +320 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP +321 # check-ints-equal(h1->address, h2->address, msg) +322 # . . push args +323 68/push "F - test-lookup-failure"/imm32 +324 ff 6/subop/push 1/mod/*+disp8 2/rm32/ECX . . . . 4/disp8 . # push *(EDX+4) +325 ff 6/subop/push 1/mod/*+disp8 1/rm32/ECX . . . . 4/disp8 . # push *(ECX+4) +326 # . . call +327 e8/call check-ints-equal/disp32 +328 # . . discard args +329 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP +330 # lookup(h1) should crash +331 # . . push args +332 51/push-ECX +333 # . . call +334 e8/call lookup/disp32 +335 # should never get past this point +336 # . . discard args +337 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP +338 # clean up +339 # . *Next-alloc-id = 1 +340 c7 0/subop/copy 0/mod/indirect 5/rm32/.disp32 . . . Next-alloc-id/disp32 1/imm32 # copy to *Next-alloc-id +341 # . restore registers +342 5a/pop-to-EDX +343 59/pop-to-ECX +344 58/pop-to-EAX +345 # . epilog +346 89/copy 3/mod/direct 4/rm32/ESP . . . 5/r32/EBP . . # copy EBP to ESP +347 5d/pop-to-EBP +348 c3/return +349 +350 == data +351 +352 # Monotonically increasing counter for calls to 'new' +353 Next-alloc-id: +354 1/imm32 +355 +356 # . . vim:nowrap:textwidth=0 -- cgit 1.4.1-2-gfad0