about summary refs log tree commit diff stats
path: root/059stop.subx
diff options
context:
space:
mode:
authorKartik Agaram <vc@akkartik.com>2020-06-10 23:26:53 -0700
committerKartik Agaram <vc@akkartik.com>2020-06-10 23:34:42 -0700
commit80f53f4a18d3121445ee98bf405669676c5e7017 (patch)
treed4c2a2b717c4ffc1a2da55bef334b705ba3a60b7 /059stop.subx
parent7dac9ade153d736b7a183d073d83b7a17b22b4cc (diff)
downloadmu-80f53f4a18d3121445ee98bf405669676c5e7017.tar.gz
6508 - support null exit-descriptor
Diffstat (limited to '059stop.subx')
-rw-r--r--059stop.subx19
1 files changed, 13 insertions, 6 deletions
diff --git a/059stop.subx b/059stop.subx
index 85b6ad36..f6cb6fae 100644
--- a/059stop.subx
+++ b/059stop.subx
@@ -93,21 +93,28 @@ stop:  # ed: (addr exit-descriptor), value: int
     # no prologue; one way or another, we're going to clobber registers
     # eax = ed
     8b/copy                         1/mod/*+disp8   4/rm32/sib    4/base/esp  4/index/none  .           0/r32/eax   4/disp8         .                 # copy *(esp+4) to eax
+    # if (ed == 0) really exit
+    3d/compare-eax-and 0/imm32
+    74/jump-if-=  $stop:real/disp8
     # if (ed->target == 0) really exit
     81          7/subop/compare     0/mod/indirect  0/rm32/eax    .           .             .           .           .               0/imm32           # compare *eax
-    75/jump-if-!=  $stop:fake/disp8
-    # . syscall(exit, value)
-    8b/copy                         1/mod/*+disp8   4/rm32/sib    4/base/esp  4/index/none  .           3/r32/ebx   8/disp8         .                 # copy *(esp+8) to ebx
-    e8/call  syscall_exit/disp32
+    74/jump-if-=  $stop:real/disp8
 $stop:fake:
-    # otherwise:
     # ed->value = value+1
     8b/copy                         1/mod/*+disp8   4/rm32/sib    4/base/esp  4/index/none  .           1/r32/ecx   8/disp8         .                 # copy *(esp+8) to ecx
     41/increment-ecx
     89/copy                         1/mod/*+disp8   0/rm32/eax    .           .             .           1/r32/ecx   4/disp8         .                 # copy ecx to *(eax+4)
     # perform a non-local jump to ed->target
     8b/copy                         0/mod/indirect  0/rm32/eax    .           .             .           4/r32/esp   .               .                 # copy *eax to esp
-$stop:end:
+$stop:end1:
+    # never gets here
+    c3/return  # doesn't return to caller
+$stop:real:
+    # . syscall(exit, value)
+    8b/copy                         1/mod/*+disp8   4/rm32/sib    4/base/esp  4/index/none  .           3/r32/ebx   8/disp8         .                 # copy *(esp+8) to ebx
+    e8/call  syscall_exit/disp32
+$stop:end2:
+    # never gets here
     c3/return  # doesn't return to caller
 
 test-stop-skips-returns-on-exit: