https://github.com/akkartik/mu/blob/master/123slice.subx
   1 # new data structure: a slice is an open interval of addresses [start, end)
   2 # that includes 'start' but not 'end'
   3 
   4 == code
   5 #   instruction                     effective address                                                   register    displacement    immediate
   6 # . op          subop               mod             rm32          base        index         scale       r32
   7 # . 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
   8 
   9 slice-empty?:  # s: (addr slice) -> result/eax: boolean
  10     # . prologue
  11     55/push-ebp
  12     89/copy                         3/mod/direct    5/rm32/ebp    .           .             .           4/r32/esp   .               .                 # copy esp to ebp
  13     # . save registers
  14     51/push-ecx
  15     # ecx = s
  16     8b/copy                         1/mod/*+disp8   5/rm32/ebp    .           .             .           1/r32/ecx   8/disp8         .                 # copy *(ebp+8) to ecx
  17     # if (s->start >= s->end) return true
  18     # . eax = s->start
  19     8b/copy                         0/mod/indirect  1/rm32/ecx    .           .             .           0/r32/eax   .               .                 # copy *ecx to eax
  20     # . if (eax >= s->end) return true
  21     3b/compare                      1/mod/*+disp8   1/rm32/ecx    .           .             .           0/r32/eax   4/disp8         .                 # compare eax with *(ecx+4)
  22     b8/copy-to-eax  1/imm32/true
  23     73/jump-if-addr>=  $slice-empty?:end/disp8
  24     b8/copy-to-eax  0/imm32/false
  25 $slice-empty?:end:
  26     # . restore registers
  27     59/pop-to-ecx
  28     # . epilogue
  29     89/copy                         3/mod/direct    4/rm32/esp    .           .             .           5/r32/ebp   .               .                 # copy ebp to esp
  30     5d/pop-to-ebp
  31     c3/return
  32 
  33 test-slice-empty-true:
  34     # . prologue
  35     55/push-ebp
  36     89/copy                         3/mod/direct    5/rm32/ebp    .           .             .           4/r32/esp   .               .                 # copy esp to ebp
  37     # var slice/ecx: slice = {34, 34}
  38     68/push  34/imm32/end
  39     68/push  34/imm32/start
  40     89/copy                         3/mod/direct    1/rm32/ecx    .           .             .           4/r32/esp   .               .                 # copy esp to ecx
  41     # slice-empty?(slice)
  42     # . . push args
  43     51/push-ecx
  44     # . . call
  45     e8/call  slice-empty?/disp32
  46     # . . discard args
  47     81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               4/imm32           # add to esp
  48     # check-ints-equal(eax, 1, msg)
  49     # . . push args
  50     68/push  "F - test-slice-empty-true"/imm32
  51     68/push  1/imm32
  52     50/push-eax
  53     # . . call
  54     e8/call  check-ints-equal/disp32
  55     # . . discard args
  56     81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               0xc/imm32         # add to esp
  57     # . epilogue
  58     89/copy                         3/mod/direct    4/rm32/esp    .           .             .           5/r32/ebp   .               .                 # copy ebp to esp
  59     5d/pop-to-ebp
  60     c3/return
  61 
  62 test-slice-empty-false:
  63     # . prologue
  64     55/push-ebp
  65     89/copy                         3/mod/direct    5/rm32/ebp    .           .             .           4/r32/esp   .               .                 # copy esp to ebp
  66     # var slice/ecx: slice = {32, 34}
  67     68/push  34/imm32/end
  68     68/push  32/imm32/start
  69     89/copy                         3/mod/direct    1/rm32/ecx    .           .             .           4/r32/esp   .               .                 # copy esp to ecx
  70     # slice-empty?(slice)
  71     # . . push args
  72     51/push-ecx
  73     # . . call
  74     e8/call  slice-empty?/disp32
  75     # . . discard args
  76     81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               4/imm32           # add to esp
  77     # check-ints-equal(eax, 0, msg)
  78     # . . push args
  79     68/push  "F - test-slice-empty-false"/imm32
  80     68/push  0/imm32
  81     50/push-eax
  82     # . . call
  83     e8/call  check-ints-equal/disp32
  84     # . . discard args
  85     81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               0xc/imm32         # add to esp
  86     # . epilogue
  87     89/copy                         3/mod/direct    4/rm32/esp    .           .             .           5/r32/ebp   .               .                 # copy ebp to esp
  88     5d/pop-to-ebp
  89     c3/return
  90 
  91 test-slice-empty-if-start-greater-than-end:
  92     # . prologue
  93     55/push-ebp
  94     89/copy                         3/mod/direct    5/rm32/ebp    .           .             .           4/r32/esp   .               .                 # copy esp to ebp
  95     # var slice/ecx: slice = {34, 32}
  96     68/push  32/imm32/end
  97     68/push  34/imm32/start
  98     89/copy                         3/mod/direct    1/rm32/ecx    .           .             .           4/r32/esp   .               .                 # copy esp to ecx
  99     # slice-empty?(slice)
 100     # . . push args
 101     51/push-ecx
 102     # . . call
 103     e8/call  slice-empty?/disp32
 104     # . . discard args
 105     81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               4/imm32           # add to esp
 106     # check-ints-equal(eax, 1, msg)
 107     # . . push args
 108     68/push  "F - test-slice-empty-if-start-greater-than-end"/imm32
 109     68/push  1/imm32
 110     50/push-eax
 111     # . . call
 112     e8/call  check-ints-equal/disp32
 113     # . . discard args
 114     81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               0xc/imm32         # add to esp
 115     # . epilogue
 116     89/copy                         3/mod/direct    4/rm32/esp    .           .             .           5/r32/ebp   .               .                 # copy ebp to esp
 117     5d/pop-to-ebp
 118     c3/return
 119 
 120 slice-equal?:  # s: (addr slice), p: (addr array byte) -> result/eax: boolean
 121     # pseudocode:
 122     #   if (p == 0) return (s == 0)
 123     #   currs = s->start
 124     #   maxs = s->end
 125     #   if (maxs - currs != p->size) return false
 126     #   currp = p->data
 127     #   while currs < maxs
 128     #     if (*currs != *currp) return false
 129     #     ++currs
 130     #     ++currp
 131     #   return true
 132     #
 133     # registers:
 134     #   currs: edx
 135     #   maxs: esi
 136     #   currp: ebx
 137     #   *currs: eax
 138     #   *currp: ecx
 139     #
 140     # . prologue
 141     55/push-ebp
 142     89/copy                         3/mod/direct    5/rm32/ebp    .           .             .           4/r32/esp   .               .                 # copy esp to ebp
 143     # . save registers
 144     51/push-ecx
 145     52/push-edx
 146     53/push-ebx
 147     56/push-esi
 148     # esi = s
 149     8b/copy                         1/mod/*+disp8   5/rm32/ebp    .           .             .           6/r32/esi   8/disp8         .                 # copy *(ebp+8) to esi
 150     # var currs/edx: (addr byte) = s->start
 151     8b/copy                         0/mod/indirect  6/rm32/esi    .           .             .           2/r32/edx   .               .                 # copy *esi t
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html><head><title>Python: module ranger.fsobject.loader</title>
</head><body bgcolor="#f0f0f8">

<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
<tr bgcolor="#7799ee">
<td valign=bottom>&nbsp;<br>
<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="ranger.html"><font color="#ffffff">ranger</font></a>.<a href="ranger.fsobject.html"><font color="#ffffff">fsobject</font></a>.loader</strong></big></big></font></td
><td align=right valign=bottom
><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="file:/home/hut/ranger/ranger/fsobject/loader.py">/home/hut/ranger/ranger/fsobject/loader.py</a></font></td></tr></table>
    <p><tt>#&nbsp;Copyright&nbsp;(C)&nbsp;2009,&nbsp;2010&nbsp;&nbsp;Roman&nbsp;Zimbelmann&nbsp;&lt;romanz@lavabit.com&gt;<br>
#<br>
#&nbsp;This&nbsp;program&nbsp;is&nbsp;free&nbsp;software:&nbsp;you&nbsp;can&nbsp;redistribute&nbsp;it&nbsp;and/or&nbsp;modify<br>
#&nbsp;it&nbsp;under&nbsp;the&nbsp;terms&nbsp;of&nbsp;the&nbsp;GNU&nbsp;General&nbsp;Public&nbsp;License&nbsp;as&nbsp;published&nbsp;by<br>
#&nbsp;the&nbsp;Free&nbsp;Software&nbsp;Foundation,&nbsp;either&nbsp;version&nbsp;3&nbsp;of&nbsp;the&nbsp;License,&nbsp;or<br>
#&nbsp;(at&nbsp;your&nbsp;option)&nbsp;any&nbsp;later&nbsp;version.<br>
#<br>
#&nbsp;This&nbsp;program&nbsp;is&nbsp;distributed&nbsp;in&nbsp;the&nbsp;hope&nbsp;that&nbsp;it&nbsp;will&nbsp;be&nbsp;useful,<br>
#&nbsp;but&nbsp;WITHOUT&nbsp;ANY&nbsp;WARRANTY;&nbsp;without&nbsp;even&nbsp;the&nbsp;implied&nbsp;warranty&nbsp;of<br>
#&nbsp;MERCHANTABILITY&nbsp;or&nbsp;FITNESS&nbsp;FOR&nbsp;A&nbsp;PARTICULAR&nbsp;PURPOSE.&nbsp;&nbsp;See&nbsp;the<br>
#&nbsp;GNU&nbsp;General&nbsp;Public&nbsp;License&nbsp;for&nbsp;more&nbsp;details.<br>
#<br>
#&nbsp;You&nbsp;should&nbsp;have&nbsp;received&nbsp;a&nbsp;copy&nbsp;of&nbsp;the&nbsp;GNU&nbsp;General&nbsp;Public&nbsp;License<br>
#&nbsp;along&nbsp;with&nbsp;this&nbsp;program.&nbsp;&nbsp;If&nbsp;not,&nbsp;see&nbsp;&lt;<a href="http://www.gnu.org/licenses/">http://www.gnu.org/licenses/</a>&gt;.</tt></p>
<p>
<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
<tr bgcolor="#aa55cc">
<td colspan=3 valign=bottom>&nbsp;<br>
<font color="#ffffff" face="helvetica, arial"><big><strong>Modules</strong></big></font></td></tr>
    
<tr><td bgcolor="#aa55cc"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="math.html">math</a><br>
</td><td width="25%" valign=top></td><td width="25%" valign=top></td><td width="25%" valign=top></td></tr></table></td></tr></table><p>
<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
<tr bgcolor="#ee77aa">
<td colspan=3 valign=bottom>&nbsp;<br>
<font color="#ffffff" face="helvetica, arial"><big><strong>Classes</strong></big></font></td></tr>
    
<tr><td bgcolor="#ee77aa"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
<td width="100%"><dl>
<dt><font face="helvetica, arial"><a href="__builtin__.html#object">__builtin__.object</a>
</font></dt><dd>
<dl>
<dt><font face="helvetica, arial"><a href="ranger.fsobject.loader.html#LoadableObject">LoadableObject</a>
</font></dt></dl>
</dd>
<dt><font face="helvetica, arial"><a href="ranger.shared.html#FileManagerAware">ranger.shared.FileManagerAware</a>(<a href="ranger.shared.html#Awareness">ranger.shared.Awareness</a>)
</font></dt><dd>
<dl>
<dt><font face="helvetica, arial"><a href="ranger.fsobject.loader.html#Loader">Loader</a>
</font></dt></dl>
</dd>
</dl>
 <p>
<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
<tr bgcolor="#ffc8d8">
<td colspan=3 valign=bottom>&nbsp;<br>
<font color="#000000" face="helvetica, arial"><a name="LoadableObject">class <strong>LoadableObject</strong></a>(<a href="__builtin__.html#object">__builtin__.object</a>)</font></td></tr>
    
<tr><td bgcolor="#ffc8d8"><tt>&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
<td width="100%">Methods defined here:<br>
<dl><dt><a name="LoadableObject-__init__"><strong>__init__</strong></a>(self, gen, descr)</dt></dl>

<dl><dt><a name="LoadableObject-get_description"><strong>get_description</strong></a>(self)</dt></dl>

<hr>
Data descriptors defined here:<br>
<dl><dt><strong>__dict__</strong></dt>
<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
</dl>
<dl><dt><strong>__weakref__</strong></dt>
<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
</dl>
</td></tr></table> <p>
<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
<tr bgcolor="#ffc8d8">
<td colspan=3 valign=bottom>&nbsp;<br>
<font color="#000000" face="helvetica, arial"><a name="Loader">class <strong>Loader</strong></a>(<a href="ranger.shared.html#FileManagerAware">ranger.shared.FileManagerAware</a>)</font></td></tr>
    
<tr><td bgcolor="#ffc8d8"><tt>&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
<td width="100%"><dl><dt>Method resolution order:</dt>
<dd><a href="ranger.fsobject.loader.html#Loader">Loader</a></dd>
<dd><a href="ranger.shared.html#FileManagerAware">ranger.shared.FileManagerAware</a></dd>
<dd><a href="ranger.shared.html#Awareness">ranger.shared.Awareness</a></dd>
<dd><a href="__builtin__.html#object">__builtin__.object</a></dd>
</dl>
<hr>
Methods defined here:<br>
<dl><dt><a name="Loader-__init__"><strong>__init__</strong></a>(self)</dt></dl>

<dl><dt><a name="Loader-add"><strong>add</strong></a>(self, obj)</dt><dd><tt>Add&nbsp;an&nbsp;<a href="__builtin__.html#object">object</a>&nbsp;to&nbsp;the&nbsp;queue.<br>
It&nbsp;should&nbsp;have&nbsp;a&nbsp;load_generator&nbsp;method.</tt></dd></dl>

<dl><dt><a name="Loader-has_work"><strong>has_work</strong></a>(self)</dt><dd><tt>Is&nbsp;there&nbsp;anything&nbsp;to&nbsp;load?</tt></dd></dl>

<dl><dt><a name="Loader-move"><strong>move</strong></a>(self, _from, to)</dt></dl>

<dl><dt><a name="Loader-remove"><strong>remove</strong></a>(self, item<font color="#909090">=None</font>, index<font color="#909090">=None</font>)</dt></dl>

<dl><dt><a name="Loader-rotate"><strong>rotate</strong></a>(self)</dt><dd><tt>Rotate&nbsp;the&nbsp;throbber</tt></dd></dl>

<dl><dt><a name="Loader-work"><strong>work</strong></a>(self)</dt><dd><tt>Load&nbsp;items&nbsp;from&nbsp;the&nbsp;queue&nbsp;if&nbsp;there&nbsp;are&nbsp;any.<br>
Stop&nbsp;after&nbsp;approximately&nbsp;self.<strong>seconds_of_work_time</strong>.</tt></dd></dl>

<hr>
Data and other attributes defined here:<br>
<dl><dt><strong>seconds_of_work_time</strong> = 0.029999999999999999</dl>

<hr>
Data and other attributes inherited from <a href="ranger.shared.html#FileManagerAware">ranger.shared.FileManagerAware</a>:<br>
<dl><dt><strong>fm</strong> = None</dl>

<hr>
Data descriptors inherited from <a href="ranger.shared.html#Awareness">ranger.shared.Awareness</a>:<br>
<dl><dt><strong>__dict__</strong></dt>
<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
</dl>
<dl><dt><strong>__weakref__</strong></dt>
<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
</dl>
</td></tr></table></td></tr></table><p>
<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
<tr bgcolor="#eeaa77">
<td colspan=3 valign=bottom>&nbsp;<br>
<font color="#ffffff" face="helvetica, arial"><big><strong>Functions</strong></big></font></td></tr>
    
<tr><td bgcolor="#eeaa77"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
<td width="100%"><dl><dt><a name="-status_generator"><strong>status_generator</strong></a>()</dt><dd><tt>Generate&nbsp;a&nbsp;rotating&nbsp;line&nbsp;which&nbsp;can&nbsp;be&nbsp;used&nbsp;as&nbsp;a&nbsp;throbber</tt></dd></dl>
 <dl><dt><a name="-time"><strong>time</strong></a>(...)</dt><dd><tt><a href="#-time">time</a>()&nbsp;-&gt;&nbsp;floating&nbsp;point&nbsp;number<br>
&nbsp;<br>
Return&nbsp;the&nbsp;current&nbsp;time&nbsp;in&nbsp;seconds&nbsp;since&nbsp;the&nbsp;Epoch.<br>
Fractions&nbsp;of&nbsp;a&nbsp;second&nbsp;may&nbsp;be&nbsp;present&nbsp;if&nbsp;the&nbsp;system&nbsp;clock&nbsp;provides&nbsp;them.</tt></dd></dl>
</td></tr></table>
</body></html>
irect 6/rm32/esi . . . 0/r32/AL . . # copy byte at *esi to AL 546 # c2 = *currh 547 8a/copy-byte 0/mod/indirect 7/rm32/edi . . . 3/r32/BL . . # copy byte at *edi to BL 548 # if (c1 != c2) return false 549 39/compare 3/mod/direct 0/rm32/eax . . . 3/r32/ebx . . # compare eax and ebx 550 75/jump-if-!= $slice-starts-with?:false/disp8 551 # ++i 552 41/increment-ecx 553 # ++currs 554 46/increment-esi 555 # ++currh 556 47/increment-edi 557 eb/jump $slice-starts-with?:loop/disp8 558 $slice-starts-with?:true: 559 b8/copy-to-eax 1/imm32 560 eb/jump $slice-starts-with?:end/disp8 561 $slice-starts-with?:false: 562 b8/copy-to-eax 0/imm32 563 $slice-starts-with?:end: 564 # . restore registers 565 5f/pop-to-edi 566 5e/pop-to-esi 567 5b/pop-to-ebx 568 5a/pop-to-edx 569 59/pop-to-ecx 570 # . epilogue 571 89/copy 3/mod/direct 4/rm32/esp . . . 5/r32/ebp . . # copy ebp to esp 572 5d/pop-to-ebp 573 c3/return 574 575 test-slice-starts-with-single-character: 576 # - slice-starts-with?(slice("Abc"), "A") == 1 577 # . prologue 578 55/push-ebp 579 89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp 580 # (eax..ecx) = "Abc" 581 b8/copy-to-eax "Abc"/imm32 582 8b/copy 0/mod/indirect 0/rm32/eax . . . 1/r32/ecx . . # copy *eax to ecx 583 8d/copy-address 1/mod/*+disp8 4/rm32/sib 0/base/eax 1/index/ecx . 1/r32/ecx 4/disp8 . # copy eax+ecx+4 to ecx 584 05/add-to-eax 4/imm32 585 # var slice/ecx: slice = {eax, ecx} 586 51/push-ecx 587 50/push-eax 588 89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx 589 # eax = slice-starts-with?(ecx, "A") 590 # . . push args 591 68/push "A"/imm32 592 51/push-ecx 593 # . . call 594 e8/call slice-starts-with?/disp32 595 # . . discard args 596 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp 597 # check-ints-equal(eax, 1, msg) 598 # . . push args 599 68/push "F - test-slice-starts-with-single-character"/imm32 600 68/push 1/imm32 601 50/push-eax 602 # . . call 603 e8/call check-ints-equal/disp32 604 # . . discard args 605 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32 # add to esp 606 # . epilogue 607 89/copy 3/mod/direct 4/rm32/esp . . . 5/r32/ebp . . # copy ebp to esp 608 5d/pop-to-ebp 609 c3/return 610 611 test-slice-starts-with-empty-string: 612 # - slice-starts-with?(slice("Abc"), "") == 1 613 # . prologue 614 55/push-ebp 615 89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp 616 # (eax..ecx) = "Abc" 617 b8/copy-to-eax "Abc"/imm32 618 8b/copy 0/mod/indirect 0/rm32/eax . . . 1/r32/ecx . . # copy *eax to ecx 619 8d/copy-address 1/mod/*+disp8 4/rm32/sib 0/base/eax 1/index/ecx . 1/r32/ecx 4/disp8 . # copy eax+ecx+4 to ecx 620 05/add-to-eax 4/imm32 621 # var slice/ecx: slice = {eax, ecx} 622 51/push-ecx 623 50/push-eax 624 89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx 625 # eax = slice-starts-with?(ecx, "") 626 # . . push args 627 68/push ""/imm32 628 51/push-ecx 629 # . . call 630 e8/call slice-starts-with?/disp32 631 # . . discard args 632 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp 633 # check-ints-equal(eax, 1, msg) 634 # . . push args 635 68/push "F - test-slice-starts-with-empty-string"/imm32 636 68/push 1/imm32 637 50/push-eax 638 # . . call 639 e8/call check-ints-equal/disp32 640 # . . discard args 641 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32 # add to esp 642 # . epilogue 643 89/copy 3/mod/direct 4/rm32/esp . . . 5/r32/ebp . . # copy ebp to esp 644 5d/pop-to-ebp 645 c3/return 646 647 test-slice-starts-with-multiple-characters: 648 # - slice-starts-with?(slice("Abc"), "Ab") == 1 649 # . prologue 650 55/push-ebp 651 89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp 652 # (eax..ecx) = "Abc" 653 b8/copy-to-eax "Abc"/imm32 654 8b/copy 0/mod/indirect 0/rm32/eax . . . 1/r32/ecx . . # copy *eax to ecx 655 8d/copy-address 1/mod/*+disp8 4/rm32/sib 0/base/eax 1/index/ecx . 1/r32/ecx 4/disp8 . # copy eax+ecx+4 to ecx 656 05/add-to-eax 4/imm32 657 # var slice/ecx: slice = {eax, ecx} 658 51/push-ecx 659 50/push-eax 660 89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx 661 # eax = slice-starts-with?(ecx, "Ab") 662 # . . push args 663 68/push "Ab"/imm32 664 51/push-ecx 665 # . . call 666 e8/call slice-starts-with?/disp32 667 # . . discard args 668 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp 669 # check-ints-equal(eax, 1, msg) 670 # . . push args 671 68/push "F - test-slice-starts-with-multiple-characters"/imm32 672 68/push 1/imm32 673 50/push-eax 674 # . . call 675 e8/call check-ints-equal/disp32 676 # . . discard args 677 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32 # add to esp 678 # . epilogue 679 89/copy 3/mod/direct 4/rm32/esp . . . 5/r32/ebp . . # copy ebp to esp 680 5d/pop-to-ebp 681 c3/return 682 683 test-slice-starts-with-entire-string: 684 # - slice-starts-with?(slice("Abc"), "Abc") == 1 685 # . prologue 686 55/push-ebp 687 89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp 688 # (eax..ecx) = "Abc" 689 b8/copy-to-eax "Abc"/imm32 690 8b/copy 0/mod/indirect 0/rm32/eax . . . 1/r32/ecx . . # copy *eax to ecx 691 8d/copy-address 1/mod/*+disp8 4/rm32/sib 0/base/eax 1/index/ecx . 1/r32/ecx 4/disp8 . # copy eax+ecx+4 to ecx 692 05/add-to-eax 4/imm32 693 # var slice/ecx: slice = {eax, ecx} 694 51/push-ecx 695 50/push-eax 696 89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx 697 # eax = slice-starts-with?(ecx, "Abc") 698 # . . push args 699 68/push "Abc"/imm32 700 51/push-ecx 701 # . . call 702 e8/call slice-starts-with?/disp32 703 # . . discard args 704 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp 705 # check-ints-equal(eax, 1, msg) 706 # . . push args 707 68/push "F - test-slice-starts-with-entire-string"/imm32 708 68/push 1/imm32 709 50/push-eax 710 # . . call 711 e8/call check-ints-equal/disp32 712 # . . discard args 713 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32 # add to esp 714 # . epilogue 715 89/copy 3/mod/direct 4/rm32/esp . . . 5/r32/ebp . . # copy ebp to esp 716 5d/pop-to-ebp 717 c3/return 718 719 test-slice-starts-with-fails: 720 # - slice-starts-with?(slice("Abc"), "Abd") == 1 721 # . prologue 722 55/push-ebp 723 89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp 724 # (eax..ecx) = "Abc" 725 b8/copy-to-eax "Abc"/imm32 726 8b/copy 0/mod/indirect 0/rm32/eax . . . 1/r32/ecx . . # copy *eax to ecx 727 8d/copy-address 1/mod/*+disp8 4/rm32/sib 0/base/eax 1/index/ecx . 1/r32/ecx 4/disp8 . # copy eax+ecx+4 to ecx 728 05/add-to-eax 4/imm32 729 # var slice/ecx: slice = {eax, ecx} 730 51/push-ecx 731 50/push-eax 732 89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx 733 # eax = slice-starts-with?(ecx, "Abd") 734 # . . push args 735 68/push "Abd"/imm32 736 51/push-ecx 737 # . . call 738 e8/call slice-starts-with?/disp32 739 # . . discard args 740 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp 741 # check-ints-equal(eax, 0, msg) 742 # . . push args 743 68/push "F - test-slice-starts-with-fails"/imm32 744 68/push 0/imm32 745 50/push-eax 746 # . . call 747 e8/call check-ints-equal/disp32 748 # . . discard args 749 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32 # add to esp 750 # . epilogue 751 89/copy 3/mod/direct 4/rm32/esp . . . 5/r32/ebp . . # copy ebp to esp 752 5d/pop-to-ebp 753 c3/return 754 755 test-slice-starts-with-fails-2: 756 # - slice-starts-with?(slice("Abc"), "Ac") == 1 757 # . prologue 758 55/push-ebp 759 89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp 760 # (eax..ecx) = "Abc" 761 b8/copy-to-eax "Abc"/imm32 762 8b/copy 0/mod/indirect 0/rm32/eax . . . 1/r32/ecx . . # copy *eax to ecx 763 8d/copy-address 1/mod/*+disp8 4/rm32/sib 0/base/eax 1/index/ecx . 1/r32/ecx 4/disp8 . # copy eax+ecx+4 to ecx 764 05/add-to-eax 4/imm32 765 # var slice/ecx: slice = {eax, ecx} 766 51/push-ecx 767 50/push-eax 768 89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx 769 # eax = slice-starts-with?(ecx, "Ac") 770 # . . push args 771 68/push "Ac"/imm32 772 51/push-ecx 773 # . . call 774 e8/call slice-starts-with?/disp32 775 # . . discard args 776 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp 777 # check-ints-equal(eax, 0, msg) 778 # . . push args 779 68/push "F - test-slice-starts-with-fails-2"/imm32 780 68/push 0/imm32 781 50/push-eax 782 # . . call 783 e8/call check-ints-equal/disp32 784 # . . discard args 785 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32 # add to esp 786 # . epilogue 787 89/copy 3/mod/direct 4/rm32/esp . . . 5/r32/ebp . . # copy ebp to esp 788 5d/pop-to-ebp 789 c3/return 790 791 # write a slice to a stream 792 # abort if the stream doesn't have enough space 793 write-slice: # out: (addr stream byte), s: (addr slice) 794 # . prologue 795 55/push-ebp 796 89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp 797 # . save registers 798 50/push-eax 799 51/push-ecx 800 52/push-edx 801 53/push-ebx 802 56/push-esi 803 57/push-edi 804 # esi = s 805 8b/copy 1/mod/*+disp8 5/rm32/ebp . . . 6/r32/esi 0xc/disp8 . # copy *(ebp+12) to esi 806 # var curr/ecx: (addr byte) = s->start 807 8b/copy 0/mod/indirect 6/rm32/esi . . . 1/r32/ecx . . # copy *esi to ecx 808 # var max/esi: (addr byte) = s->end 809 8b/copy 1/mod/*+disp8 6/rm32/esi . . . 6/r32/esi 4/disp8 . # copy *(esi+4) to esi 810 # edi = out 811 8b/copy 1/mod/*+disp8 5/rm32/ebp . . 7/r32/edi 8/disp8 . # copy *(ebp+8) to edi 812 # edx = out->size 813 8b/copy 1/mod/*+disp8 7/rm32/edi . . . 2/r32/edx 8/disp8 . # copy *(edi+8) to edx 814 # ebx = out->write 815 8b/copy 0/mod/indirect 7/rm32/edi . . . 3/r32/ebx . . # copy *edi to ebx 816 $write-slice:loop: 817 # if (curr >= max) break 818 39/compare 3/mod/direct 1/rm32/ecx . . . 6/r32/esi . . # compare ecx with esi 819 73/jump-if-addr>= $write-slice:loop-end/disp8 820 # if (out->write >= out->size) abort 821 39/compare 3/mod/direct 3/rm32/ebx . . . 2/r32/edx . . # compare ebx with edx 822 7d/jump-if->= $write-slice:abort/disp8 823 # out->data[out->write] = *in 824 # . AL = *in 825 31/xor 3/mod/direct 0/rm32/eax . . . 0/r32/eax . . # clear eax 826 8a/copy-byte 0/mod/indirect 1/rm32/ecx . . . 0/r32/AL . . # copy byte at *ecx to AL 827 # . out->data[out->write] = AL 828 88/copy-byte 1/mod/*+disp8 4/rm32/sib 7/base/edi 3/index/ebx . 0/r32/AL 0xc/disp8 . # copy AL to *(edi+ebx+12) 829 # ++out->write 830 43/increment-ebx 831 # ++in 832 41/increment-ecx 833 eb/jump $write-slice:loop/disp8 834 $write-slice:loop-end: 835 # persist out->write 836 89/copy 0/mod/indirect 7/rm32/edi . . . 3/r32/ebx . . # copy ebx to *edi 837 $write-slice:end: 838 # . restore registers 839 5f/pop-to-edi 840 5e/pop-to-esi 841 5b/pop-to-ebx 842 5a/pop-to-edx 843 59/pop-to-ecx 844 58/pop-to-eax 845 # . epilogue 846 89/copy 3/mod/direct 4/rm32/esp . . . 5/r32/ebp . . # copy ebp to esp 847 5d/pop-to-ebp 848 c3/return 849 850 $write-slice:abort: 851 # . _write(2/stderr, error) 852 # . . push args 853 68/push "write-slice: out of space"/imm32 854 68/push 2/imm32/stderr 855 # . . call 856 e8/call _write/disp32 857 # . . discard args 858 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp 859 # . syscall(exit, 1) 860 bb/copy-to-ebx 1/imm32 861 e8/call syscall_exit/disp32 862 # never gets here 863 864 test-write-slice: 865 # . prologue 866 55/push-ebp 867 89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp 868 # setup 869 # . clear-stream(_test-stream) 870 # . . push args 871 68/push _test-stream/imm32 872 # . . call 873 e8/call clear-stream/disp32 874 # . . discard args 875 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp 876 # (eax..ecx) = "Abc" 877 b8/copy-to-eax "Abc"/imm32 878 8b/copy 0/mod/indirect 0/rm32/eax . . . 1/r32/ecx . . # copy *eax to ecx 879 8d/copy-address 1/mod/*+disp8 4/rm32/sib 0/base/eax 1/index/ecx . 1/r32/ecx 4/disp8 . # copy eax+ecx+4 to ecx 880 05/add-to-eax 4/imm32 881 # var slice/ecx: slice = {eax, ecx} 882 51/push-ecx 883 50/push-eax 884 89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx 885 # write-slice(_test-stream, slice) 886 # . . push args 887 51/push-ecx 888 68/push _test-stream/imm32 889 # . . call 890 e8/call write-slice/disp32 891 # . . discard args 892 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp 893 # check-stream-equal(_test-stream, "Abc", msg) 894 # . . push args 895 68/push "F - test-write-slice"/imm32 896 68/push "Abc"/imm32 897 68/push _test-stream/imm32 898 # . . call 899 e8/call check-stream-equal/disp32 900 # . . discard args 901 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32 # add to esp 902 # . epilogue 903 89/copy 3/mod/direct 4/rm32/esp . . . 5/r32/ebp . . # copy ebp to esp 904 5d/pop-to-ebp 905 c3/return 906 907 # write a slice to a buffered-file 908 write-slice-buffered: # out: (addr buffered-file), s: (addr slice) 909 # . prologue 910 55/push-ebp 911 89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp 912 # . save registers 913 50/push-eax 914 51/push-ecx 915 52/push-edx 916 53/push-ebx 917 56/push-esi 918 57/push-edi 919 # esi = s 920 8b/copy 1/mod/*+disp8 5/rm32/ebp . . . 6/r32/esi 0xc/disp8 . # copy *(ebp+12) to esi 921 # var curr/ecx: (addr byte) = s->start 922 8b/copy 0/mod/indirect 6/rm32/esi . . . 1/r32/ecx . . # copy *esi to ecx 923 # var max/esi: (addr byte) = s->end 924 8b/copy 1/mod/*+disp8 6/rm32/esi . . . 6/r32/esi 4/disp8 . # copy *(esi+4) to esi 925 # edi = out 926 8b/copy 1/mod/*+disp8 5/rm32/ebp . . 7/r32/edi 8/disp8 . # copy *(ebp+8) to edi 927 # edx = out->size 928 8b/copy 1/mod/*+disp8 7/rm32/edi . . . 2/r32/edx 0xc/disp8 . # copy *(edi+12) to edx 929 # ebx = out->write 930 8b/copy 1/mod/*+disp8 7/rm32/edi . . . 3/r32/ebx 4/disp8 . # copy *(edi+4) to ebx 931 $write-slice-buffered:loop: 932 # if (curr >= max) break 933 39/compare 3/mod/direct 1/rm32/ecx . . . 6/r32/esi . . # compare ecx with esi 934 73/jump-if-addr>= $write-slice-buffered:loop-end/disp8 935 # if (out->write >= out->size) flush and clear out's stream 936 39/compare 3/mod/direct 3/rm32/ebx . . . 2/r32/edx . . # compare ebx with edx 937 7c/jump-if-< $write-slice-buffered:to-stream/disp8 938 # . persist out->write 939 89/copy 1/mod/*+disp8 7/rm32/edi . . . 3/r32/ebx 4/disp8 . # copy ebx to *(edi+4) 940 # . flush(out) 941 # . . push args 942 57/push-edi 943 # . . call 944 e8/call flush/disp32 945 # . . discard args 946 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp 947 # . clear-stream(stream = out+4) 948 # . . push args 949 8d/copy-address 1/mod/*+disp8 7/rm32/edi . . . 0/r32/eax 4/disp8 . # copy edi+4 to eax 950 50/push-eax 951 # . . call 952 e8/call clear-stream/disp32 953 # . . discard args 954 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp 955 # . out->write must now be 0; update its cache at ebx 956 31/xor 3/mod/direct 3/rm32/ebx . . . 3/r32/ebx . . # clear ebx 957 $write-slice-buffered:to-stream: 958 # out->data[out->write] = *in 959 # . AL = *in 960 31/xor 3/mod/direct 0/rm32/eax . . . 0/r32/eax . . # clear eax 961 8a/copy-byte 0/mod/indirect 1/rm32/ecx . . . 0/r32/AL . . # copy byte at *ecx to AL 962 # . out->data[out->write] = AL 963 88/copy-byte 1/mod/*+disp8 4/rm32/sib 7/base/edi 3/index/ebx . 0/r32/AL 0x10/disp8 . # copy AL to *(edi+ebx+16) 964 # ++out->write 965 43/increment-ebx 966 # ++in 967 41/increment-ecx 968 eb/jump $write-slice-buffered:loop/disp8 969 $write-slice-buffered:loop-end: 970 # persist necessary variables from registers 971 89/copy 1/mod/*+disp8 7/rm32/edi . . . 3/r32/ebx 4/disp8 . # copy ebx to *(edi+4) 972 $write-slice-buffered:end: 973 # . restore registers 974 5f/pop-to-edi 975 5e/pop-to-esi 976 5b/pop-to-ebx 977 5a/pop-to-edx 978 59/pop-to-ecx 979 58/pop-to-eax 980 # . epilogue 981 89/copy 3/mod/direct 4/rm32/esp . . . 5/r32/ebp . . # copy ebp to esp 982 5d/pop-to-ebp 983 c3/return 984 985 test-write-slice-buffered: 986 # . prologue 987 55/push-ebp 988 89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp 989 # setup 990 # . clear-stream(_test-stream) 991 # . . push args 992 68/push _test-stream/imm32 993 # . . call 994 e8/call clear-stream/disp32 995 # . . discard args 996 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp 997 # . clear-stream($_test-buffered-file->buffer) 998 # . . push args 999 68/push $_test-buffered-file->buffer/imm32 1000 # . . call 1001 e8/call clear-stream/disp32 1002 # . . discard args 1003 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp 1004 # (eax..ecx) = "Abc" 1005 b8/copy-to-eax "Abc"/imm32 1006 8b/copy 0/mod/indirect 0/rm32/eax . . . 1/r32/ecx . . # copy *eax to ecx 1007 8d/copy-address 1/mod/*+disp8 4/rm32/sib 0/base/eax 1/index/ecx . 1/r32/ecx 4/disp8 . # copy eax+ecx+4 to ecx 1008 05/add-to-eax 4/imm32 1009 # var slice/ecx: slice = {eax, ecx} 1010 51/push-ecx 1011 50/push-eax 1012 89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx 1013 # write-slice-buffered(_test-buffered-file, slice) 1014 # . . push args 1015 51/push-ecx 1016 68/push _test-buffered-file/imm32 1017 # . . call 1018 e8/call write-slice-buffered/disp32 1019 # . . discard args 1020 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp 1021 # flush(_test-buffered-file) 1022 # . . push args 1023 68/push _test-buffered-file/imm32 1024 # . . call 1025 e8/call flush/disp32 1026 # . . discard args 1027 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp 1028 # check-stream-equal(_test-stream, "Abc", msg) 1029 # . . push args 1030 68/push "F - test-write-slice-buffered"/imm32 1031 68/push "Abc"/imm32 1032 68/push _test-stream/imm32 1033 # . . call 1034 e8/call check-stream-equal/disp32 1035 # . . discard args 1036 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32 # add to esp 1037 # . epilogue 1038 89/copy 3/mod/direct 4/rm32/esp . . . 5/r32/ebp . . # copy ebp to esp 1039 5d/pop-to-ebp 1040 c3/return 1041 1042 # copy a slice into a new (dynamically allocated) string 1043 slice-to-string: # ad: (addr allocation-descriptor), in: (addr slice), out: (addr handle array byte) 1044 # . prologue 1045 55/push-ebp 1046 89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp 1047 # . save registers 1048 50/push-eax 1049 51/push-ecx 1050 52/push-edx 1051 53/push-ebx 1052 56/push-esi 1053 # esi = in 1054 8b/copy 1/mod/*+disp8 5/rm32/ebp . . . 6/r32/esi 0xc/disp8 . # copy *(ebp+12) to esi 1055 # var curr/edx: (addr byte) = in->start 1056 8b/copy 0/mod/indirect 6/rm32/esi . . . 2/r32/edx . . # copy *esi to edx 1057 # var max/ebx: (addr byte) = in->end 1058 8b/copy 1/mod/*+disp8 6/rm32/esi . . . 3/r32/ebx 4/disp8 . # copy *(esi+4) to ebx 1059 # var size/ecx: int = max - curr + 4 # total size of output string (including the initial 'size' field) 1060 89/copy 3/mod/direct 1/rm32/ecx . . . 3/r32/ebx . . # copy ebx to ecx 1061 29/subtract 3/mod/direct 1/rm32/ecx . . . 2/r32/edx . . # subtract edx from ecx 1062 81 0/subop/add 3/mod/direct 1/rm32/ecx . . . . . 4/imm32 # add to ecx 1063 # allocate(ad, size, out) 1064 # . . push args 1065 ff 6/subop/push 1/mod/*+disp8 5/rm32/ebp . . . . 0x10/disp8 . # push *(ebp+16) 1066 51/push-ecx 1067 ff 6/subop/push 1/mod/*+disp8 5/rm32/ebp . . . . 8/disp8 . # push *(ebp+8) 1068 # . . call 1069 e8/call allocate/disp32 1070 # . . discard args 1071 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32 # add to esp 1072 # eax = out->payload 1073 8b/copy 1/mod/*+disp8 5/rm32/ebp . . . 0/r32/eax 0x10/disp8 . # copy *(ebp+16) to eax 1074 8b/copy 1/mod/*+disp8 0/rm32/eax . . . 0/r32/eax 4/disp8 . # copy *(eax+4) to eax 1075 # skip payload->allocid 1076 05/add-to-eax 4/imm32 1077 # if (eax == 0) abort 1078 3d/compare-eax-and 0/imm32 1079 74/jump-if-= $slice-to-string:abort/disp8 1080 # out->size = size-4 1081 89/copy 0/mod/indirect 0/rm32/eax . . . 1/r32/ecx . . # copy ecx to *eax 1082 81 5/subop/subtract 0/mod/indirect 0/rm32/eax . . . . . 4/imm32 # subtract 4 from *eax 1083 # save out 1084 50/push-eax 1085 $slice-to-string:initialize: 1086 # eax = _append-4(eax+4, eax+size, curr, max) # clobbering ecx 1087 # . . push args 1088 53/push-ebx 1089 52/push-edx 1090 # . . push eax+size (clobbering ecx) 1091 01/add 3/mod/direct 1/rm32/ecx . . . 0/r32/eax . . # add eax to ecx 1092 51/push-ecx 1093 # . . push eax+4 (clobbering eax) 1094 81 0/subop/add 3/mod/direct 0/rm32/eax . . . . . 4/imm32 # add to eax 1095 50/push-eax 1096 # . . call 1097 e8/call _append-4/disp32 1098 # . . discard args 1099 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0x10/imm32 # add to esp 1100 # restore out (assumes _append-4 can't error) 1101 58/pop-to-eax 1102 $slice-to-string:end: 1103 # . restore registers 1104 5e/pop-to-esi 1105 5b/pop-to-ebx 1106 5a/pop-to-edx 1107 59/pop-to-ecx 1108 58/pop-to-eax 1109 # . epilogue 1110 89/copy 3/mod/direct 4/rm32/esp . . . 5/r32/ebp . . # copy ebp to esp 1111 5d/pop-to-ebp 1112 c3/return 1113 1114 $slice-to-string:abort: 1115 # . _write(2/stderr, error) 1116 # . . push args 1117 68/push "slice-to-string: out of space\n"/imm32 1118 68/push 2/imm32/stderr 1119 # . . call 1120 e8/call _write/disp32 1121 # . . discard args 1122 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp 1123 # . syscall(exit, 1) 1124 bb/copy-to-ebx 1/imm32 1125 e8/call syscall_exit/disp32 1126 # never gets here 1127 1128 test-slice-to-string: 1129 # . prologue 1130 55/push-ebp 1131 89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp 1132 # var heap/edx: allocation-descriptor 1133 68/push 0/imm32/limit 1134 68/push 0/imm32/curr 1135 89/copy 3/mod/direct 2/rm32/edx . . . 4/r32/esp . . # copy esp to edx 1136 # heap = new-segment(512) 1137 # . . push args 1138 52/push-edx 1139 68/push 0x200/imm32 1140 # . . call 1141 e8/call new-segment/disp32 1142 # . . discard args 1143 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp 1144 # (eax..ecx) = "Abc" 1145 b8/copy-to-eax "Abc"/imm32 1146 8b/copy 0/mod/indirect 0/rm32/eax . . . 1/r32/ecx . . # copy *eax to ecx 1147 8d/copy-address 1/mod/*+disp8 4/rm32/sib 0/base/eax 1/index/ecx . 1/r32/ecx 4/disp8 . # copy eax+ecx+4 to ecx 1148 05/add-to-eax 4/imm32 1149 # var slice/ecx: slice = {eax, ecx} 1150 51/push-ecx 1151 50/push-eax 1152 89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx 1153 # var h/ebx: (handle array byte) 1154 68/push 0/imm32 1155 68/push 0/imm32 1156 89/copy 3/mod/direct 3/rm32/ebx . . . 4/r32/esp . . # copy esp to ebx 1157 # slice-to-string(heap, slice, h) 1158 # . . push args 1159 53/push-ebx 1160 51/push-ecx 1161 52/push-edx 1162 # . . call 1163 e8/call slice-to-string/disp32 1164 # . . discard args 1165 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32 # add to esp 1166 # eax = h->payload 1167 8b/copy 1/mod/*+disp8 3/rm32/ebx . . . 0/r32/eax 4/disp8 . # copy *(ebx+4) to eax 1168 # skip payload->allocid 1169 05/add-to-eax 4/imm32 1170 +-- 26 lines: #? # dump eax --------------------------------------------------------------------------------------------------------------------------------------------------------- 1196 # eax = string-equal?(eax, "Abc") 1197 # . . push args 1198 68/push "Abc"/imm32 1199 50/push-eax 1200 # . . call 1201 e8/call string-equal?/disp32 1202 # . . discard args 1203 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp 1204 # check-ints-equal(eax, 1, msg) 1205 # . . push args 1206 68/push "F - test-slice-to-string"/imm32 1207 68/push 1/imm32/true 1208 50/push-eax 1209 # . . call 1210 e8/call check-ints-equal/disp32 1211 # . . discard args 1212 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32 # add to esp 1213 # . reclaim locals 1214 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0x18/imm32 # add to esp 1215 # . epilogue 1216 89/copy 3/mod/direct 4/rm32/esp . . . 5/r32/ebp . . # copy ebp to esp 1217 5d/pop-to-ebp 1218 c3/return 1219 1220 # . . vim:nowrap:textwidth=0