From 86351aafe218a7386f6578be3c4da3edcdcb0c98 Mon Sep 17 00:00:00 2001 From: Kartik Agaram Date: Fri, 12 Jun 2020 07:57:27 -0700 Subject: 6513 --- html/059stop.subx.html | 232 +++++++++++++++++++++++++------------------------ 1 file changed, 119 insertions(+), 113 deletions(-) (limited to 'html/059stop.subx.html') diff --git a/html/059stop.subx.html b/html/059stop.subx.html index 8cf368fc..b694cf6a 100644 --- a/html/059stop.subx.html +++ b/html/059stop.subx.html @@ -154,119 +154,125 @@ if ('onhashchange' in window) { 93 # no prologue; one way or another, we're going to clobber registers 94 # eax = ed 95 8b/copy 1/mod/*+disp8 4/rm32/sib 4/base/esp 4/index/none . 0/r32/eax 4/disp8 . # copy *(esp+4) to eax - 96 # if (ed->target == 0) really exit - 97 81 7/subop/compare 0/mod/indirect 0/rm32/eax . . . . . 0/imm32 # compare *eax - 98 75/jump-if-!= $stop:fake/disp8 - 99 # . syscall(exit, value) -100 8b/copy 1/mod/*+disp8 4/rm32/sib 4/base/esp 4/index/none . 3/r32/ebx 8/disp8 . # copy *(esp+8) to ebx -101 b8/copy-to-eax 1/imm32/exit -102 cd/syscall 0x80/imm8 -103 $stop:fake: -104 # otherwise: -105 # ed->value = value+1 -106 8b/copy 1/mod/*+disp8 4/rm32/sib 4/base/esp 4/index/none . 1/r32/ecx 8/disp8 . # copy *(esp+8) to ecx -107 41/increment-ecx -108 89/copy 1/mod/*+disp8 0/rm32/eax . . . 1/r32/ecx 4/disp8 . # copy ecx to *(eax+4) -109 # perform a non-local jump to ed->target -110 8b/copy 0/mod/indirect 0/rm32/eax . . . 4/r32/esp . . # copy *eax to esp -111 $stop:end: -112 c3/return # doesn't return to caller -113 -114 test-stop-skips-returns-on-exit: -115 # This looks like the standard prologue, but is here for different reasons. -116 # A function calling 'stop' can't rely on ebp persisting past the call. -117 # -118 # Use ebp here as a stable base to refer to locals and arguments from in the -119 # presence of push/pop/call instructions. -120 # *Don't* use ebp as a way to restore esp. -121 55/push-ebp -122 89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp -123 # Make room for an exit descriptor on the stack. That's almost always the -124 # right place for it, available only as long as it's legal to use. Once this -125 # containing function returns we'll need a new exit descriptor. -126 # var ed/eax: exit-descriptor -127 68/push 0/imm32 -128 68/push 0/imm32 -129 89/copy 3/mod/direct 0/rm32/eax . . . 4/r32/esp . . # copy esp to eax -130 # Size the exit-descriptor precisely for the next call below, to _test-stop-1. -131 # tailor-exit-descriptor(ed, 4) -132 # . . push args -133 68/push 4/imm32/nbytes-of-args-for-_test-stop-1 -134 50/push-eax -135 # . . call -136 e8/call tailor-exit-descriptor/disp32 -137 # . . discard args -138 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp -139 # . _test-stop-1(ed) -140 # . . push args -141 50/push-eax -142 # . . call -143 e8/call _test-stop-1/disp32 -144 # registers except esp may be clobbered at this point -145 # restore args -146 58/pop-to-eax -147 # check that _test-stop-1 tried to call exit(1) -148 # . check-ints-equal(ed->value, 2, msg) # i.e. stop was called with value 1 -149 # . . push args -150 68/push "F - test-stop-skips-returns-on-exit"/imm32 -151 68/push 2/imm32 -152 # . . push ed->value -153 ff 6/subop/push 1/mod/*+disp8 0/rm32/eax . . . . 4/disp8 . # push *(eax+4) -154 # . . call -155 e8/call check-ints-equal/disp32 -156 # . . discard args -157 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32 # add to esp -158 # . epilogue -159 # don't restore esp from ebp; manually reclaim locals -160 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp -161 5d/pop-to-ebp -162 c3/return -163 -164 _test-stop-1: # ed: (addr exit-descriptor) -165 # . prologue -166 55/push-ebp -167 89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp -168 # _test-stop-2(ed) -169 # . . push args -170 ff 6/subop/push 1/mod/*+disp8 5/rm32/ebp . . . . 8/disp8 . # push *(ebp+8) -171 # . . call -172 e8/call _test-stop-2/disp32 -173 # should never get past this point -174 $_test-stop-1:dead-end: -175 # . . discard args -176 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp -177 # signal test failed: check-ints-equal(1, 0, msg) -178 # . . push args -179 68/push "F - test-stop-skips-returns-on-exit"/imm32 -180 68/push 0/imm32 -181 68/push 1/imm32 -182 # . . call -183 e8/call check-ints-equal/disp32 -184 # . . discard args -185 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32 # add to esp -186 # . epilogue -187 89/copy 3/mod/direct 4/rm32/esp . . . 5/r32/ebp . . # copy ebp to esp -188 5d/pop-to-ebp -189 c3/return -190 -191 _test-stop-2: # ed: (addr exit-descriptor) -192 # . prologue -193 55/push-ebp -194 89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp -195 # . stop(ed, 1) -196 # . . push args -197 68/push 1/imm32 -198 ff 6/subop/push 1/mod/*+disp8 5/rm32/ebp . . . . 8/disp8 . # push *(ebp+8) -199 # . . call -200 e8/call stop/disp32 -201 # should never get past this point -202 $_test-stop-2:dead-end: -203 # . epilogue -204 89/copy 3/mod/direct 4/rm32/esp . . . 5/r32/ebp . . # copy ebp to esp -205 5d/pop-to-ebp -206 c3/return -207 -208 # . . vim:nowrap:textwidth=0 + 96 # if (ed == 0) really exit + 97 3d/compare-eax-and 0/imm32 + 98 74/jump-if-= $stop:real/disp8 + 99 # if (ed->target == 0) really exit +100 81 7/subop/compare 0/mod/indirect 0/rm32/eax . . . . . 0/imm32 # compare *eax +101 74/jump-if-= $stop:real/disp8 +102 $stop:fake: +103 # ed->value = value+1 +104 8b/copy 1/mod/*+disp8 4/rm32/sib 4/base/esp 4/index/none . 1/r32/ecx 8/disp8 . # copy *(esp+8) to ecx +105 41/increment-ecx +106 89/copy 1/mod/*+disp8 0/rm32/eax . . . 1/r32/ecx 4/disp8 . # copy ecx to *(eax+4) +107 # perform a non-local jump to ed->target +108 8b/copy 0/mod/indirect 0/rm32/eax . . . 4/r32/esp . . # copy *eax to esp +109 $stop:end1: +110 # never gets here +111 c3/return # doesn't return to caller +112 $stop:real: +113 # . syscall(exit, value) +114 8b/copy 1/mod/*+disp8 4/rm32/sib 4/base/esp 4/index/none . 3/r32/ebx 8/disp8 . # copy *(esp+8) to ebx +115 e8/call syscall_exit/disp32 +116 $stop:end2: +117 # never gets here +118 c3/return # doesn't return to caller +119 +120 test-stop-skips-returns-on-exit: +121 # This looks like the standard prologue, but is here for different reasons. +122 # A function calling 'stop' can't rely on ebp persisting past the call. +123 # +124 # Use ebp here as a stable base to refer to locals and arguments from in the +125 # presence of push/pop/call instructions. +126 # *Don't* use ebp as a way to restore esp. +127 55/push-ebp +128 89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp +129 # Make room for an exit descriptor on the stack. That's almost always the +130 # right place for it, available only as long as it's legal to use. Once this +131 # containing function returns we'll need a new exit descriptor. +132 # var ed/eax: exit-descriptor +133 68/push 0/imm32 +134 68/push 0/imm32 +135 89/copy 3/mod/direct 0/rm32/eax . . . 4/r32/esp . . # copy esp to eax +136 # Size the exit-descriptor precisely for the next call below, to _test-stop-1. +137 # tailor-exit-descriptor(ed, 4) +138 # . . push args +139 68/push 4/imm32/nbytes-of-args-for-_test-stop-1 +140 50/push-eax +141 # . . call +142 e8/call tailor-exit-descriptor/disp32 +143 # . . discard args +144 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp +145 # . _test-stop-1(ed) +146 # . . push args +147 50/push-eax +148 # . . call +149 e8/call _test-stop-1/disp32 +150 # registers except esp may be clobbered at this point +151 # restore args +152 58/pop-to-eax +153 # check that _test-stop-1 tried to call exit(1) +154 # . check-ints-equal(ed->value, 2, msg) # i.e. stop was called with value 1 +155 # . . push args +156 68/push "F - test-stop-skips-returns-on-exit"/imm32 +157 68/push 2/imm32 +158 # . . push ed->value +159 ff 6/subop/push 1/mod/*+disp8 0/rm32/eax . . . . 4/disp8 . # push *(eax+4) +160 # . . call +161 e8/call check-ints-equal/disp32 +162 # . . discard args +163 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32 # add to esp +164 # . epilogue +165 # don't restore esp from ebp; manually reclaim locals +166 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp +167 5d/pop-to-ebp +168 c3/return +169 +170 _test-stop-1: # ed: (addr exit-descriptor) +171 # . prologue +172 55/push-ebp +173 89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp +174 # _test-stop-2(ed) +175 # . . push args +176 ff 6/subop/push 1/mod/*+disp8 5/rm32/ebp . . . . 8/disp8 . # push *(ebp+8) +177 # . . call +178 e8/call _test-stop-2/disp32 +179 # should never get past this point +180 $_test-stop-1:dead-end: +181 # . . discard args +182 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp +183 # signal test failed: check-ints-equal(1, 0, msg) +184 # . . push args +185 68/push "F - test-stop-skips-returns-on-exit"/imm32 +186 68/push 0/imm32 +187 68/push 1/imm32 +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 # . epilogue +193 89/copy 3/mod/direct 4/rm32/esp . . . 5/r32/ebp . . # copy ebp to esp +194 5d/pop-to-ebp +195 c3/return +196 +197 _test-stop-2: # ed: (addr exit-descriptor) +198 # . prologue +199 55/push-ebp +200 89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp +201 # . stop(ed, 1) +202 # . . push args +203 68/push 1/imm32 +204 ff 6/subop/push 1/mod/*+disp8 5/rm32/ebp . . . . 8/disp8 . # push *(ebp+8) +205 # . . call +206 e8/call stop/disp32 +207 # should never get past this point +208 $_test-stop-2:dead-end: +209 # . epilogue +210 89/copy 3/mod/direct 4/rm32/esp . . . 5/r32/ebp . . # copy ebp to esp +211 5d/pop-to-ebp +212 c3/return +213 +214 # . . vim:nowrap:textwidth=0 -- cgit 1.4.1-2-gfad0