From 5396e24cba8390ca2d70d99c7e8772eee4ec3a11 Mon Sep 17 00:00:00 2001 From: Kartik Agaram Date: Tue, 18 May 2021 13:01:59 -0700 Subject: . --- html/120allocate.subx.html | 1577 ++++++++++++++++++++++---------------------- 1 file changed, 799 insertions(+), 778 deletions(-) (limited to 'html/120allocate.subx.html') diff --git a/html/120allocate.subx.html b/html/120allocate.subx.html index cd7568b7..e5b5d820 100644 --- a/html/120allocate.subx.html +++ b/html/120allocate.subx.html @@ -125,7 +125,7 @@ if ('onhashchange' in window) { 64 ff 6/subop/push 1/mod/*+disp8 5/rm32/ebp . . . . 0xc/disp8 . # push *(ebp+12) 65 50/push-eax 66 # . . call - 67 e8/call zero-out/disp32 + 67 e8/call zero-out/disp32 68 # . . discard args 69 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp 70 $allocate:end: @@ -173,7 +173,7 @@ if ('onhashchange' in window) { 112 # TODO: move this check up before any state updates when we support error recovery 113 8d/copy-address 1/mod/*+disp8 4/rm32/sib 0/base/eax 3/index/ebx . 0/r32/eax 4/disp8 . # copy eax+ebx+4 to eax 114 3b/compare 1/mod/*+disp8 1/rm32/ecx . . . 0/r32/eax 4/disp8 . # compare eax with *(ecx+4) -115 73/jump-if->=-signed $allocate-raw:abort/disp8 +115 73/jump-if->=-signed $allocate-raw:abort/disp8 116 $allocate-raw:commit: 117 # ad->curr += n+4 118 89/copy 0/mod/indirect 1/rm32/ecx . . . 0/r32/eax . . # copy eax to *ecx @@ -190,789 +190,810 @@ if ('onhashchange' in window) { 129 5d/pop-to-ebp 130 c3/return 131 -132 $allocate-raw:abort: -133 (draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0 "allocate: failed" 3 0) # 3=cyan -134 { -135 eb/jump loop/disp8 -136 } -137 # never gets here -138 -139 test-allocate-raw-success: -140 # . prologue -141 55/push-ebp -142 89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp -143 # var ad/ecx: allocation-descriptor containing 16 bytes -144 # . var end/ecx: (addr byte) -145 89/<- %ecx 4/r32/esp -146 # . var start/edx: (addr byte) = end - 16 -147 81 5/subop/subtract %esp 0x10/imm32 -148 89/<- %edx 4/r32/esp -149 # . ad = {start, end} -150 51/push-ecx -151 52/push-edx -152 89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx -153 # var expected-payload/ebx = ad->curr -154 8b/copy 0/mod/indirect 1/rm32/ecx . . . 3/r32/ebx . . # copy *ecx to ebx -155 # var h/edx: handle = {0, 0} -156 68/push 0/imm32 -157 68/push 0/imm32 -158 89/copy 3/mod/direct 2/rm32/edx . . . 4/r32/esp . . # copy esp to edx -159 # *Next-alloc-id = 0x34 -160 c7 0/subop/copy 0/mod/indirect 5/rm32/.disp32 . . . Next-alloc-id/disp32 0x34/imm32 # copy to *Next-alloc-id -161 # allocate-raw(ad, 3, h) -162 # . . push args -163 52/push-edx -164 68/push 3/imm32 -165 51/push-ecx -166 # . . call -167 e8/call allocate-raw/disp32 -168 # . . discard args -169 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32 # add to esp -170 # check-ints-equal(h->alloc-id, 0x34, msg) -171 # . . push args -172 68/push "F - test-allocate-raw-success: sets alloc-id in handle"/imm32 -173 68/push 0x34/imm32 -174 ff 6/subop/push 0/mod/indirect 2/rm32/edx . . . . . . # push *edx -175 # . . call -176 e8/call check-ints-equal/disp32 -177 # . . discard args -178 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32 # add to esp -179 # check-ints-equal(h->payload, expected-payload, msg) -180 # . . push args -181 68/push "F - test-allocate-raw-success: sets payload in handle"/imm32 -182 53/push-ebx -183 ff 6/subop/push 1/mod/*+disp8 2/rm32/edx . . . . 4/disp8 . # push *(edx+4) -184 # . . call -185 e8/call check-ints-equal/disp32 -186 # . . discard args -187 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32 # add to esp -188 # check-ints-equal(h->payload->alloc-id, 0x34, msg) -189 # . . push args -190 68/push "F - test-allocate-raw-success: sets alloc-id in payload"/imm32 -191 68/push 0x34/imm32 -192 ff 6/subop/push 0/mod/indirect 3/rm32/ebx . . . . . . # push *ebx -193 # . . call -194 e8/call check-ints-equal/disp32 -195 # . . discard args -196 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32 # add to esp -197 # check-ints-equal(*Next-alloc-id, 0x35, msg) -198 # . . push args -199 68/push "F - test-allocate-raw-success: increments Next-alloc-id"/imm32 -200 68/push 0x35/imm32 -201 ff 6/subop/push 0/mod/indirect 5/rm32/.disp32 . . . Next-alloc-id/disp32 # push *Next-alloc-id -202 # . . call -203 e8/call check-ints-equal/disp32 -204 # . . discard args -205 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32 # add to esp -206 # check-ints-equal(ad->curr - expected-payload, 3 + 4 for alloc-id, msg) -207 # . . push args -208 68/push "F - test-allocate-raw-success: updates allocation descriptor"/imm32 -209 68/push 7/imm32 -210 8b/copy 0/mod/indirect 1/rm32/ecx . . . 0/r32/eax . . # copy *ecx to eax -211 29/subtract 3/mod/direct 0/rm32/eax . . . 3/r32/ebx . . # subtract ebx from eax -212 50/push-eax -213 # . . call -214 e8/call check-ints-equal/disp32 -215 # . . discard args -216 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32 # add to esp -217 # clean up -218 c7 0/subop/copy 0/mod/indirect 5/rm32/.disp32 . . . Next-alloc-id/disp32 0x100/imm32 # copy to *Next-alloc-id -219 # . reclaim locals -220 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0x20/imm32 # add to esp -221 # . epilogue -222 89/copy 3/mod/direct 4/rm32/esp . . . 5/r32/ebp . . # copy ebp to esp -223 5d/pop-to-ebp -224 c3/return -225 -226 lookup: # h: (handle _T) -> result/eax: (addr _T) -227 # . prologue -228 55/push-ebp -229 89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp -230 # . save registers -231 51/push-ecx -232 # eax = 0 -233 31/xor 3/mod/direct 0/rm32/eax . . . 0/r32/eax . . # clear eax -234 # ecx = handle->alloc_id -235 8b/copy 1/mod/*+disp8 5/rm32/ebp . . . 1/r32/ecx 8/disp8 . # copy *(ebp+8) to ecx -236 # if (ecx == 0) return 0 -237 81 7/subop/compare 3/mod/direct 1/rm32/ecx . . . . . 0/imm32 # compare ecx -238 74/jump-if-= $lookup:end/disp8 -239 # eax = handle->address (payload) -240 8b/copy 1/mod/*+disp8 5/rm32/ebp . . . 0/r32/eax 0xc/disp8 . # copy *(ebp+12) to eax -241 # if (ecx != *eax) abort -242 39/compare 0/mod/indirect 0/rm32/eax . . . 1/r32/ecx . . # compare *eax and ecx -243 75/jump-if-!= $lookup:abort/disp8 -244 # add 4 to eax -245 05/add-to-eax 4/imm32 -246 $lookup:end: -247 # . restore registers -248 59/pop-to-ecx -249 # . epilogue -250 89/copy 3/mod/direct 4/rm32/esp . . . 5/r32/ebp . . # copy ebp to esp -251 5d/pop-to-ebp -252 c3/return -253 -254 $lookup:abort: -255 (draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0 "lookup: failed" 3 0) # 3=cyan -256 { -257 eb/jump loop/disp8 -258 } -259 # never gets here -260 -261 test-lookup-success: -262 # . prologue -263 55/push-ebp -264 89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp -265 # var ad/ebx: allocation-descriptor containing 16 bytes -266 # . var end/ecx: (addr byte) -267 89/<- %ecx 4/r32/esp -268 # . var start/edx: (addr byte) = end - 16 -269 81 5/subop/subtract %esp 0x10/imm32 -270 89/<- %edx 4/r32/esp -271 # . ad = {start, end} -272 51/push-ecx -273 52/push-edx -274 89/copy 3/mod/direct 3/rm32/ebx . . . 4/r32/esp . . # copy esp to ebx -275 # var handle/ecx: handle -276 68/push 0/imm32/address -277 68/push 0/imm32/alloc-id -278 89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx -279 # var old-top/edx = ad->curr -280 8b/copy 0/mod/indirect 3/rm32/ebx . . . 2/r32/edx . . # copy *ebx to edx -281 # allocate-raw(ad, 2, handle) -282 # . . push args -283 51/push-ecx -284 68/push 2/imm32/size -285 53/push-ebx -286 # . . call -287 e8/call allocate-raw/disp32 -288 # . . discard args -289 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32 # add to esp -290 # eax = lookup(handle) -291 # . . push args -292 ff 6/subop/push 1/mod/*+disp8 1/rm32/ecx . . . . 4/disp8 . # push *(ecx+4) -293 ff 6/subop/push 0/mod/indirect 1/rm32/ecx . . . . . . # push *ecx -294 # . . call -295 e8/call lookup/disp32 -296 # . . discard args -297 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp -298 # eax contains old top of heap, except skipping the alloc-id in the payload -299 # . check-ints-equal(eax, old-top+4, msg) -300 # . . push args -301 68/push "F - test-lookup-success"/imm32 -302 81 0/subop/add 3/mod/direct 2/rm32/edx . . . . . 4/imm32 # add to edx -303 52/push-edx -304 50/push-eax -305 # . . call -306 e8/call check-ints-equal/disp32 -307 # . . discard args -308 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32 # add to esp -309 # clean up -310 c7 0/subop/copy 0/mod/indirect 5/rm32/.disp32 . . . Next-alloc-id/disp32 0x100/imm32 # copy to *Next-alloc-id -311 # . reclaim locals -312 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0x20/imm32 # add to esp -313 # . epilogue -314 89/copy 3/mod/direct 4/rm32/esp . . . 5/r32/ebp . . # copy ebp to esp -315 5d/pop-to-ebp -316 c3/return -317 -318 test-lookup-null-returns-null: -319 # . prologue -320 55/push-ebp -321 89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp -322 # var handle/ecx: handle -323 68/push 0/imm32/address -324 68/push 0/imm32/alloc-id -325 89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx -326 # eax = lookup(handle) -327 # . . push args -328 ff 6/subop/push 1/mod/*+disp8 1/rm32/ecx . . . . 4/disp8 . # push *(ecx+4) -329 ff 6/subop/push 0/mod/indirect 1/rm32/ecx . . . . . . # push *ecx -330 # . . call -331 e8/call lookup/disp32 -332 # . . discard args -333 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp -334 # check-ints-equal(eax, 0, msg) -335 # . . push args -336 68/push "F - test-lookup-null-returns-null"/imm32 -337 68/push 0/imm32 -338 50/push-eax -339 # . . call -340 e8/call check-ints-equal/disp32 -341 # . . discard args -342 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32 # add to esp -343 # . reclaim locals -344 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp -345 # . epilogue -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 _pending-test-lookup-failure: -351 # . prologue -352 55/push-ebp -353 89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp -354 # var ad/ecx: allocation-descriptor containing 16 bytes -355 # . var end/ecx: (addr byte) -356 89/<- %ecx 4/r32/esp -357 # . var start/edx: (addr byte) = end - 16 -358 81 5/subop/subtract %esp 0x10/imm32 -359 89/<- %edx 4/r32/esp -360 # . ad = {start, end} -361 51/push-ecx -362 52/push-edx -363 89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx -364 # var h1/ecx: handle -365 68/push 0/imm32/address -366 68/push 0/imm32/alloc-id -367 89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx -368 # var old_top/ebx = ad->curr -369 8b/copy 0/mod/indirect 6/rm32/esi . . . 3/r32/ebx . . # copy *esi to ebx -370 # first allocation, to h1 -371 # . allocate(ad, 2, h1) -372 # . . push args -373 51/push-ecx -374 68/push 2/imm32/size -375 56/push-esi -376 # . . call -377 e8/call allocate/disp32 -378 # . . discard args -379 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32 # add to esp -380 # reset ad->curr to mimic reclamation -381 89/copy 0/mod/indirect 6/rm32/esi . . . 3/r32/ebx . . # copy ebx to *esi -382 # second allocation that returns the same address as the first -383 # var h2/edx: handle -384 68/push 0/imm32/address -385 68/push 0/imm32/alloc-id -386 89/copy 3/mod/direct 2/rm32/edx . . . 4/r32/esp . . # copy esp to edx -387 # . allocate(ad, 2, h2) -388 # . . push args -389 52/push-edx -390 68/push 2/imm32/size -391 56/push-esi -392 # . . call -393 e8/call allocate/disp32 -394 # . . discard args -395 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32 # add to esp -396 # check-ints-equal(h1->address, h2->address, msg) -397 # . . push args -398 68/push "F - test-lookup-failure"/imm32 -399 ff 6/subop/push 1/mod/*+disp8 2/rm32/ecx . . . . 4/disp8 . # push *(edx+4) -400 ff 6/subop/push 1/mod/*+disp8 1/rm32/ecx . . . . 4/disp8 . # push *(ecx+4) -401 # . . call -402 e8/call check-ints-equal/disp32 -403 # . . discard args -404 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32 # add to esp -405 # lookup(h1) should crash -406 # . . push args -407 ff 6/subop/push 1/mod/*+disp8 1/rm32/ecx . . . . 4/disp8 . # push *(ecx+4) -408 ff 6/subop/push 0/mod/indirect 1/rm32/ecx . . . . . . # push *ecx -409 # . . call -410 e8/call lookup/disp32 -411 # should never get past this point -412 # . . discard args -413 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp -414 # clean up -415 c7 0/subop/copy 0/mod/indirect 5/rm32/.disp32 . . . Next-alloc-id/disp32 0x100/imm32 # copy to *Next-alloc-id -416 # . reclaim locals -417 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0x20/imm32 # add to esp -418 # . epilogue -419 89/copy 3/mod/direct 4/rm32/esp . . . 5/r32/ebp . . # copy ebp to esp -420 5d/pop-to-ebp -421 c3/return -422 -423 # when comparing handles, just treat them as pure values -424 handle-equal?: # a: (handle _T), b: (handle _T) -> result/eax: boolean -425 # . prologue -426 55/push-ebp -427 89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp -428 # . save registers -429 51/push-ecx -430 # eax = false -431 b8/copy-to-eax 0/imm32/false -432 $handle-equal?:compare-alloc-id: -433 # ecx = a->alloc_id -434 8b/copy 1/mod/*+disp8 5/rm32/ebp . . . 1/r32/ecx 8/disp8 . # copy *(ebp+8) to ecx -435 # if (ecx != b->alloc_id) return false -436 39/compare 1/mod/*+disp8 5/rm32/ebp . . . 1/r32/ecx 0x10/disp8 . # compare ecx and *(ebp+16) -437 75/jump-if-!= $handle-equal?:end/disp8 -438 $handle-equal?:compare-address: -439 # ecx = handle->address -440 8b/copy 1/mod/*+disp8 5/rm32/ebp . . . 1/r32/ecx 0xc/disp8 . # copy *(ebp+12) to ecx -441 # if (ecx != b->address) return false -442 39/compare 1/mod/*+disp8 5/rm32/ebp . . . 1/r32/ecx 0x14/disp8 . # compare ecx and *(ebp+20) -443 75/jump-if-!= $handle-equal?:end/disp8 -444 $handle-equal?:return-true: -445 # return true -446 b8/copy-to-eax 1/imm32/true -447 $handle-equal?:end: -448 # . restore registers -449 59/pop-to-ecx -450 # . epilogue -451 89/copy 3/mod/direct 4/rm32/esp . . . 5/r32/ebp . . # copy ebp to esp -452 5d/pop-to-ebp -453 c3/return -454 -455 copy-handle: # src: (handle _T), dest: (addr handle _T) -456 # . prologue -457 55/push-ebp -458 89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp -459 # . save registers -460 50/push-eax -461 51/push-ecx -462 # ecx = dest -463 8b/copy 1/mod/*+disp8 5/rm32/ebp . . . 1/r32/ecx 0x10/disp8 . # copy *(ebp+16) to ecx -464 # *dest = src -465 8b/copy 1/mod/*+disp8 5/rm32/ebp . . . 0/r32/eax 8/disp8 . # copy *(ebp+8) to eax -466 89/copy 0/mod/indirect 1/rm32/ecx . . . 0/r32/eax . . # copy eax to *ecx -467 8b/copy 1/mod/*+disp8 5/rm32/ebp . . . 0/r32/eax 0xc/disp8 . # copy *(ebp+12) to eax -468 89/copy 1/mod/*+disp8 1/rm32/ecx . . . 0/r32/eax 4/disp8 . # copy eax to *(ecx+4) -469 $copy-handle:end: -470 # . restore registers -471 59/pop-to-ecx -472 58/pop-to-eax -473 # . epilogue -474 89/copy 3/mod/direct 4/rm32/esp . . . 5/r32/ebp . . # copy ebp to esp -475 5d/pop-to-ebp -476 c3/return -477 -478 # helper: create a nested allocation descriptor (useful for tests) -479 allocate-region: # ad: (addr allocation-descriptor), n: int, out: (addr handle allocation-descriptor) +132 $allocate-raw:abort: +133 (abort "allocate: failed") +134 # never gets here +135 +136 test-allocate-raw-success: +137 # . prologue +138 55/push-ebp +139 89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp +140 # var ad/ecx: allocation-descriptor containing 16 bytes +141 # . var end/ecx: (addr byte) +142 89/<- %ecx 4/r32/esp +143 # . var start/edx: (addr byte) = end - 16 +144 81 5/subop/subtract %esp 0x10/imm32 +145 89/<- %edx 4/r32/esp +146 # . ad = {start, end} +147 51/push-ecx +148 52/push-edx +149 89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx +150 # var expected-payload/ebx = ad->curr +151 8b/copy 0/mod/indirect 1/rm32/ecx . . . 3/r32/ebx . . # copy *ecx to ebx +152 # var h/edx: handle = {0, 0} +153 68/push 0/imm32 +154 68/push 0/imm32 +155 89/copy 3/mod/direct 2/rm32/edx . . . 4/r32/esp . . # copy esp to edx +156 # *Next-alloc-id = 0x34 +157 c7 0/subop/copy 0/mod/indirect 5/rm32/.disp32 . . . Next-alloc-id/disp32 0x34/imm32 # copy to *Next-alloc-id +158 # allocate-raw(ad, 3, h) +159 # . . push args +160 52/push-edx +161 68/push 3/imm32 +162 51/push-ecx +163 # . . call +164 e8/call allocate-raw/disp32 +165 # . . discard args +166 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32 # add to esp +167 # check-ints-equal(h->alloc-id, 0x34, msg) +168 # . . push args +169 68/push "F - test-allocate-raw-success: sets alloc-id in handle"/imm32 +170 68/push 0x34/imm32 +171 ff 6/subop/push 0/mod/indirect 2/rm32/edx . . . . . . # push *edx +172 # . . call +173 e8/call check-ints-equal/disp32 +174 # . . discard args +175 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32 # add to esp +176 # check-ints-equal(h->payload, expected-payload, msg) +177 # . . push args +178 68/push "F - test-allocate-raw-success: sets payload in handle"/imm32 +179 53/push-ebx +180 ff 6/subop/push 1/mod/*+disp8 2/rm32/edx . . . . 4/disp8 . # push *(edx+4) +181 # . . call +182 e8/call check-ints-equal/disp32 +183 # . . discard args +184 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32 # add to esp +185 # check-ints-equal(h->payload->alloc-id, 0x34, msg) +186 # . . push args +187 68/push "F - test-allocate-raw-success: sets alloc-id in payload"/imm32 +188 68/push 0x34/imm32 +189 ff 6/subop/push 0/mod/indirect 3/rm32/ebx . . . . . . # push *ebx +190 # . . call +191 e8/call check-ints-equal/disp32 +192 # . . discard args +193 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32 # add to esp +194 # check-ints-equal(*Next-alloc-id, 0x35, msg) +195 # . . push args +196 68/push "F - test-allocate-raw-success: increments Next-alloc-id"/imm32 +197 68/push 0x35/imm32 +198 ff 6/subop/push 0/mod/indirect 5/rm32/.disp32 . . . Next-alloc-id/disp32 # push *Next-alloc-id +199 # . . call +200 e8/call check-ints-equal/disp32 +201 # . . discard args +202 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32 # add to esp +203 # check-ints-equal(ad->curr - expected-payload, 3 + 4 for alloc-id, msg) +204 # . . push args +205 68/push "F - test-allocate-raw-success: updates allocation descriptor"/imm32 +206 68/push 7/imm32 +207 8b/copy 0/mod/indirect 1/rm32/ecx . . . 0/r32/eax . . # copy *ecx to eax +208 29/subtract 3/mod/direct 0/rm32/eax . . . 3/r32/ebx . . # subtract ebx from eax +209 50/push-eax +210 # . . call +211 e8/call check-ints-equal/disp32 +212 # . . discard args +213 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32 # add to esp +214 # clean up +215 c7 0/subop/copy 0/mod/indirect 5/rm32/.disp32 . . . Next-alloc-id/disp32 0x100/imm32 # copy to *Next-alloc-id +216 # . reclaim locals +217 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0x20/imm32 # add to esp +218 # . epilogue +219 89/copy 3/mod/direct 4/rm32/esp . . . 5/r32/ebp . . # copy ebp to esp +220 5d/pop-to-ebp +221 c3/return +222 +223 lookup: # h: (handle _T) -> result/eax: (addr _T) +224 # . prologue +225 55/push-ebp +226 89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp +227 # . save registers +228 51/push-ecx +229 # eax = 0 +230 31/xor 3/mod/direct 0/rm32/eax . . . 0/r32/eax . . # clear eax +231 # ecx = handle->alloc_id +232 8b/copy 1/mod/*+disp8 5/rm32/ebp . . . 1/r32/ecx 8/disp8 . # copy *(ebp+8) to ecx +233 # if (ecx == 0) return 0 +234 81 7/subop/compare 3/mod/direct 1/rm32/ecx . . . . . 0/imm32 # compare ecx +235 74/jump-if-= $lookup:end/disp8 +236 # eax = handle->address (payload) +237 8b/copy 1/mod/*+disp8 5/rm32/ebp . . . 0/r32/eax 0xc/disp8 . # copy *(ebp+12) to eax +238 # if (ecx != *eax) abort +239 39/compare 0/mod/indirect 0/rm32/eax . . . 1/r32/ecx . . # compare *eax and ecx +240 75/jump-if-!= $lookup:abort/disp8 +241 # add 4 to eax +242 05/add-to-eax 4/imm32 +243 $lookup:end: +244 # . restore registers +245 59/pop-to-ecx +246 # . epilogue +247 89/copy 3/mod/direct 4/rm32/esp . . . 5/r32/ebp . . # copy ebp to esp +248 5d/pop-to-ebp +249 c3/return +250 +251 $lookup:abort: +252 (draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0 "lookup failed: (" 3 0) # 3=cyan +253 (draw-int32-hex-wrapping-right-then-down-from-cursor-over-full-screen 0 *(ebp+8) 3 0) +254 (draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0 ", " 3 0) +255 (draw-int32-hex-wrapping-right-then-down-from-cursor-over-full-screen 0 *(ebp+0xc) 3 0) +256 (draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0 ") -> " 3 0) +257 (draw-int32-hex-wrapping-right-then-down-from-cursor-over-full-screen 0 *eax 3 0) +258 (draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0 ". Contents of a few words starting from address 0: " 3 0) +259 b8/copy-to-eax 0/imm32 +260 (draw-int32-hex-wrapping-right-then-down-from-cursor-over-full-screen 0 *eax 2 0) +261 (draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0 " " 2 0) +262 40/increment-eax +263 (draw-int32-hex-wrapping-right-then-down-from-cursor-over-full-screen 0 *eax 3 0) +264 (draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0 " " 2 0) +265 40/increment-eax +266 (draw-int32-hex-wrapping-right-then-down-from-cursor-over-full-screen 0 *eax 3 0) +267 (draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0 " " 2 0) +268 40/increment-eax +269 (draw-int32-hex-wrapping-right-then-down-from-cursor-over-full-screen 0 *eax 3 0) +270 (draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0 " " 2 0) +271 40/increment-eax +272 (draw-int32-hex-wrapping-right-then-down-from-cursor-over-full-screen 0 *eax 3 0) +273 (draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0 " " 2 0) +274 40/increment-eax +275 (draw-int32-hex-wrapping-right-then-down-from-cursor-over-full-screen 0 *eax 3 0) +276 (draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0 " " 2 0) +277 40/increment-eax +278 (draw-int32-hex-wrapping-right-then-down-from-cursor-over-full-screen 0 *eax 3 0) +279 (draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0 " " 2 0) +280 40/increment-eax +281 (draw-int32-hex-wrapping-right-then-down-from-cursor-over-full-screen 0 *eax 3 0) +282 (abort "\n") +283 # never gets here +284 +285 test-lookup-success: +286 # . prologue +287 55/push-ebp +288 89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp +289 # var ad/ebx: allocation-descriptor containing 16 bytes +290 # . var end/ecx: (addr byte) +291 89/<- %ecx 4/r32/esp +292 # . var start/edx: (addr byte) = end - 16 +293 81 5/subop/subtract %esp 0x10/imm32 +294 89/<- %edx 4/r32/esp +295 # . ad = {start, end} +296 51/push-ecx +297 52/push-edx +298 89/copy 3/mod/direct 3/rm32/ebx . . . 4/r32/esp . . # copy esp to ebx +299 # var handle/ecx: handle +300 68/push 0/imm32/address +301 68/push 0/imm32/alloc-id +302 89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx +303 # var old-top/edx = ad->curr +304 8b/copy 0/mod/indirect 3/rm32/ebx . . . 2/r32/edx . . # copy *ebx to edx +305 # allocate-raw(ad, 2, handle) +306 # . . push args +307 51/push-ecx +308 68/push 2/imm32/size +309 53/push-ebx +310 # . . call +311 e8/call allocate-raw/disp32 +312 # . . discard args +313 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32 # add to esp +314 # eax = lookup(handle) +315 # . . push args +316 ff 6/subop/push 1/mod/*+disp8 1/rm32/ecx . . . . 4/disp8 . # push *(ecx+4) +317 ff 6/subop/push 0/mod/indirect 1/rm32/ecx . . . . . . # push *ecx +318 # . . call +319 e8/call lookup/disp32 +320 # . . discard args +321 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp +322 # eax contains old top of heap, except skipping the alloc-id in the payload +323 # . check-ints-equal(eax, old-top+4, msg) +324 # . . push args +325 68/push "F - test-lookup-success"/imm32 +326 81 0/subop/add 3/mod/direct 2/rm32/edx . . . . . 4/imm32 # add to edx +327 52/push-edx +328 50/push-eax +329 # . . call +330 e8/call check-ints-equal/disp32 +331 # . . discard args +332 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32 # add to esp +333 # clean up +334 c7 0/subop/copy 0/mod/indirect 5/rm32/.disp32 . . . Next-alloc-id/disp32 0x100/imm32 # copy to *Next-alloc-id +335 # . reclaim locals +336 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0x20/imm32 # add to esp +337 # . epilogue +338 89/copy 3/mod/direct 4/rm32/esp . . . 5/r32/ebp . . # copy ebp to esp +339 5d/pop-to-ebp +340 c3/return +341 +342 test-lookup-null-returns-null: +343 # . prologue +344 55/push-ebp +345 89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp +346 # var handle/ecx: handle +347 68/push 0/imm32/address +348 68/push 0/imm32/alloc-id +349 89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx +350 # eax = lookup(handle) +351 # . . push args +352 ff 6/subop/push 1/mod/*+disp8 1/rm32/ecx . . . . 4/disp8 . # push *(ecx+4) +353 ff 6/subop/push 0/mod/indirect 1/rm32/ecx . . . . . . # push *ecx +354 # . . call +355 e8/call lookup/disp32 +356 # . . discard args +357 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp +358 # check-ints-equal(eax, 0, msg) +359 # . . push args +360 68/push "F - test-lookup-null-returns-null"/imm32 +361 68/push 0/imm32 +362 50/push-eax +363 # . . call +364 e8/call check-ints-equal/disp32 +365 # . . discard args +366 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32 # add to esp +367 # . reclaim locals +368 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp +369 # . epilogue +370 89/copy 3/mod/direct 4/rm32/esp . . . 5/r32/ebp . . # copy ebp to esp +371 5d/pop-to-ebp +372 c3/return +373 +374 _pending-test-lookup-failure: +375 # . prologue +376 55/push-ebp +377 89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp +378 # var ad/ecx: allocation-descriptor containing 16 bytes +379 # . var end/ecx: (addr byte) +380 89/<- %ecx 4/r32/esp +381 # . var start/edx: (addr byte) = end - 16 +382 81 5/subop/subtract %esp 0x10/imm32 +383 89/<- %edx 4/r32/esp +384 # . ad = {start, end} +385 51/push-ecx +386 52/push-edx +387 89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx +388 # var h1/ecx: handle +389 68/push 0/imm32/address +390 68/push 0/imm32/alloc-id +391 89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx +392 # var old_top/ebx = ad->curr +393 8b/copy 0/mod/indirect 6/rm32/esi . . . 3/r32/ebx . . # copy *esi to ebx +394 # first allocation, to h1 +395 # . allocate(ad, 2, h1) +396 # . . push args +397 51/push-ecx +398 68/push 2/imm32/size +399 56/push-esi +400 # . . call +401 e8/call allocate/disp32 +402 # . . discard args +403 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32 # add to esp +404 # reset ad->curr to mimic reclamation +405 89/copy 0/mod/indirect 6/rm32/esi . . . 3/r32/ebx . . # copy ebx to *esi +406 # second allocation that returns the same address as the first +407 # var h2/edx: handle +408 68/push 0/imm32/address +409 68/push 0/imm32/alloc-id +410 89/copy 3/mod/direct 2/rm32/edx . . . 4/r32/esp . . # copy esp to edx +411 # . allocate(ad, 2, h2) +412 # . . push args +413 52/push-edx +414 68/push 2/imm32/size +415 56/push-esi +416 # . . call +417 e8/call allocate/disp32 +418 # . . discard args +419 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32 # add to esp +420 # check-ints-equal(h1->address, h2->address, msg) +421 # . . push args +422 68/push "F - test-lookup-failure"/imm32 +423 ff 6/subop/push 1/mod/*+disp8 2/rm32/ecx . . . . 4/disp8 . # push *(edx+4) +424 ff 6/subop/push 1/mod/*+disp8 1/rm32/ecx . . . . 4/disp8 . # push *(ecx+4) +425 # . . call +426 e8/call check-ints-equal/disp32 +427 # . . discard args +428 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32 # add to esp +429 # lookup(h1) should crash +430 # . . push args +431 ff 6/subop/push 1/mod/*+disp8 1/rm32/ecx . . . . 4/disp8 . # push *(ecx+4) +432 ff 6/subop/push 0/mod/indirect 1/rm32/ecx . . . . . . # push *ecx +433 # . . call +434 e8/call lookup/disp32 +435 # should never get past this point +436 # . . discard args +437 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp +438 # clean up +439 c7 0/subop/copy 0/mod/indirect 5/rm32/.disp32 . . . Next-alloc-id/disp32 0x100/imm32 # copy to *Next-alloc-id +440 # . reclaim locals +441 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0x20/imm32 # add to esp +442 # . epilogue +443 89/copy 3/mod/direct 4/rm32/esp . . . 5/r32/ebp . . # copy ebp to esp +444 5d/pop-to-ebp +445 c3/return +446 +447 # when comparing handles, just treat them as pure values +448 handle-equal?: # a: (handle _T), b: (handle _T) -> result/eax: boolean +449 # . prologue +450 55/push-ebp +451 89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp +452 # . save registers +453 51/push-ecx +454 # eax = false +455 b8/copy-to-eax 0/imm32/false +456 $handle-equal?:compare-alloc-id: +457 # ecx = a->alloc_id +458 8b/copy 1/mod/*+disp8 5/rm32/ebp . . . 1/r32/ecx 8/disp8 . # copy *(ebp+8) to ecx +459 # if (ecx != b->alloc_id) return false +460 39/compare 1/mod/*+disp8 5/rm32/ebp . . . 1/r32/ecx 0x10/disp8 . # compare ecx and *(ebp+16) +461 75/jump-if-!= $handle-equal?:end/disp8 +462 $handle-equal?:compare-address: +463 # ecx = handle->address +464 8b/copy 1/mod/*+disp8 5/rm32/ebp . . . 1/r32/ecx 0xc/disp8 . # copy *(ebp+12) to ecx +465 # if (ecx != b->address) return false +466 39/compare 1/mod/*+disp8 5/rm32/ebp . . . 1/r32/ecx 0x14/disp8 . # compare ecx and *(ebp+20) +467 75/jump-if-!= $handle-equal?:end/disp8 +468 $handle-equal?:return-true: +469 # return true +470 b8/copy-to-eax 1/imm32/true +471 $handle-equal?:end: +472 # . restore registers +473 59/pop-to-ecx +474 # . epilogue +475 89/copy 3/mod/direct 4/rm32/esp . . . 5/r32/ebp . . # copy ebp to esp +476 5d/pop-to-ebp +477 c3/return +478 +479 copy-handle: # src: (handle _T), dest: (addr handle _T) 480 # . prologue 481 55/push-ebp 482 89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp 483 # . save registers 484 50/push-eax 485 51/push-ecx -486 # allocate(ad, n, out) -487 # . . push args -488 ff 6/subop/push 1/mod/*+disp8 5/rm32/ebp . . . . 0x10/disp8 . # push *(ebp+16) -489 ff 6/subop/push 1/mod/*+disp8 5/rm32/ebp . . . . 0xc/disp8 . # push *(ebp+12) -490 ff 6/subop/push 1/mod/*+disp8 5/rm32/ebp . . . . 8/disp8 . # push *(ebp+8) -491 # . . call -492 e8/call allocate/disp32 -493 # . . discard args -494 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32 # add to esp -495 # eax = out->payload -496 8b/copy 1/mod/*+disp8 5/rm32/ebp . . . 0/r32/eax 0x10/disp8 . # copy *(ebp+16) to eax -497 8b/copy 1/mod/*+disp8 0/rm32/eax . . . 0/r32/eax 4/disp8 . # copy *(eax+4) to eax -498 # skip payload->allocid -499 05/add-to-eax 4/imm32 -500 # if (eax == 0) abort -501 3d/compare-eax-and 0/imm32 -502 74/jump-if-= $allocate-region:abort/disp8 -503 # earmark 8 bytes at the start for a new allocation descriptor -504 # . *eax = eax + 8 -505 89/copy 3/mod/direct 1/rm32/ecx . . . 0/r32/eax . . # copy eax to ecx -506 81 0/subop/add 3/mod/direct 1/rm32/ecx . . . . . 8/imm32 # add to ecx -507 89/copy 0/mod/indirect 0/rm32/eax . . . 1/r32/ecx . . # copy ecx to *eax -508 # . *(eax+4) = eax + n -509 89/copy 3/mod/direct 1/rm32/ecx . . . 0/r32/eax . . # copy eax to ecx -510 03/add 1/mod/*+disp8 5/rm32/ebp . . . 1/r32/ecx 0xc/disp8 . # add *(ebp+12) to ecx -511 89/copy 1/mod/*+disp8 0/rm32/eax . . . 1/r32/ecx 4/disp8 . # copy ecx to *(eax+4) -512 # . restore registers -513 59/pop-to-ecx -514 58/pop-to-eax -515 # . epilogue -516 89/copy 3/mod/direct 4/rm32/esp . . . 5/r32/ebp . . # copy ebp to esp -517 5d/pop-to-ebp -518 c3/return -519 -520 # We could create a more general '$abort' jump target, but then we'd need to do -521 # a conditional jump followed by loading the error message and an unconditional -522 # jump. Or we'd need to unconditionally load the error message before a -523 # conditional jump, even if it's unused the vast majority of the time. This way -524 # we bloat a potentially cold segment in RAM so we can abort with a single -525 # instruction. -526 $allocate-region:abort: -527 (draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0 "allocate-region: failed to allocate" 3 0) # 3=cyan -528 { -529 eb/jump loop/disp8 -530 } -531 # never gets here -532 -533 # Claim the next 'n+4' bytes of memory and initialize the first 4 to n. -534 # Abort if there isn't enough memory in 'ad'. -535 allocate-array: # ad: (addr allocation-descriptor), n: int, out: (addr handle _) -536 # . prologue -537 55/push-ebp -538 89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp -539 # . save registers -540 50/push-eax -541 51/push-ecx -542 52/push-edx -543 # ecx = n -544 8b/copy 1/mod/*+disp8 5/rm32/ebp . . . 1/r32/ecx 0xc/disp8 . # copy *(ebp+12) to ecx -545 # var size/edx: int = n+4 -546 8d/copy-address 1/mod/*+disp8 1/rm32/ecx . . . 2/r32/edx 4/disp8 . # copy ecx+4 to edx -547 # allocate(ad, size, out) -548 # . . push args -549 ff 6/subop/push 1/mod/*+disp8 5/rm32/ebp . . . . 0x10/disp8 . # push *(ebp+16) -550 52/push-edx -551 ff 6/subop/push 1/mod/*+disp8 5/rm32/ebp . . . . 8/disp8 . # push *(ebp+8) -552 # . . call -553 e8/call allocate/disp32 -554 # . . discard args -555 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32 # add to esp -556 # *out->payload = n -557 8b/copy 1/mod/*+disp8 5/rm32/ebp . . . 0/r32/eax 0x10/disp8 . # copy *(ebp+16) to eax -558 8b/copy 1/mod/*+disp8 0/rm32/eax . . . 0/r32/eax 4/disp8 . # copy *(eax+4) to eax -559 # . skip payload->allocid -560 05/add-to-eax 4/imm32 -561 # . -562 89/copy 0/mod/indirect 0/rm32/eax . . . 1/r32/ecx . . # copy ecx to *eax -563 $allocate-array:end: -564 # . restore registers -565 5a/pop-to-edx -566 59/pop-to-ecx -567 58/pop-to-eax -568 # . epilogue -569 89/copy 3/mod/direct 4/rm32/esp . . . 5/r32/ebp . . # copy ebp to esp -570 5d/pop-to-ebp -571 c3/return -572 -573 test-allocate-array: -574 # . prologue -575 55/push-ebp -576 89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp -577 # var ad/ecx: allocation-descriptor containing 16 bytes -578 # . var end/ecx: (addr byte) -579 89/<- %ecx 4/r32/esp -580 # . var start/edx: (addr byte) = end - 16 -581 81 5/subop/subtract %esp 0x10/imm32 -582 89/<- %edx 4/r32/esp -583 # . ad = {start, end} -584 51/push-ecx -585 52/push-edx -586 89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx -587 # var expected-payload/ebx = ad->curr -588 8b/copy 0/mod/indirect 1/rm32/ecx . . . 3/r32/ebx . . # copy *ecx to ebx -589 # var h/edx: handle = {0, 0} -590 68/push 0/imm32 -591 68/push 0/imm32 -592 89/copy 3/mod/direct 2/rm32/edx . . . 4/r32/esp . . # copy esp to edx -593 # *Next-alloc-id = 0x34 -594 c7 0/subop/copy 0/mod/indirect 5/rm32/.disp32 . . . Next-alloc-id/disp32 0x34/imm32 # copy to *Next-alloc-id -595 # allocate-array(ad, 3, h) -596 # . . push args -597 52/push-edx -598 68/push 3/imm32 -599 51/push-ecx -600 # . . call -601 e8/call allocate-array/disp32 -602 # . . discard args -603 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32 # add to esp -604 # check-ints-equal(h->alloc-id, 0x34, msg) -605 # . . push args -606 68/push "F - test-allocate-array: sets alloc-id in handle"/imm32 -607 68/push 0x34/imm32 -608 ff 6/subop/push 0/mod/indirect 2/rm32/edx . . . . . . # push *edx -609 # . . call -610 e8/call check-ints-equal/disp32 -611 # . . discard args -612 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32 # add to esp -613 # check-ints-equal(h->payload, expected-payload, msg) -614 # . . push args -615 68/push "F - test-allocate-array: sets payload in handle"/imm32 -616 53/push-ebx -617 ff 6/subop/push 1/mod/*+disp8 2/rm32/edx . . . . 4/disp8 . # push *(edx+4) -618 # . . call -619 e8/call check-ints-equal/disp32 -620 # . . discard args -621 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32 # add to esp -622 # check-ints-equal(h->payload->alloc-id, 0x34, msg) -623 # . . push args -624 68/push "F - test-allocate-array: sets alloc-id in payload"/imm32 -625 68/push 0x34/imm32 -626 ff 6/subop/push 0/mod/indirect 3/rm32/ebx . . . . . . # push *ebx -627 # . . call -628 e8/call check-ints-equal/disp32 -629 # . . discard args -630 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32 # add to esp -631 # check-ints-equal(h->payload->size, 3, msg) -632 # . . push args -633 68/push "F - test-allocate-array: sets array size in payload"/imm32 -634 68/push 3/imm32 -635 ff 6/subop/push 1/mod/*+disp8 3/rm32/ebx . . . . 4/disp8 . # push *(ebx+4) -636 # . . call -637 e8/call check-ints-equal/disp32 -638 # . . discard args -639 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32 # add to esp -640 # check-ints-equal(*Next-alloc-id, 0x35, msg) -641 # . . push args -642 68/push "F - test-allocate-array: increments Next-alloc-id"/imm32 -643 68/push 0x35/imm32 -644 ff 6/subop/push 0/mod/indirect 5/rm32/.disp32 . . . Next-alloc-id/disp32 # push *Next-alloc-id -645 # . . call -646 e8/call check-ints-equal/disp32 -647 # . . discard args -648 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32 # add to esp -649 # check-ints-equal(ad->curr - expected-payload, 3 + 4 for alloc-id + 4 for array size, msg) -650 # . . push args -651 68/push "F - test-allocate-array: updates allocation descriptor"/imm32 -652 68/push 0xb/imm32 -653 8b/copy 0/mod/indirect 1/rm32/ecx . . . 0/r32/eax . . # copy *ecx to eax -654 29/subtract 3/mod/direct 0/rm32/eax . . . 3/r32/ebx . . # subtract ebx from eax -655 50/push-eax -656 # . . call -657 e8/call check-ints-equal/disp32 -658 # . . discard args -659 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32 # add to esp -660 # clean up -661 c7 0/subop/copy 0/mod/indirect 5/rm32/.disp32 . . . Next-alloc-id/disp32 1/imm32 # copy to *Next-alloc-id -662 # . reclaim locals -663 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0x20/imm32 # add to esp -664 # . epilogue -665 89/copy 3/mod/direct 4/rm32/esp . . . 5/r32/ebp . . # copy ebp to esp -666 5d/pop-to-ebp -667 c3/return -668 -669 copy-array: # ad: (addr allocation-descriptor), src: (addr array _T), out: (addr handle array _T) -670 # . prologue -671 55/push-ebp -672 89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp -673 # . save registers -674 50/push-eax -675 51/push-ecx -676 52/push-edx -677 56/push-esi -678 # esi = src -679 8b/copy 1/mod/*+disp8 5/rm32/ebp . . . 6/r32/esi 0xc/disp8 . # copy *(ebp+12) to esi -680 # var size/ecx: int = src->size+4 -681 8b/copy 0/mod/indirect 6/rm32/esi . . . 1/r32/ecx . . # copy *esi to ecx -682 81 0/subop/add 3/mod/direct 1/rm32/ecx . . . . . 4/imm32 # add to ecx -683 # allocate(ad, size, out) -684 # . . push args -685 ff 6/subop/push 1/mod/*+disp8 5/rm32/ebp . . . . 0x10/disp8 . # push *(ebp+16) -686 51/push-ecx -687 ff 6/subop/push 1/mod/*+disp8 5/rm32/ebp . . . . 8/disp8 . # push *(ebp+8) -688 # . . call -689 e8/call allocate/disp32 -690 # . . discard args -691 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32 # add to esp -692 # var payload/eax: (addr byte) = out->payload -693 8b/copy 1/mod/*+disp8 5/rm32/ebp . . . 0/r32/eax 0x10/disp8 . # copy *(ebp+16) to eax -694 8b/copy 1/mod/*+disp8 0/rm32/eax . . . 0/r32/eax 4/disp8 . # copy *(eax+4) to eax -695 # . skip payload->allocid -696 05/add-to-eax 4/imm32 -697 # var max/ecx: (addr byte) = payload + size -698 01/add 3/mod/direct 1/rm32/ecx . . . 0/r32/eax . . # add eax to ecx -699 # _append-4(payload, max, src, &src->data[src->size]) -700 # . . push &src->data[src->size] -701 8b/copy 0/mod/indirect 6/rm32/esi . . . 2/r32/edx . . # copy *esi to edx -702 8d/copy-address 1/mod/*+disp8 4/rm32/sib 6/base/esi 2/index/edx . 2/r32/edx 4/disp8 . # copy esi+edx+4 to edx -703 52/push-edx -704 # . . push src -705 56/push-esi -706 # . . push max +486 # ecx = dest +487 8b/copy 1/mod/*+disp8 5/rm32/ebp . . . 1/r32/ecx 0x10/disp8 . # copy *(ebp+16) to ecx +488 # *dest = src +489 8b/copy 1/mod/*+disp8 5/rm32/ebp . . . 0/r32/eax 8/disp8 . # copy *(ebp+8) to eax +490 89/copy 0/mod/indirect 1/rm32/ecx . . . 0/r32/eax . . # copy eax to *ecx +491 8b/copy 1/mod/*+disp8 5/rm32/ebp . . . 0/r32/eax 0xc/disp8 . # copy *(ebp+12) to eax +492 89/copy 1/mod/*+disp8 1/rm32/ecx . . . 0/r32/eax 4/disp8 . # copy eax to *(ecx+4) +493 $copy-handle:end: +494 # . restore registers +495 59/pop-to-ecx +496 58/pop-to-eax +497 # . epilogue +498 89/copy 3/mod/direct 4/rm32/esp . . . 5/r32/ebp . . # copy ebp to esp +499 5d/pop-to-ebp +500 c3/return +501 +502 # helper: create a nested allocation descriptor (useful for tests) +503 allocate-region: # ad: (addr allocation-descriptor), n: int, out: (addr handle allocation-descriptor) +504 # . prologue +505 55/push-ebp +506 89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp +507 # . save registers +508 50/push-eax +509 51/push-ecx +510 # allocate(ad, n, out) +511 # . . push args +512 ff 6/subop/push 1/mod/*+disp8 5/rm32/ebp . . . . 0x10/disp8 . # push *(ebp+16) +513 ff 6/subop/push 1/mod/*+disp8 5/rm32/ebp . . . . 0xc/disp8 . # push *(ebp+12) +514 ff 6/subop/push 1/mod/*+disp8 5/rm32/ebp . . . . 8/disp8 . # push *(ebp+8) +515 # . . call +516 e8/call allocate/disp32 +517 # . . discard args +518 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32 # add to esp +519 # eax = out->payload +520 8b/copy 1/mod/*+disp8 5/rm32/ebp . . . 0/r32/eax 0x10/disp8 . # copy *(ebp+16) to eax +521 8b/copy 1/mod/*+disp8 0/rm32/eax . . . 0/r32/eax 4/disp8 . # copy *(eax+4) to eax +522 # skip payload->allocid +523 05/add-to-eax 4/imm32 +524 # if (eax == 0) abort +525 3d/compare-eax-and 0/imm32 +526 74/jump-if-= $allocate-region:abort/disp8 +527 # earmark 8 bytes at the start for a new allocation descriptor +528 # . *eax = eax + 8 +529 89/copy 3/mod/direct 1/rm32/ecx . . . 0/r32/eax . . # copy eax to ecx +530 81 0/subop/add 3/mod/direct 1/rm32/ecx . . . . . 8/imm32 # add to ecx +531 89/copy 0/mod/indirect 0/rm32/eax . . . 1/r32/ecx . . # copy ecx to *eax +532 # . *(eax+4) = eax + n +533 89/copy 3/mod/direct 1/rm32/ecx . . . 0/r32/eax . . # copy eax to ecx +534 03/add 1/mod/*+disp8 5/rm32/ebp . . . 1/r32/ecx 0xc/disp8 . # add *(ebp+12) to ecx +535 89/copy 1/mod/*+disp8 0/rm32/eax . . . 1/r32/ecx 4/disp8 . # copy ecx to *(eax+4) +536 # . restore registers +537 59/pop-to-ecx +538 58/pop-to-eax +539 # . epilogue +540 89/copy 3/mod/direct 4/rm32/esp . . . 5/r32/ebp . . # copy ebp to esp +541 5d/pop-to-ebp +542 c3/return +543 +544 # We could create a more general '$abort' jump target, but then we'd need to do +545 # a conditional jump followed by loading the error message and an unconditional +546 # jump. Or we'd need to unconditionally load the error message before a +547 # conditional jump, even if it's unused the vast majority of the time. This way +548 # we bloat a potentially cold segment in RAM so we can abort with a single +549 # instruction. +550 $allocate-region:abort: +551 (abort "allocate-region: failed to allocate") +552 # never gets here +553 +554 # Claim the next 'n+4' bytes of memory and initialize the first 4 to n. +555 # Abort if there isn't enough memory in 'ad'. +556 allocate-array: # ad: (addr allocation-descriptor), n: int, out: (addr handle _) +557 # . prologue +558 55/push-ebp +559 89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp +560 # . save registers +561 50/push-eax +562 51/push-ecx +563 52/push-edx +564 # ecx = n +565 8b/copy 1/mod/*+disp8 5/rm32/ebp . . . 1/r32/ecx 0xc/disp8 . # copy *(ebp+12) to ecx +566 # var size/edx: int = n+4 +567 8d/copy-address 1/mod/*+disp8 1/rm32/ecx . . . 2/r32/edx 4/disp8 . # copy ecx+4 to edx +568 # allocate(ad, size, out) +569 # . . push args +570 ff 6/subop/push 1/mod/*+disp8 5/rm32/ebp . . . . 0x10/disp8 . # push *(ebp+16) +571 52/push-edx +572 ff 6/subop/push 1/mod/*+disp8 5/rm32/ebp . . . . 8/disp8 . # push *(ebp+8) +573 # . . call +574 e8/call allocate/disp32 +575 # . . discard args +576 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32 # add to esp +577 # *out->payload = n +578 8b/copy 1/mod/*+disp8 5/rm32/ebp . . . 0/r32/eax 0x10/disp8 . # copy *(ebp+16) to eax +579 8b/copy 1/mod/*+disp8 0/rm32/eax . . . 0/r32/eax 4/disp8 . # copy *(eax+4) to eax +580 # . skip payload->allocid +581 05/add-to-eax 4/imm32 +582 # . +583 89/copy 0/mod/indirect 0/rm32/eax . . . 1/r32/ecx . . # copy ecx to *eax +584 $allocate-array:end: +585 # . restore registers +586 5a/pop-to-edx +587 59/pop-to-ecx +588 58/pop-to-eax +589 # . epilogue +590 89/copy 3/mod/direct 4/rm32/esp . . . 5/r32/ebp . . # copy ebp to esp +591 5d/pop-to-ebp +592 c3/return +593 +594 test-allocate-array: +595 # . prologue +596 55/push-ebp +597 89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp +598 # var ad/ecx: allocation-descriptor containing 16 bytes +599 # . var end/ecx: (addr byte) +600 89/<- %ecx 4/r32/esp +601 # . var start/edx: (addr byte) = end - 16 +602 81 5/subop/subtract %esp 0x10/imm32 +603 89/<- %edx 4/r32/esp +604 # . ad = {start, end} +605 51/push-ecx +606 52/push-edx +607 89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx +608 # var expected-payload/ebx = ad->curr +609 8b/copy 0/mod/indirect 1/rm32/ecx . . . 3/r32/ebx . . # copy *ecx to ebx +610 # var h/edx: handle = {0, 0} +611 68/push 0/imm32 +612 68/push 0/imm32 +613 89/copy 3/mod/direct 2/rm32/edx . . . 4/r32/esp . . # copy esp to edx +614 # *Next-alloc-id = 0x34 +615 c7 0/subop/copy 0/mod/indirect 5/rm32/.disp32 . . . Next-alloc-id/disp32 0x34/imm32 # copy to *Next-alloc-id +616 # allocate-array(ad, 3, h) +617 # . . push args +618 52/push-edx +619 68/push 3/imm32 +620 51/push-ecx +621 # . . call +622 e8/call allocate-array/disp32 +623 # . . discard args +624 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32 # add to esp +625 # check-ints-equal(h->alloc-id, 0x34, msg) +626 # . . push args +627 68/push "F - test-allocate-array: sets alloc-id in handle"/imm32 +628 68/push 0x34/imm32 +629 ff 6/subop/push 0/mod/indirect 2/rm32/edx . . . . . . # push *edx +630 # . . call +631 e8/call check-ints-equal/disp32 +632 # . . discard args +633 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32 # add to esp +634 # check-ints-equal(h->payload, expected-payload, msg) +635 # . . push args +636 68/push "F - test-allocate-array: sets payload in handle"/imm32 +637 53/push-ebx +638 ff 6/subop/push 1/mod/*+disp8 2/rm32/edx . . . . 4/disp8 . # push *(edx+4) +639 # . . call +640 e8/call check-ints-equal/disp32 +641 # . . discard args +642 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32 # add to esp +643 # check-ints-equal(h->payload->alloc-id, 0x34, msg) +644 # . . push args +645 68/push "F - test-allocate-array: sets alloc-id in payload"/imm32 +646 68/push 0x34/imm32 +647 ff 6/subop/push 0/mod/indirect 3/rm32/ebx . . . . . . # push *ebx +648 # . . call +649 e8/call check-ints-equal/disp32 +650 # . . discard args +651 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32 # add to esp +652 # check-ints-equal(h->payload->size, 3, msg) +653 # . . push args +654 68/push "F - test-allocate-array: sets array size in payload"/imm32 +655 68/push 3/imm32 +656 ff 6/subop/push 1/mod/*+disp8 3/rm32/ebx . . . . 4/disp8 . # push *(ebx+4) +657 # . . call +658 e8/call check-ints-equal/disp32 +659 # . . discard args +660 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32 # add to esp +661 # check-ints-equal(*Next-alloc-id, 0x35, msg) +662 # . . push args +663 68/push "F - test-allocate-array: increments Next-alloc-id"/imm32 +664 68/push 0x35/imm32 +665 ff 6/subop/push 0/mod/indirect 5/rm32/.disp32 . . . Next-alloc-id/disp32 # push *Next-alloc-id +666 # . . call +667 e8/call check-ints-equal/disp32 +668 # . . discard args +669 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32 # add to esp +670 # check-ints-equal(ad->curr - expected-payload, 3 + 4 for alloc-id + 4 for array size, msg) +671 # . . push args +672 68/push "F - test-allocate-array: updates allocation descriptor"/imm32 +673 68/push 0xb/imm32 +674 8b/copy 0/mod/indirect 1/rm32/ecx . . . 0/r32/eax . . # copy *ecx to eax +675 29/subtract 3/mod/direct 0/rm32/eax . . . 3/r32/ebx . . # subtract ebx from eax +676 50/push-eax +677 # . . call +678 e8/call check-ints-equal/disp32 +679 # . . discard args +680 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32 # add to esp +681 # clean up +682 c7 0/subop/copy 0/mod/indirect 5/rm32/.disp32 . . . Next-alloc-id/disp32 1/imm32 # copy to *Next-alloc-id +683 # . reclaim locals +684 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0x20/imm32 # add to esp +685 # . epilogue +686 89/copy 3/mod/direct 4/rm32/esp . . . 5/r32/ebp . . # copy ebp to esp +687 5d/pop-to-ebp +688 c3/return +689 +690 copy-array: # ad: (addr allocation-descriptor), src: (addr array _T), out: (addr handle array _T) +691 # . prologue +692 55/push-ebp +693 89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp +694 # . save registers +695 50/push-eax +696 51/push-ecx +697 52/push-edx +698 56/push-esi +699 # esi = src +700 8b/copy 1/mod/*+disp8 5/rm32/ebp . . . 6/r32/esi 0xc/disp8 . # copy *(ebp+12) to esi +701 # var size/ecx: int = src->size+4 +702 8b/copy 0/mod/indirect 6/rm32/esi . . . 1/r32/ecx . . # copy *esi to ecx +703 81 0/subop/add 3/mod/direct 1/rm32/ecx . . . . . 4/imm32 # add to ecx +704 # allocate(ad, size, out) +705 # . . push args +706 ff 6/subop/push 1/mod/*+disp8 5/rm32/ebp . . . . 0x10/disp8 . # push *(ebp+16) 707 51/push-ecx -708 # . . push payload -709 50/push-eax -710 # . . call -711 e8/call _append-4/disp32 -712 # . . discard args -713 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0x10/imm32 # add to esp -714 $copy-array:end: -715 # . restore registers -716 5e/pop-to-esi -717 5a/pop-to-edx -718 59/pop-to-ecx -719 58/pop-to-eax -720 # . epilogue -721 89/copy 3/mod/direct 4/rm32/esp . . . 5/r32/ebp . . # copy ebp to esp -722 5d/pop-to-ebp -723 c3/return -724 -725 test-copy-array: -726 # . prologue -727 55/push-ebp -728 89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp -729 # var src/esi: (addr array int) = [3, 4, 5] -730 68/push 5/imm32 -731 68/push 4/imm32 -732 68/push 3/imm32 -733 68/push 0xc/imm32/size -734 89/copy 3/mod/direct 6/rm32/esi . . . 4/r32/esp . . # copy esp to esi -735 # var ad/ecx: allocation-descriptor containing 32 bytes -736 # . var end/ecx: (addr byte) -737 89/<- %ecx 4/r32/esp -738 # . var start/edx: (addr byte) = end - 32 -739 81 5/subop/subtract %esp 0x20/imm32 -740 89/<- %edx 4/r32/esp -741 # . ad = {start, end} -742 51/push-ecx -743 52/push-edx -744 89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx -745 # var expected-payload/ebx = ad->curr -746 8b/copy 0/mod/indirect 1/rm32/ecx . . . 3/r32/ebx . . # copy *ecx to ebx -747 # var h/edx: handle = {0, 0} -748 68/push 0/imm32 -749 68/push 0/imm32 -750 89/copy 3/mod/direct 2/rm32/edx . . . 4/r32/esp . . # copy esp to edx -751 # *Next-alloc-id = 0x34 -752 c7 0/subop/copy 0/mod/indirect 5/rm32/.disp32 . . . Next-alloc-id/disp32 0x34/imm32 # copy to *Next-alloc-id -753 # copy-array(ad, src, h) -754 # . . push args -755 52/push-edx -756 56/push-esi -757 51/push-ecx -758 # . . call -759 e8/call copy-array/disp32 -760 # . . discard args -761 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32 # add to esp -762 # check-ints-equal(h->alloc-id, 0x34, msg) -763 # . . push args -764 68/push "F - test-copy-array: sets alloc-id in handle"/imm32 -765 68/push 0x34/imm32 -766 ff 6/subop/push 0/mod/indirect 2/rm32/edx . . . . . . # push *edx -767 # . . call -768 e8/call check-ints-equal/disp32 -769 # . . discard args -770 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32 # add to esp -771 # check-ints-equal(h->payload, expected-payload, msg) -772 # . . push args -773 68/push "F - test-copy-array: sets payload in handle"/imm32 -774 53/push-ebx -775 ff 6/subop/push 1/mod/*+disp8 2/rm32/edx . . . . 4/disp8 . # push *(edx+4) -776 # . . call -777 e8/call check-ints-equal/disp32 -778 # . . discard args -779 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32 # add to esp -780 # check-ints-equal(h->payload->alloc-id, 0x34, msg) -781 # . . push args -782 68/push "F - test-copy-array: sets alloc-id in payload"/imm32 -783 68/push 0x34/imm32 -784 ff 6/subop/push 0/mod/indirect 2/rm32/edx . . . . . . # push *edx -785 # . . call -786 e8/call check-ints-equal/disp32 -787 # . . discard args -788 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32 # add to esp -789 # var payload/eax: (addr int) = lookup(h) -790 # . . push args -791 ff 6/subop/push 1/mod/*+disp8 2/rm32/edx . . . . 4/disp8 . # push *(edx+4) -792 ff 6/subop/push 0/mod/indirect 2/rm32/edx . . . . . . # push *edx -793 # . . call -794 e8/call lookup/disp32 -795 # . . discard args -796 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp -797 # check-ints-equal(payload->size, 0xc, msg) -798 # . . push args -799 68/push "F - test-copy-array: sets array size in payload"/imm32 -800 68/push 0xc/imm32 -801 ff 6/subop/push 0/mod/indirect 0/rm32/eax . . . . . . # push *eax -802 # . . call -803 e8/call check-ints-equal/disp32 -804 # . . discard args -805 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32 # add to esp -806 # check-ints-equal(*Next-alloc-id, 0x35, msg) -807 # . . push args -808 68/push "F - test-copy-array: increments Next-alloc-id"/imm32 -809 68/push 0x35/imm32 -810 ff 6/subop/push 0/mod/indirect 5/rm32/.disp32 . . . Next-alloc-id/disp32 # push *Next-alloc-id -811 # . . call -812 e8/call check-ints-equal/disp32 -813 # . . discard args -814 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32 # add to esp -815 # check-ints-equal(ad->curr - expected-payload, 12 + 4 for alloc-id + 4 for size, msg) -816 # . . push args -817 68/push "F - test-copy-array: updates allocation descriptor"/imm32 -818 68/push 0x14/imm32 -819 8b/copy 0/mod/indirect 1/rm32/ecx . . . 0/r32/eax . . # copy *ecx to eax -820 29/subtract 3/mod/direct 0/rm32/eax . . . 3/r32/ebx . . # subtract ebx from eax -821 50/push-eax -822 # . . call -823 e8/call check-ints-equal/disp32 -824 # . . discard args -825 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32 # add to esp -826 # clean up -827 c7 0/subop/copy 0/mod/indirect 5/rm32/.disp32 . . . Next-alloc-id/disp32 1/imm32 # copy to *Next-alloc-id -828 # . reclaim locals -829 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0x40/imm32 # add to esp -830 # . epilogue -831 89/copy 3/mod/direct 4/rm32/esp . . . 5/r32/ebp . . # copy ebp to esp -832 5d/pop-to-ebp -833 c3/return -834 -835 # Fill a region of memory with zeroes. -836 zero-out: # start: (addr byte), size: int -837 # pseudocode: -838 # curr/esi = start -839 # i/ecx = 0 -840 # while true -841 # if (i >= size) break -842 # *curr = 0 -843 # ++curr -844 # ++i -845 # -846 # . prologue -847 55/push-ebp -848 89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp -849 # . save registers -850 50/push-eax -851 51/push-ecx -852 52/push-edx -853 56/push-esi -854 # curr/esi = start -855 8b/copy 1/mod/*+disp8 5/rm32/ebp . . . 6/r32/esi 8/disp8 . # copy *(ebp+8) to esi -856 # var i/ecx: int = 0 -857 31/xor 3/mod/direct 1/rm32/ecx . . . 1/r32/ecx . . # clear ecx -858 # edx = size -859 8b/copy 1/mod/*+disp8 5/rm32/ebp . . . 2/r32/edx 0xc/disp8 . # copy *(ebp+12) to edx -860 $zero-out:loop: -861 # if (i >= size) break -862 39/compare 3/mod/direct 1/rm32/ecx . . . 2/r32/edx . . # compare ecx with edx -863 7d/jump-if->= $zero-out:end/disp8 -864 # *curr = 0 -865 c6 0/subop/copy-byte 0/mod/direct 6/rm32/esi . . . . . 0/imm8 # copy byte to *esi -866 # ++curr -867 46/increment-esi -868 # ++i -869 41/increment-ecx -870 eb/jump $zero-out:loop/disp8 -871 $zero-out:end: -872 # . restore registers -873 5e/pop-to-esi -874 5a/pop-to-edx -875 59/pop-to-ecx -876 58/pop-to-eax -877 # . epilogue -878 89/copy 3/mod/direct 4/rm32/esp . . . 5/r32/ebp . . # copy ebp to esp -879 5d/pop-to-ebp -880 c3/return -881 -882 test-zero-out: -883 # . prologue -884 55/push-ebp -885 89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp -886 # region/ecx = 34, 35, 36, 37 -887 68/push 0x37363534/imm32 -888 89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx -889 # zero-out(ecx, 3) -890 # . . push args -891 68/push 3/imm32/size -892 51/push-ecx -893 # . . call -894 e8/call zero-out/disp32 -895 # . . discard args -896 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp -897 # first 3 bytes cleared, fourth left alone -898 # . check-ints-equal(*ecx, 0x37000000, msg) -899 # . . push args -900 68/push "F - test-zero-out"/imm32 -901 68/push 0x37000000/imm32 -902 ff 6/subop/push 0/mod/indirect 1/rm32/ecx . . . . . . # push *ecx -903 # . . call -904 e8/call check-ints-equal/disp32 -905 # . . discard args -906 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32 # add to esp -907 # . reclaim locals -908 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp -909 # . epilogue -910 89/copy 3/mod/direct 4/rm32/esp . . . 5/r32/ebp . . # copy ebp to esp -911 5d/pop-to-ebp -912 c3/return -913 -914 # . . vim:nowrap:textwidth=0 +708 ff 6/subop/push 1/mod/*+disp8 5/rm32/ebp . . . . 8/disp8 . # push *(ebp+8) +709 # . . call +710 e8/call allocate/disp32 +711 # . . discard args +712 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32 # add to esp +713 # var payload/eax: (addr byte) = out->payload +714 8b/copy 1/mod/*+disp8 5/rm32/ebp . . . 0/r32/eax 0x10/disp8 . # copy *(ebp+16) to eax +715 8b/copy 1/mod/*+disp8 0/rm32/eax . . . 0/r32/eax 4/disp8 . # copy *(eax+4) to eax +716 # . skip payload->allocid +717 05/add-to-eax 4/imm32 +718 # var max/ecx: (addr byte) = payload + size +719 01/add 3/mod/direct 1/rm32/ecx . . . 0/r32/eax . . # add eax to ecx +720 # _append-4(payload, max, src, &src->data[src->size]) +721 # . . push &src->data[src->size] +722 8b/copy 0/mod/indirect 6/rm32/esi . . . 2/r32/edx . . # copy *esi to edx +723 8d/copy-address 1/mod/*+disp8 4/rm32/sib 6/base/esi 2/index/edx . 2/r32/edx 4/disp8 . # copy esi+edx+4 to edx +724 52/push-edx +725 # . . push src +726 56/push-esi +727 # . . push max +728 51/push-ecx +729 # . . push payload +730 50/push-eax +731 # . . call +732 e8/call _append-4/disp32 +733 # . . discard args +734 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0x10/imm32 # add to esp +735 $copy-array:end: +736 # . restore registers +737 5e/pop-to-esi +738 5a/pop-to-edx +739 59/pop-to-ecx +740 58/pop-to-eax +741 # . epilogue +742 89/copy 3/mod/direct 4/rm32/esp . . . 5/r32/ebp . . # copy ebp to esp +743 5d/pop-to-ebp +744 c3/return +745 +746 test-copy-array: +747 # . prologue +748 55/push-ebp +749 89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp +750 # var src/esi: (addr array int) = [3, 4, 5] +751 68/push 5/imm32 +752 68/push 4/imm32 +753 68/push 3/imm32 +754 68/push 0xc/imm32/size +755 89/copy 3/mod/direct 6/rm32/esi . . . 4/r32/esp . . # copy esp to esi +756 # var ad/ecx: allocation-descriptor containing 32 bytes +757 # . var end/ecx: (addr byte) +758 89/<- %ecx 4/r32/esp +759 # . var start/edx: (addr byte) = end - 32 +760 81 5/subop/subtract %esp 0x20/imm32 +761 89/<- %edx 4/r32/esp +762 # . ad = {start, end} +763 51/push-ecx +764 52/push-edx +765 89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx +766 # var expected-payload/ebx = ad->curr +767 8b/copy 0/mod/indirect 1/rm32/ecx . . . 3/r32/ebx . . # copy *ecx to ebx +768 # var h/edx: handle = {0, 0} +769 68/push 0/imm32 +770 68/push 0/imm32 +771 89/copy 3/mod/direct 2/rm32/edx . . . 4/r32/esp . . # copy esp to edx +772 # *Next-alloc-id = 0x34 +773 c7 0/subop/copy 0/mod/indirect 5/rm32/.disp32 . . . Next-alloc-id/disp32 0x34/imm32 # copy to *Next-alloc-id +774 # copy-array(ad, src, h) +775 # . . push args +776 52/push-edx +777 56/push-esi +778 51/push-ecx +779 # . . call +780 e8/call copy-array/disp32 +781 # . . discard args +782 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32 # add to esp +783 # check-ints-equal(h->alloc-id, 0x34, msg) +784 # . . push args +785 68/push "F - test-copy-array: sets alloc-id in handle"/imm32 +786 68/push 0x34/imm32 +787 ff 6/subop/push 0/mod/indirect 2/rm32/edx . . . . . . # push *edx +788 # . . call +789 e8/call check-ints-equal/disp32 +790 # . . discard args +791 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32 # add to esp +792 # check-ints-equal(h->payload, expected-payload, msg) +793 # . . push args +794 68/push "F - test-copy-array: sets payload in handle"/imm32 +795 53/push-ebx +796 ff 6/subop/push 1/mod/*+disp8 2/rm32/edx . . . . 4/disp8 . # push *(edx+4) +797 # . . call +798 e8/call check-ints-equal/disp32 +799 # . . discard args +800 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32 # add to esp +801 # check-ints-equal(h->payload->alloc-id, 0x34, msg) +802 # . . push args +803 68/push "F - test-copy-array: sets alloc-id in payload"/imm32 +804 68/push 0x34/imm32 +805 ff 6/subop/push 0/mod/indirect 2/rm32/edx . . . . . . # push *edx +806 # . . call +807 e8/call check-ints-equal/disp32 +808 # . . discard args +809 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32 # add to esp +810 # var payload/eax: (addr int) = lookup(h) +811 # . . push args +812 ff 6/subop/push 1/mod/*+disp8 2/rm32/edx . . . . 4/disp8 . # push *(edx+4) +813 ff 6/subop/push 0/mod/indirect 2/rm32/edx . . . . . . # push *edx +814 # . . call +815 e8/call lookup/disp32 +816 # . . discard args +817 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp +818 # check-ints-equal(payload->size, 0xc, msg) +819 # . . push args +820 68/push "F - test-copy-array: sets array size in payload"/imm32 +821 68/push 0xc/imm32 +822 ff 6/subop/push 0/mod/indirect 0/rm32/eax . . . . . . # push *eax +823 # . . call +824 e8/call check-ints-equal/disp32 +825 # . . discard args +826 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32 # add to esp +827 # check-ints-equal(*Next-alloc-id, 0x35, msg) +828 # . . push args +829 68/push "F - test-copy-array: increments Next-alloc-id"/imm32 +830 68/push 0x35/imm32 +831 ff 6/subop/push 0/mod/indirect 5/rm32/.disp32 . . . Next-alloc-id/disp32 # push *Next-alloc-id +832 # . . call +833 e8/call check-ints-equal/disp32 +834 # . . discard args +835 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32 # add to esp +836 # check-ints-equal(ad->curr - expected-payload, 12 + 4 for alloc-id + 4 for size, msg) +837 # . . push args +838 68/push "F - test-copy-array: updates allocation descriptor"/imm32 +839 68/push 0x14/imm32 +840 8b/copy 0/mod/indirect 1/rm32/ecx . . . 0/r32/eax . . # copy *ecx to eax +841 29/subtract 3/mod/direct 0/rm32/eax . . . 3/r32/ebx . . # subtract ebx from eax +842 50/push-eax +843 # . . call +844 e8/call check-ints-equal/disp32 +845 # . . discard args +846 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32 # add to esp +847 # clean up +848 c7 0/subop/copy 0/mod/indirect 5/rm32/.disp32 . . . Next-alloc-id/disp32 1/imm32 # copy to *Next-alloc-id +849 # . reclaim locals +850 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0x40/imm32 # add to esp +851 # . epilogue +852 89/copy 3/mod/direct 4/rm32/esp . . . 5/r32/ebp . . # copy ebp to esp +853 5d/pop-to-ebp +854 c3/return +855 +856 # Fill a region of memory with zeroes. +857 zero-out: # start: (addr byte), size: int +858 # pseudocode: +859 # curr/esi = start +860 # i/ecx = 0 +861 # while true +862 # if (i >= size) break +863 # *curr = 0 +864 # ++curr +865 # ++i +866 # +867 # . prologue +868 55/push-ebp +869 89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp +870 # . save registers +871 50/push-eax +872 51/push-ecx +873 52/push-edx +874 56/push-esi +875 # curr/esi = start +876 8b/copy 1/mod/*+disp8 5/rm32/ebp . . . 6/r32/esi 8/disp8 . # copy *(ebp+8) to esi +877 # var i/ecx: int = 0 +878 31/xor 3/mod/direct 1/rm32/ecx . . . 1/r32/ecx . . # clear ecx +879 # edx = size +880 8b/copy 1/mod/*+disp8 5/rm32/ebp . . . 2/r32/edx 0xc/disp8 . # copy *(ebp+12) to edx +881 $zero-out:loop: +882 # if (i >= size) break +883 39/compare 3/mod/direct 1/rm32/ecx . . . 2/r32/edx . . # compare ecx with edx +884 7d/jump-if->= $zero-out:end/disp8 +885 # *curr = 0 +886 c6 0/subop/copy-byte 0/mod/direct 6/rm32/esi . . . . . 0/imm8 # copy byte to *esi +887 # ++curr +888 46/increment-esi +889 # ++i +890 41/increment-ecx +891 eb/jump $zero-out:loop/disp8 +892 $zero-out:end: +893 # . restore registers +894 5e/pop-to-esi +895 5a/pop-to-edx +896 59/pop-to-ecx +897 58/pop-to-eax +898 # . epilogue +899 89/copy 3/mod/direct 4/rm32/esp . . . 5/r32/ebp . . # copy ebp to esp +900 5d/pop-to-ebp +901 c3/return +902 +903 test-zero-out: +904 # . prologue +905 55/push-ebp +906 89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp +907 # region/ecx = 34, 35, 36, 37 +908 68/push 0x37363534/imm32 +909 89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx +910 # zero-out(ecx, 3) +911 # . . push args +912 68/push 3/imm32/size +913 51/push-ecx +914 # . . call +915 e8/call zero-out/disp32 +916 # . . discard args +917 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp +918 # first 3 bytes cleared, fourth left alone +919 # . check-ints-equal(*ecx, 0x37000000, msg) +920 # . . push args +921 68/push "F - test-zero-out"/imm32 +922 68/push 0x37000000/imm32 +923 ff 6/subop/push 0/mod/indirect 1/rm32/ecx . . . . . . # push *ecx +924 # . . call +925 e8/call check-ints-equal/disp32 +926 # . . discard args +927 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32 # add to esp +928 # . reclaim locals +929 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp +930 # . epilogue +931 89/copy 3/mod/direct 4/rm32/esp . . . 5/r32/ebp . . # copy ebp to esp +932 5d/pop-to-ebp +933 c3/return +934 +935 # . . vim:nowrap:textwidth=0 -- cgit 1.4.1-2-gfad0