# Some tokenization primitives. == code # instruction effective address register displacement immediate # . op subop mod rm32 base index scale r32 # . 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 # extract the next run of characters that are different from a given 'delimiter' (skipping multiple delimiters if necessary) # on reaching end of file, return an empty interval next-token-from-slice: # start: (addr byte), end: (addr byte), delimiter: byte, out: (addr slice) # . prologue 55/push-ebp 89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp # . save registers 50/push-eax 51/push-ecx 52/push-edx 57/push-edi # ecx = end 8b/copy 1/mod/*+disp8 5/rm32/ebp . . . 1/r32/ecx 0xc/disp8 . # copy *(ebp+12) to ecx # edx = delimiter 8b/copy 1/mod/*+disp8 5/rm32/ebp . . . 2/r32/edx 0x10/disp8 . # copy *(ebp+16) to edx # edi = out 8b/copy 1/mod/*+disp8 5/rm32/ebp . . . 7/r32/edi 0x14/disp8 . # copy *(ebp+20) to edi # eax = skip-chars-matching-in-slice(start, end, delimiter) # . . push args 52/push-edx 51/push-ecx ff 6/subop/push 1/mod/*+disp8 5/rm32/ebp . . . . 8/disp8 . # push *(ebp+8) # . . call e8/call skip-chars-matching-in-slice/disp32 # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32 # add to esp # out->start = eax 89/copy 0/mod/indirect 7/rm32/edi . . . 0/r32/eax . . # copy eax to *edi # eax = skip-chars-not-matching-in-slice(eax, end, delimiter) # . . push args 52/push-edx 51/push-ecx 50/push-eax # . . call e8/call skip-chars-not-matching-in-slice/disp32 # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32 # add to esp # out->end = eax 89/copy 1/mod/*+disp8 7/rm32/edi . . . 0/r32/eax 4/disp8 . # copy eax to *(edi+4) # . restore registers 5f/pop-to-edi 5a/pop-to-edx 59/pop-to-ecx 58/pop-to-eax # . epilogue 89/copy 3/mod/direct 4/rm32/esp . . . 5/r32/ebp . . # copy ebp to esp 5d/pop-to-ebp c3/return test-next-token-from-slice: # . prologue 55/push-ebp 89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp # (eax..ecx) = " ab" b8/copy-to-eax " ab"/imm32 8b/copy 0/mod/indirect 0/rm32/eax . . . 1/r32/ecx . . # copy *eax to ecx 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 05/add-to-eax 4/imm32 # var out/edi: slice 68/push 0/imm32/end 68/push 0/imm32/start 89/copy 3/mod/direct 7/rm32/edi . . . 4/r32/esp . . # copy esp to edi # next-token-from-slice(eax, ecx, 0x20/space, out) # . . push args 57/push-edi 68/push 0x20/imm32 51/push-ecx 50/pu
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html><head><title>Python: module ranger.ext.debug</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
</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.ext.html"><font color="#ffffff">ext</font></a>.debug</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/work/ranger/ranger/ext/debug.py">/home/hut/work/ranger/ranger/ext/debug.py</a></font></td></tr></table>
    <p></p>
<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="-log"><strong>log</strong></a>(*objects, **keywords)</dt><dd><tt>Writes&nbsp;objects&nbsp;to&nbsp;a&nbsp;logfile.<br>
Has&nbsp;the&nbsp;same&nbsp;arguments&nbsp;as&nbsp;print()&nbsp;in&nbsp;python3</tt></dd></dl>
 <dl><dt><a name="-trace"><strong>trace</strong></a>()</dt></dl>
</td></tr></table><p>
<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
<tr bgcolor="#55aa55">
<td colspan=3 valign=bottom>&nbsp;<br>
<font color="#ffffff" face="helvetica, arial"><big><strong>Data</strong></big></font></td></tr>
    
<tr><td bgcolor="#55aa55"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
<td width="100%"><strong>LOGFILE</strong> = '/tmp/errorlog'</td></tr></table>
</body></html>
tar --xattrs -xpvf $DATA_CNF/usr_etc.tar.gz --directory=$CHROOT/usr/etc else echo "1.1.7. dns resolver, copy resolv.conf;\n" cp /etc/resolv.conf $CHROOT/etc echo "1.1.9. Install Skeletons\n" cp -r $DATA_CNF/skel $CHROOT/etc/ cp $DATA_CNF/sudoers $CHROOT/etc/ echo "1.2.1. Set hostname and hosts;" cp $DATA_CNF/hosts $CHROOT/etc/ echo "1.2.5. File system table;" cp $DATA_CNF/fstab $CHROOT/etc/ chroot $CHROOT /bin/bash -c "mount >> /etc/fstab" echo "1.2.6. Initialization Scripts;" cp $DATA_CNF/rc.d/* $CHROOT/etc/rc.d/ cp $DATA_CNF/rc.conf $CHROOT/etc/ echo "1.3 Install Ports;" rm -fr $CHROOT/etc/ports cp -r $DATA_CNF/ports $CHROOT/etc/ports cp $DATA_CNF/ports.conf $CHROOT/etc/ports.conf echo "1.3.3 Configure pkgmk;" cp $DATA_CNF/pkgmk.conf $CHROOT/etc/pkgmk.conf cp $DATA_CNF/pkgmk.conf.harden $CHROOT/etc/pkgmk.conf.harden echo "1.3.4 Configure prt-get;" cp $DATA_CNF/prt-get.conf $CHROOT/etc/ fi echo "1.2.2. Set timezone;" chroot $CHROOT /bin/bash -c tzselect echo "1.2.3. Set locale;" chroot $CHROOT /bin/bash -c "localedef -i en_US -f UTF-8 en_US.UTF-8" } setup_users(){ echo "1.2.4.2. Create Administrator $ADMIN_USER;" chroot $CHROOT /usr/bin/env -i \ HOME=/root TERM="$TERM" PS1='\u:\w\$ ' \ PATH=/bin:/usr/bin:/sbin:/usr/sbin \ /bin/bash -c "useradd -U -m -k /etc/skel -s /bin/bash $ADMIN_USER" echo "1.2.4.3. Add Administrator $ADMIN_USER to wheel group;" chroot $CHROOT /bin/bash -c "usermod -a -G wheel $ADMIN_USER" echo "1.2.4.3. Uncomment to allow members of group wheel to execute any command\n # %wheel ALL=(ALL) ALL" echo "1.3.1. Ports Layout;" chroot --userspec=pkgmk:pkgmk $CHROOT /bin/bash -c "mkdir /usr/ports/{work,distfiles,packages,work,pkgbuild}" echo "1.3.2. Build as unprivileged user;" chroot $CHROOT /usr/bin/env -i \ HOME=/root TERM="$TERM" PS1='\u:\w\$ ' \ PATH=/bin:/usr/bin:/sbin:/usr/sbin \ /bin/bash -c "useradd -U -M -d /usr/ports -s /bin/false pkgmk" chroot $CHROOT /usr/bin/env -i \ HOME=/root TERM="$TERM" PS1='\u:\w\$ ' \ PATH=/bin:/usr/bin:/sbin:/usr/sbin \ /bin/bash -c "usermod -a -G pkgmk $ADMIN_USER" chroot $CHROOT /usr/bin/env -i \ HOME=/root TERM="$TERM" PS1='\u:\w\$ ' \ PATH=/bin:/usr/bin:/sbin:/usr/sbin \ /bin/bash -c "chown pkgmk /usr/ports/{distfiles,packages,work,pkgbuild}" chroot $CHROOT /usr/bin/env -i \ HOME=/root TERM="$TERM" PS1='\u:\w\$ ' \ PATH=/bin:/usr/bin:/sbin:/usr/sbin \ /bin/bash -c "chown pkgmk:pkgmk /usr/ports/pkgbuild" chroot $CHROOT /usr/bin/env -i \ HOME=/root TERM="$TERM" PS1='\u:\w\$ ' \ PATH=/bin:/usr/bin:/sbin:/usr/sbin \ /bin/bash -c "chmod g+w /usr/ports/pkgbuild" PKGMK_WRK="pkgmk /usr/ports/work tmpfs size=30G,gid=$(id -g pkgmk),uid=$(id -u pkgmk),defaults,mode=0750 0 0 >> /etc/fstab" chroot $CHROOT /usr/bin/env -i \ HOME=/root TERM="$TERM" PS1='\u:\w\$ ' \ PATH=/bin:/usr/bin:/sbin:/usr/sbin \ /bin/bash -c "echo ${PKGMK_WRK} >> /etc/fstab" } setup_config(){ vim $CHROOT/etc/rc.conf vim $CHROOT/etc/hosts vim $CHROOT/etc/resolv.conf vim $CHROOT/etc/fstab vim $CHROOT/etc/pkgmk.conf vim $CHROOT/etc/prt-get.conf } echo "ADMIN_USER=${ADMIN_USER}"; echo "CHROOT=${CHROOT}"; echo "DATA_CNF=${DATA_CNF}"; ConfirmOrExit setup_core setup_users setup_config 0xc/imm32 # add to esp # check-ints-equal(ecx-eax, 2, msg) # . . push args 68/push "F - test-skip-chars-matching-in-slice-none"/imm32 68/push 2/imm32 # . . push ecx-eax 29/subtract 3/mod/direct 1/rm32/ecx . . . 0/r32/eax . . # subtract eax from ecx 51/push-ecx # . . call e8/call check-ints-equal/disp32 # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32 # add to esp # end c3/return skip-chars-matching-whitespace-in-slice: # curr: (addr byte), end: (addr byte) -> curr/eax: (addr byte) # . prologue 55/push-ebp 89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp # . save registers 51/push-ecx 53/push-ebx # eax = curr 8b/copy 1/mod/*+disp8 5/rm32/ebp . . . 0/r32/eax 8/disp8 . # copy *(ebp+8) to eax # ecx = end 8b/copy 1/mod/*+disp8 5/rm32/ebp . . . 1/r32/ecx 0xc/disp8 . # copy *(ebp+12) to ecx # var c/ebx: byte = 0 31/xor 3/mod/direct 3/rm32/ebx . . . 3/r32/ebx . . # clear ebx $skip-chars-matching-whitespace-in-slice:loop: # if (curr >= end) break 39/compare 3/mod/direct 0/rm32/eax . . . 1/r32/ecx . . # compare eax with ecx 0f 83/jump-if-addr>= $skip-chars-matching-in-slice:end/disp32 # c = *curr 8a/copy-byte 0/mod/indirect 0/rm32/eax . . . 3/r32/BL . . # copy byte at *eax to BL # if (c == ' ') goto body 81 7/subop/compare 3/mod/direct 3/rm32/ebx . . . . . 0x20/imm32/space # compare ebx 74/jump-if-= $skip-chars-matching-whitespace-in-slice:body/disp8 # if (c == '\n') goto body 81 7/subop/compare 3/mod/direct 3/rm32/ebx . . . . . 0x0a/imm32/newline # compare ebx 74/jump-if-= $skip-chars-matching-whitespace-in-slice:body/disp8 # if (c == '\t') goto body 81 7/subop/compare 3/mod/direct 3/rm32/ebx . . . . . 0x09/imm32/tab # compare ebx 74/jump-if-= $skip-chars-matching-whitespace-in-slice:body/disp8 # if (c != '\r') break 81 7/subop/compare 3/mod/direct 3/rm32/ebx . . . . . 0x0d/imm32/cr # compare ebx 75/jump-if-!= $skip-chars-matching-whitespace-in-slice:end/disp8 $skip-chars-matching-whitespace-in-slice:body: # ++curr 40/increment-eax eb/jump $skip-chars-matching-whitespace-in-slice:loop/disp8 $skip-chars-matching-whitespace-in-slice:end: # . restore registers 5b/pop-to-ebx 59/pop-to-ecx # . epilogue 89/copy 3/mod/direct 4/rm32/esp . . . 5/r32/ebp . . # copy ebp to esp 5d/pop-to-ebp c3/return test-skip-chars-matching-whitespace-in-slice: # (eax..ecx) = " \nab" b8/copy-to-eax " \nab"/imm32 8b/copy 0/mod/indirect 0/rm32/eax . . . 1/r32/ecx . . # copy *eax to ecx 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 05/add-to-eax 4/imm32 # eax = skip-chars-matching-whitespace-in-slice(eax, ecx) # . . push args 51/push-ecx 50/push-eax # . . call e8/call skip-chars-matching-whitespace-in-slice/disp32 # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp # check-ints-equal(ecx-eax, 2, msg) # . . push args 68/push "F - test-skip-chars-matching-whitespace-in-slice"/imm32 68/push 2/imm32 # . . push ecx-eax 29/subtract 3/mod/direct 1/rm32/ecx . . . 0/r32/eax . . # subtract eax from ecx 51/push-ecx # . . call e8/call check-ints-equal/disp32 # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32 # add to esp # end c3/return # minor fork of 'skip-chars-matching-in-slice' skip-chars-not-matching-in-slice: # curr: (addr byte), end: (addr byte), delimiter: byte -> curr/eax: (addr byte) # . prologue 55/push-ebp 89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp # . save registers 51/push-ecx 52/push-edx 53/push-ebx # eax = curr 8b/copy 1/mod/*+disp8 5/rm32/ebp . . . 0/r32/eax 8/disp8 . # copy *(ebp+8) to eax # ecx = end 8b/copy 1/mod/*+disp8 5/rm32/ebp . . . 1/r32/ecx 0xc/disp8 . # copy *(ebp+12) to ecx # edx = delimiter 8b/copy 1/mod/*+disp8 5/rm32/ebp . . . 2/r32/edx 0x10/disp8 . # copy *(ebp+16) to edx # var c/ebx: byte = 0 31/xor 3/mod/direct 3/rm32/ebx . . . 3/r32/ebx . . # clear ebx $skip-chars-not-matching-in-slice:loop: # if (curr >= end) break 39/compare 3/mod/direct 0/rm32/eax . . . 1/r32/ecx . . # compare eax with ecx 73/jump-if-addr>= $skip-chars-not-matching-in-slice:end/disp8 # c = *curr 8a/copy-byte 0/mod/indirect 0/rm32/eax . . . 3/r32/BL . . # copy byte at *eax to BL # if (c == delimiter) break 39/compare 3/mod/direct 3/rm32/ebx . . . 2/r32/edx . . # compare ebx and edx 74/jump-if-= $skip-chars-not-matching-in-slice:end/disp8 # ++curr 40/increment-eax eb/jump $skip-chars-not-matching-in-slice:loop/disp8 $skip-chars-not-matching-in-slice:end: # . restore registers 5b/pop-to-ebx 5a/pop-to-edx 59/pop-to-ecx # . epilogue 89/copy 3/mod/direct 4/rm32/esp . . . 5/r32/ebp . . # copy ebp to esp 5d/pop-to-ebp c3/return test-skip-chars-not-matching-in-slice: # (eax..ecx) = "ab " b8/copy-to-eax "ab "/imm32 8b/copy 0/mod/indirect 0/rm32/eax . . . 1/r32/ecx . . # copy *eax to ecx 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 05/add-to-eax 4/imm32 # eax = skip-chars-not-matching-in-slice(eax, ecx, 0x20/space) # . . push args 68/push 0x20/imm32/space 51/push-ecx 50/push-eax # . . call e8/call skip-chars-not-matching-in-slice/disp32 # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32 # add to esp # check-ints-equal(ecx-eax, 1, msg) # . . push args 68/push "F - test-skip-chars-not-matching-in-slice"/imm32 68/push 1/imm32 # . . push ecx-eax 29/subtract 3/mod/direct 1/rm32/ecx . . . 0/r32/eax . . # subtract eax from ecx 51/push-ecx # . . call e8/call check-ints-equal/disp32 # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32 # add to esp # end c3/return test-skip-chars-not-matching-in-slice-none: # (eax..ecx) = " ab" b8/copy-to-eax " ab"/imm32 8b/copy 0/mod/indirect 0/rm32/eax . . . 1/r32/ecx . . # copy *eax to ecx 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 05/add-to-eax 4/imm32 # eax = skip-chars-not-matching-in-slice(eax, ecx, 0x20/space) # . . push args 68/push 0x20/imm32/space 51/push-ecx 50/push-eax # . . call e8/call skip-chars-not-matching-in-slice/disp32 # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32 # add to esp # check-ints-equal(ecx-eax, 3, msg) # . . push args 68/push "F - test-skip-chars-not-matching-in-slice-none"/imm32 68/push 3/imm32 # . . push ecx-eax 29/subtract 3/mod/direct 1/rm32/ecx . . . 0/r32/eax . . # subtract eax from ecx 51/push-ecx # . . call e8/call check-ints-equal/disp32 # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32 # add to esp # end c3/return test-skip-chars-not-matching-in-slice-all: # (eax..ecx) = "ab" b8/copy-to-eax "ab"/imm32 8b/copy 0/mod/indirect 0/rm32/eax . . . 1/r32/ecx . . # copy *eax to ecx 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 05/add-to-eax 4/imm32 # eax = skip-chars-not-matching-in-slice(eax, ecx, 0x20/space) # . . push args 68/push 0x20/imm32/space 51/push-ecx 50/push-eax # . . call e8/call skip-chars-not-matching-in-slice/disp32 # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32 # add to esp # check-ints-equal(ecx-eax, 0, msg) # . . push args 68/push "F - test-skip-chars-not-matching-in-slice-all"/imm32 68/push 0/imm32 # . . push ecx-eax 29/subtract 3/mod/direct 1/rm32/ecx . . . 0/r32/eax . . # subtract eax from ecx 51/push-ecx # . . call e8/call check-ints-equal/disp32 # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32 # add to esp # end c3/return skip-chars-not-matching-whitespace-in-slice: # curr: (addr byte), end: (addr byte) -> curr/eax: (addr byte) # . prologue 55/push-ebp 89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp # . save registers 51/push-ecx 53/push-ebx # eax = curr 8b/copy 1/mod/*+disp8 5/rm32/ebp . . . 0/r32/eax 8/disp8 . # copy *(ebp+8) to eax # ecx = end 8b/copy 1/mod/*+disp8 5/rm32/ebp . . . 1/r32/ecx 0xc/disp8 . # copy *(ebp+12) to ecx # var c/ebx: byte = 0 31/xor 3/mod/direct 3/rm32/ebx . . . 3/r32/ebx . . # clear ebx $skip-chars-not-matching-whitespace-in-slice:loop: # if (curr >= end) break 39/compare 3/mod/direct 0/rm32/eax . . . 1/r32/ecx . . # compare eax with ecx 0f 83/jump-if-addr>= $skip-chars-not-matching-in-slice:end/disp32 # c = *curr 8a/copy-byte 0/mod/indirect 0/rm32/eax . . . 3/r32/BL . . # copy byte at *eax to BL # if (c == ' ') break 81 7/subop/compare 3/mod/direct 3/rm32/ebx . . . . . 0x20/imm32/space # compare ebx 74/jump-if-= $skip-chars-not-matching-whitespace-in-slice:end/disp8 # if (c == '\n') break 81 7/subop/compare 3/mod/direct 3/rm32/ebx . . . . . 0x0a/imm32/newline # compare ebx 74/jump-if-= $skip-chars-not-matching-whitespace-in-slice:end/disp8 # if (c == '\t') break 81 7/subop/compare 3/mod/direct 3/rm32/ebx . . . . . 0x09/imm32/tab # compare ebx 74/jump-if-= $skip-chars-not-matching-whitespace-in-slice:end/disp8 # if (c == '\r') break 81 7/subop/compare 3/mod/direct 3/rm32/ebx . . . . . 0x0d/imm32/cr # compare ebx 74/jump-if-= $skip-chars-not-matching-whitespace-in-slice:end/disp8 # ++curr 40/increment-eax eb/jump $skip-chars-not-matching-whitespace-in-slice:loop/disp8 $skip-chars-not-matching-whitespace-in-slice:end: # . restore registers 5b/pop-to-ebx 59/pop-to-ecx # . epilogue 89/copy 3/mod/direct 4/rm32/esp . . . 5/r32/ebp . . # copy ebp to esp 5d/pop-to-ebp c3/return test-skip-chars-not-matching-whitespace-in-slice: # (eax..ecx) = "ab\n" b8/copy-to-eax "ab\n"/imm32 8b/copy 0/mod/indirect 0/rm32/eax . . . 1/r32/ecx . . # copy *eax to ecx 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 05/add-to-eax 4/imm32 # eax = skip-chars-not-matching-whitespace-in-slice(eax, ecx) # . . push args 51/push-ecx 50/push-eax # . . call e8/call skip-chars-not-matching-whitespace-in-slice/disp32 # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp # check-ints-equal(ecx-eax, 1, msg) # . . push args 68/push "F - test-skip-chars-not-matching-whitespace-in-slice"/imm32 68/push 1/imm32 # . . push ecx-eax 29/subtract 3/mod/direct 1/rm32/ecx . . . 0/r32/eax . . # subtract eax from ecx 51/push-ecx # . . call e8/call check-ints-equal/disp32 # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32 # add to esp # end c3/return # update line->read to end of string literal surrounded by double quotes # line->read must start out at a double-quote skip-string: # line: (addr stream byte) # . prologue 55/push-ebp 89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp # . save registers 50/push-eax 51/push-ecx 52/push-edx # ecx = line 8b/copy 1/mod/*+disp8 5/rm32/ebp . . 1/r32/ecx 8/disp8 . # copy *(ebp+8) to ecx # eax = skip-string-in-slice(&line->data[line->read], &line->data[line->write]) # . . push &line->data[line->write] 8b/copy 1/mod/*+disp8 1/rm32/ecx . . 2/r32/edx 8/disp8 . # copy *(ecx+8) to edx 8d/copy-address 1/mod/*+disp8 4/rm32/sib 1/base/ecx 2/index/edx . 2/r32/edx 0xc/disp8 . # copy ecx+edx+12 to edx 52/push-edx # . . push &line->data[line->read] 8b/copy 1/mod/*+disp8 1/rm32/ecx . . 2/r32/edx 4/disp8 . # copy *(ecx+4) to edx 8d/copy-address 1/mod/*+disp8 4/rm32/sib 1/base/ecx 2/index/edx . 2/r32/edx 0xc/disp8 . # copy ecx+edx+12 to edx 52/push-edx # . . call e8/call skip-string-in-slice/disp32 # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp # line->read = eax - line->data 29/subtract 3/mod/direct 0/rm32/eax . . . 1/r32/ecx . . # subtract ecx from eax 2d/subtract-from-eax 0xc/imm32 89/copy 1/mod/*+disp8 1/rm32/ecx . . 0/r32/eax 4/disp8 . # copy eax to *(ecx+4) $skip-string:end: # . restore registers 5a/pop-to-edx 59/pop-to-ecx 58/pop-to-eax # . epilogue 89/copy 3/mod/direct 4/rm32/esp . . . 5/r32/ebp . . # copy ebp to esp 5d/pop-to-ebp c3/return test-skip-string: # . prologue 55/push-ebp 89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp # setup # . clear-stream(_test-stream) # . . push args 68/push _test-stream/imm32 # . . call e8/call clear-stream/disp32 # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp # . write(_test-stream, "\"abc\" def") # . indices: 0123 45 # . . push args 68/push "\"abc\" def"/imm32 68/push _test-stream/imm32 # . . call e8/call write/disp32 # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp # precondition: line->read == 0 # . . push args 68/push "F - test-skip-string/precondition"/imm32 68/push 0/imm32 b8/copy-to-eax _test-stream/imm32 ff 6/subop/push 1/mod/*+disp8 0/rm32/eax . . . . 4/disp8 . # push *(eax+4) # . . call e8/call check-ints-equal/disp32 # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32 # add to esp # skip-string(_test-stream) # . . push args 68/push _test-stream/imm32 # . . call e8/call skip-string/disp32 # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp # check-ints-equal(line->read, 5, msg) # . . push args 68/push "F - test-skip-string"/imm32 68/push 5/imm32 b8/copy-to-eax _test-stream/imm32 ff 6/subop/push 1/mod/*+disp8 0/rm32/eax . . . . 4/disp8 . # push *(eax+4) # . . call e8/call check-ints-equal/disp32 # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32 # add to esp # . epilogue 89/copy 3/mod/direct 4/rm32/esp . . . 5/r32/ebp . . # copy ebp to esp 5d/pop-to-ebp c3/return test-skip-string-ignores-spaces: # . prologue 55/push-ebp 89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp # setup # . clear-stream(_test-stream) # . . push args 68/push _test-stream/imm32 # . . call e8/call clear-stream/disp32 # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp # . write(_test-stream, "\"a b\"/yz") # . indices: 0123 45 # . . push args 68/push "\"a b\"/yz"/imm32 68/push _test-stream/imm32 # . . call e8/call write/disp32 # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp # precondition: line->read == 0 # . . push args 68/push "F - test-skip-string-ignores-spaces/precondition"/imm32 68/push 0/imm32 b8/copy-to-eax _test-stream/imm32 ff 6/subop/push 1/mod/*+disp8 0/rm32/eax . . . . 4/disp8 . # push *(eax+4) # . . call e8/call check-ints-equal/disp32 # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32 # add to esp # skip-string(_test-stream) # . . push args 68/push _test-stream/imm32 # . . call e8/call skip-string/disp32 # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp # check-ints-equal(line->read, 5, msg) # . . push args 68/push "F - test-skip-string-ignores-spaces"/imm32 68/push 5/imm32 b8/copy-to-eax _test-stream/imm32 ff 6/subop/push 1/mod/*+disp8 0/rm32/eax . . . . 4/disp8 . # push *(eax+4) # . . call e8/call check-ints-equal/disp32 # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32 # add to esp # . epilogue 89/copy 3/mod/direct 4/rm32/esp . . . 5/r32/ebp . . # copy ebp to esp 5d/pop-to-ebp c3/return test-skip-string-ignores-escapes: # . prologue 55/push-ebp 89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp # setup # . clear-stream(_test-stream) # . . push args 68/push _test-stream/imm32 # . . call e8/call clear-stream/disp32 # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp # . write(_test-stream, "\"a\\\"b\"/yz") # . indices: 01 2 34 56 # . . push args 68/push "\"a\\\"b\"/yz"/imm32 68/push _test-stream/imm32 # . . call e8/call write/disp32 # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp # precondition: line->read == 0 # . . push args 68/push "F - test-skip-string-ignores-escapes/precondition"/imm32 68/push 0/imm32 b8/copy-to-eax _test-stream/imm32 ff 6/subop/push 1/mod/*+disp8 0/rm32/eax . . . . 4/disp8 . # push *(eax+4) # . . call e8/call check-ints-equal/disp32 # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32 # add to esp # skip-string(_test-stream) # . . push args 68/push _test-stream/imm32 # . . call e8/call skip-string/disp32 # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp # check-ints-equal(line->read, 6, msg) # . . push args 68/push "F - test-skip-string-ignores-escapes"/imm32 68/push 6/imm32 b8/copy-to-eax _test-stream/imm32 ff 6/subop/push 1/mod/*+disp8 0/rm32/eax . . . . 4/disp8 . # push *(eax+4) # . . call e8/call check-ints-equal/disp32 # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32 # add to esp # . epilogue 89/copy 3/mod/direct 4/rm32/esp . . . 5/r32/ebp . . # copy ebp to esp 5d/pop-to-ebp c3/return test-skip-string-works-from-mid-stream: # . prologue 55/push-ebp 89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp # setup # . clear-stream(_test-stream) # . . push args 68/push _test-stream/imm32 # . . call e8/call clear-stream/disp32 # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp # . write(_test-stream, "0 \"a\\\"b\"/yz") # . indices: 01 2 34 56 # . . push args 68/push "0 \"a\\\"b\"/yz"/imm32 68/push _test-stream/imm32 # . . call e8/call write/disp32 # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp # precondition: line->read == 2 b8/copy-to-eax _test-stream/imm32 c7 0/subop/copy 1/mod/*+disp8 0/rm32/eax . . . . 4/disp8 2/imm32 # copy to *(eax+4) # skip-string(_test-stream) # . . push args 68/push _test-stream/imm32 # . . call e8/call skip-string/disp32 # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp # check-ints-equal(line->read, 8, msg) # . . push args 68/push "F - test-skip-string-works-from-mid-stream"/imm32 68/push 8/imm32 b8/copy-to-eax _test-stream/imm32 ff 6/subop/push 1/mod/*+disp8 0/rm32/eax . . . . 4/disp8 . # push *(eax+4) # . . call e8/call check-ints-equal/disp32 # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32 # add to esp # . epilogue 89/copy 3/mod/direct 4/rm32/esp . . . 5/r32/ebp . . # copy ebp to esp 5d/pop-to-ebp c3/return skip-string-in-slice: # curr: (addr byte), end: (addr byte) -> curr/eax: (addr byte) # . prologue 55/push-ebp 89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp # . save registers 51/push-ecx 52/push-edx 53/push-ebx # ecx = curr 8b/copy 1/mod/*+disp8 5/rm32/ebp . . 1/r32/ecx 8/disp8 . # copy *(ebp+8) to ecx # edx = end 8b/copy 1/mod/*+disp8 5/rm32/ebp . . 2/r32/edx 0xc/disp8 . # copy *(ebp+12) to edx # var c/eax: byte = 0 31/xor 3/mod/direct 0/rm32/eax . . . 0/r32/eax . . # clear eax # skip initial dquote 41/increment-ecx $skip-string-in-slice:loop: # if (curr >= end) return curr 39/compare 3/mod/direct 1/rm32/ecx . . . 2/r32/edx . . # compare ecx with edx 73/jump-if-addr>= $skip-string-in-slice:return-curr/disp8 # c = *curr 8a/copy-byte 0/mod/indirect 1/rm32/ecx . . . 0/r32/AL . . # copy byte at *ecx to AL $skip-string-in-slice:dquote: # if (c == '"') break 3d/compare-eax-and 0x22/imm32/double-quote 74/jump-if-= $skip-string-in-slice:break/disp8 $skip-string-in-slice:check-for-escape: # if (c == '\') escape next char 3d/compare-eax-and 0x5c/imm32/backslash 75/jump-if-!= $skip-string-in-slice:continue/disp8 $skip-string-in-slice:escape: 41/increment-ecx $skip-string-in-slice:continue: # ++curr 41/increment-ecx eb/jump $skip-string-in-slice:loop/disp8 $skip-string-in-slice:break: # skip final dquote 41/increment-ecx $skip-string-in-slice:return-curr: # return curr 89/copy 3/mod/direct 0/rm32/eax . . . 1/r32/ecx . . # copy ecx to eax $skip-string-in-slice:end: # . restore registers 5b/pop-to-ebx 5a/pop-to-edx 59/pop-to-ecx # . epilogue 89/copy 3/mod/direct 4/rm32/esp . . . 5/r32/ebp . . # copy ebp to esp 5d/pop-to-ebp c3/return test-skip-string-in-slice: # . prologue 55/push-ebp 89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp # setup: (eax..ecx) = "\"abc\" def" b8/copy-to-eax "\"abc\" def"/imm32 8b/copy 0/mod/indirect 0/rm32/eax . . . 1/r32/ecx . . # copy *eax to ecx 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 05/add-to-eax 4/imm32 # eax = skip-string-in-slice(eax, ecx) # . . push args 51/push-ecx 50/push-eax # . . call e8/call skip-string-in-slice/disp32 # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp # check-ints-equal(ecx-eax, 4, msg) # number of chars remaining after the string literal # . . push args 68/push "F - test-skip-string-in-slice"/imm32 68/push 4/imm32 # . . push ecx-eax 29/subtract 3/mod/direct 1/rm32/ecx . . . 0/r32/eax . . # subtract eax from ecx 51/push-ecx # . . call e8/call check-ints-equal/disp32 # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32 # add to esp # . epilogue 89/copy 3/mod/direct 4/rm32/esp . . . 5/r32/ebp . . # copy ebp to esp 5d/pop-to-ebp c3/return test-skip-string-in-slice-ignores-spaces: # . prologue 55/push-ebp 89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp # setup: (eax..ecx) = "\"a b\"/yz" b8/copy-to-eax "\"a b\"/yz"/imm32 8b/copy 0/mod/indirect 0/rm32/eax . . . 1/r32/ecx . . # copy *eax to ecx 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 05/add-to-eax 4/imm32 # eax = skip-string-in-slice(eax, ecx) # . . push args 51/push-ecx 50/push-eax # . . call e8/call skip-string-in-slice/disp32 # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp # check-ints-equal(ecx-eax, 3, msg) # number of chars remaining after the string literal # . . push args 68/push "F - test-skip-string-in-slice-ignores-spaces"/imm32 68/push 3/imm32 # . . push ecx-eax 29/subtract 3/mod/direct 1/rm32/ecx . . . 0/r32/eax . . # subtract eax from ecx 51/push-ecx # . . call e8/call check-ints-equal/disp32 # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32 # add to esp # . epilogue 89/copy 3/mod/direct 4/rm32/esp . . . 5/r32/ebp . . # copy ebp to esp 5d/pop-to-ebp c3/return test-skip-string-in-slice-ignores-escapes: # . prologue 55/push-ebp 89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp # setup: (eax..ecx) = "\"a\\\"b\"/yz" b8/copy-to-eax "\"a\\\"b\"/yz"/imm32 8b/copy 0/mod/indirect 0/rm32/eax . . . 1/r32/ecx . . # copy *eax to ecx 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 05/add-to-eax 4/imm32 # eax = skip-string-in-slice(eax, ecx) # . . push args 51/push-ecx 50/push-eax # . . call e8/call skip-string-in-slice/disp32 # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp # check-ints-equal(ecx-eax, 3, msg) # number of chars remaining after the string literal # . . push args 68/push "F - test-skip-string-in-slice-ignores-escapes"/imm32 68/push 3/imm32 # . . push ecx-eax 29/subtract 3/mod/direct 1/rm32/ecx . . . 0/r32/eax . . # subtract eax from ecx 51/push-ecx # . . call e8/call check-ints-equal/disp32 # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32 # add to esp # . epilogue 89/copy 3/mod/direct 4/rm32/esp . . . 5/r32/ebp . . # copy ebp to esp 5d/pop-to-ebp c3/return test-skip-string-in-slice-stops-at-end: # . prologue 55/push-ebp 89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp # setup: (eax..ecx) = "\"abc" # unbalanced dquote b8/copy-to-eax "\"abc"/imm32 8b/copy 0/mod/indirect 0/rm32/eax . . . 1/r32/ecx . . # copy *eax to ecx 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 05/add-to-eax 4/imm32 # eax = skip-string-in-slice(eax, ecx) # . . push args 51/push-ecx 50/push-eax # . . call e8/call skip-string-in-slice/disp32 # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp # check-ints-equal(ecx-eax, 0, msg) # skipped to end of slice # . . push args 68/push "F - test-skip-string-in-slice-stops-at-end"/imm32 68/push 0/imm32 # . . push ecx-eax 29/subtract 3/mod/direct 1/rm32/ecx . . . 0/r32/eax . . # subtract eax from ecx 51/push-ecx # . . call e8/call check-ints-equal/disp32 # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32 # add to esp # . epilogue 89/copy 3/mod/direct 4/rm32/esp . . . 5/r32/ebp . . # copy ebp to esp 5d/pop-to-ebp c3/return # update line->read to ')' # line->read ends at ')' skip-until-close-paren: # line: (addr stream byte) # . prologue 55/push-ebp 89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp # . save registers 50/push-eax 51/push-ecx 52/push-edx # ecx = line 8b/copy 1/mod/*+disp8 5/rm32/ebp . . 1/r32/ecx 8/disp8 . # copy *(ebp+8) to ecx # eax = skip-until-close-paren-in-slice(&line->data[line->read], &line->data[line->write]) # . . push &line->data[line->write] 8b/copy 1/mod/*+disp8 1/rm32/ecx . . 2/r32/edx 8/disp8 . # copy *(ecx+8) to edx 8d/copy-address 1/mod/*+disp8 4/rm32/sib 1/base/ecx 2/index/edx . 2/r32/edx 0xc/disp8 . # copy ecx+edx+12 to edx 52/push-edx # . . push &line->data[line->read] 8b/copy 1/mod/*+disp8 1/rm32/ecx . . 2/r32/edx 4/disp8 . # copy *(ecx+4) to edx 8d/copy-address 1/mod/*+disp8 4/rm32/sib 1/base/ecx 2/index/edx . 2/r32/edx 0xc/disp8 . # copy ecx+edx+12 to edx 52/push-edx # . . call e8/call skip-until-close-paren-in-slice/disp32 # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp # line->read = eax - line->data 29/subtract 3/mod/direct 0/rm32/eax . . . 1/r32/ecx . . # subtract ecx from eax 2d/subtract-from-eax 0xc/imm32 89/copy 1/mod/*+disp8 1/rm32/ecx . . 0/r32/eax 4/disp8 . # copy eax to *(ecx+4) $skip-until-close-paren:end: # . restore registers 5a/pop-to-edx 59/pop-to-ecx 58/pop-to-eax # . epilogue 89/copy 3/mod/direct 4/rm32/esp . . . 5/r32/ebp . . # copy ebp to esp 5d/pop-to-ebp c3/return test-skip-until-close-paren: # . prologue 55/push-ebp 89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp # setup # . clear-stream(_test-stream) # . . push args 68/push _test-stream/imm32 # . . call e8/call clear-stream/disp32 # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp # . write(_test-stream, "*(abc) def") # . indices: 0123 45 # . . push args 68/push "*(abc) def"/imm32 68/push _test-stream/imm32 # . . call e8/call write/disp32 # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp # precondition: line->read == 0 # . . push args 68/push "F - test-skip-until-close-paren/precondition"/imm32 68/push 0/imm32 b8/copy-to-eax _test-stream/imm32 ff 6/subop/push 1/mod/*+disp8 0/rm32/eax . . . . 4/disp8 . # push *(eax+4) # . . call e8/call check-ints-equal/disp32 # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32 # add to esp # skip-until-close-paren(_test-stream) # . . push args 68/push _test-stream/imm32 # . . call e8/call skip-until-close-paren/disp32 # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp # check-ints-equal(line->read, 5, msg) # . . push args 68/push "F - test-skip-until-close-paren"/imm32 68/push 5/imm32 b8/copy-to-eax _test-stream/imm32 ff 6/subop/push 1/mod/*+disp8 0/rm32/eax . . . . 4/disp8 . # push *(eax+4) # . . call e8/call check-ints-equal/disp32 # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32 # add to esp # . epilogue 89/copy 3/mod/direct 4/rm32/esp . . . 5/r32/ebp . . # copy ebp to esp 5d/pop-to-ebp c3/return test-skip-until-close-paren-ignores-spaces: # . prologue 55/push-ebp 89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp # setup # . clear-stream(_test-stream) # . . push args 68/push _test-stream/imm32 # . . call e8/call clear-stream/disp32 # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp # . write(_test-stream, "*(a b)/yz") # . . push args 68/push "*(a b)/yz"/imm32 68/push _test-stream/imm32 # . . call e8/call write/disp32 # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp # precondition: line->read == 0 # . . push args 68/push "F - test-skip-until-close-paren-ignores-spaces/precondition"/imm32 68/push 0/imm32 b8/copy-to-eax _test-stream/imm32 ff 6/subop/push 1/mod/*+disp8 0/rm32/eax . . . . 4/disp8 . # push *(eax+4) # . . call e8/call check-ints-equal/disp32 # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32 # add to esp # skip-until-close-paren(_test-stream) # . . push args 68/push _test-stream/imm32 # . . call e8/call skip-until-close-paren/disp32 # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp # check-ints-equal(line->read, 5, msg) # . . push args 68/push "F - test-skip-until-close-paren-ignores-spaces"/imm32 68/push 5/imm32 b8/copy-to-eax _test-stream/imm32 ff 6/subop/push 1/mod/*+disp8 0/rm32/eax . . . . 4/disp8 . # push *(eax+4) # . . call e8/call check-ints-equal/disp32 # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32 # add to esp # . epilogue 89/copy 3/mod/direct 4/rm32/esp . . . 5/r32/ebp . . # copy ebp to esp 5d/pop-to-ebp c3/return test-skip-until-close-paren-works-from-mid-stream: # . prologue 55/push-ebp 89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp # setup # . clear-stream(_test-stream) # . . push args 68/push _test-stream/imm32 # . . call e8/call clear-stream/disp32 # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp # . write(_test-stream, "0 *(a b)/yz") # . . push args 68/push "0 *(a b)/yz"/imm32 68/push _test-stream/imm32 # . . call e8/call write/disp32 # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp # precondition: _test-stream->read == 2 b8/copy-to-eax _test-stream/imm32 c7 0/subop/copy 1/mod/*+disp8 0/rm32/eax . . . . 4/disp8 2/imm32 # copy to *(eax+4) # skip-until-close-paren(_test-stream) # . . push args 68/push _test-stream/imm32 # . . call e8/call skip-until-close-paren/disp32 # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp # check-ints-equal(_test-stream->read, 7, msg) # . . push args 68/push "F - test-skip-until-close-paren-works-from-mid-stream"/imm32 68/push 7/imm32 b8/copy-to-eax _test-stream/imm32 ff 6/subop/push 1/mod/*+disp8 0/rm32/eax . . . . 4/disp8 . # push *(eax+4) # . . call e8/call check-ints-equal/disp32 # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32 # add to esp # . epilogue 89/copy 3/mod/direct 4/rm32/esp . . . 5/r32/ebp . . # copy ebp to esp 5d/pop-to-ebp c3/return skip-until-close-paren-in-slice: # curr: (addr byte), end: (addr byte) -> curr/eax: (addr byte) # . prologue 55/push-ebp 89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp # . save registers 51/push-ecx 52/push-edx # ecx = curr 8b/copy 1/mod/*+disp8 5/rm32/ebp . . 1/r32/ecx 8/disp8 . # copy *(ebp+8) to ecx # edx = end 8b/copy 1/mod/*+disp8 5/rm32/ebp . . 2/r32/edx 0xc/disp8 . # copy *(ebp+12) to edx # var c/eax: byte = 0 31/xor 3/mod/direct 0/rm32/eax . . . 0/r32/eax . . # clear eax # skip initial dquote 41/increment-ecx $skip-until-close-paren-in-slice:loop: # if (curr >= end) break 39/compare 3/mod/direct 1/rm32/ecx . . . 2/r32/edx . . # compare ecx with edx 73/jump-if-addr>= $skip-until-close-paren-in-slice:break/disp8 # c = *curr 8a/copy-byte 0/mod/indirect 1/rm32/ecx . . . 0/r32/AL . . # copy byte at *ecx to AL $skip-until-close-paren-in-slice:check-close: # if (c == ')') break 3d/compare-eax-and 0x29/imm32/close-paren 74/jump-if-= $skip-until-close-paren-in-slice:break/disp8 # ++curr 41/increment-ecx eb/jump $skip-until-close-paren-in-slice:loop/disp8 $skip-until-close-paren-in-slice:break: # return curr 89/copy 3/mod/direct 0/rm32/eax . . . 1/r32/ecx . . # copy ecx to eax $skip-until-close-paren-in-slice:end: # . restore registers 5a/pop-to-edx 59/pop-to-ecx # . epilogue 89/copy 3/mod/direct 4/rm32/esp . . . 5/r32/ebp . . # copy ebp to esp 5d/pop-to-ebp c3/return test-skip-until-close-paren-in-slice: # . prologue 55/push-ebp 89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp # setup: (eax..ecx) = "*(abc) def" b8/copy-to-eax "*(abc) def"/imm32 8b/copy 0/mod/indirect 0/rm32/eax . . . 1/r32/ecx . . # copy *eax to ecx 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 05/add-to-eax 4/imm32 # eax = skip-until-close-paren-in-slice(eax, ecx) # . . push args 51/push-ecx 50/push-eax # . . call e8/call skip-until-close-paren-in-slice/disp32 # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp # check-ints-equal(ecx-eax, 5, msg) # eax is at the ')' # . . push args 68/push "F - test-skip-until-close-paren-in-slice"/imm32 68/push 5/imm32 # . . push ecx-eax 29/subtract 3/mod/direct 1/rm32/ecx . . . 0/r32/eax . . # subtract eax from ecx 51/push-ecx # . . call e8/call check-ints-equal/disp32 # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32 # add to esp # . epilogue 89/copy 3/mod/direct 4/rm32/esp . . . 5/r32/ebp . . # copy ebp to esp 5d/pop-to-ebp c3/return test-skip-until-close-paren-in-slice-ignores-spaces: # . prologue 55/push-ebp 89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp # setup: (eax..ecx) = "*(a b)/yz" b8/copy-to-eax "*(a b)/yz"/imm32 8b/copy 0/mod/indirect 0/rm32/eax . . . 1/r32/ecx . . # copy *eax to ecx 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 05/add-to-eax 4/imm32 # eax = skip-until-close-paren-in-slice(eax, ecx) # . . push args 51/push-ecx 50/push-eax # . . call e8/call skip-until-close-paren-in-slice/disp32 # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp # check-ints-equal(ecx-eax, 4, msg) # eax is at the ')' # . . push args 68/push "F - test-skip-until-close-paren-in-slice-ignores-spaces"/imm32 68/push 4/imm32 # . . push ecx-eax 29/subtract 3/mod/direct 1/rm32/ecx . . . 0/r32/eax . . # subtract eax from ecx 51/push-ecx # . . call e8/call check-ints-equal/disp32 # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32 # add to esp # . epilogue 89/copy 3/mod/direct 4/rm32/esp . . . 5/r32/ebp . . # copy ebp to esp 5d/pop-to-ebp c3/return test-skip-until-close-paren-in-slice-stops-at-end: # . prologue 55/push-ebp 89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp # setup: (eax..ecx) = "*(abc" # unbalanced dquote b8/copy-to-eax "*(abc"/imm32 8b/copy 0/mod/indirect 0/rm32/eax . . . 1/r32/ecx . . # copy *eax to ecx 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 05/add-to-eax 4/imm32 # eax = skip-until-close-paren-in-slice(eax, ecx) # . . push args 51/push-ecx 50/push-eax # . . call e8/call skip-until-close-paren-in-slice/disp32 # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp # check-ints-equal(ecx-eax, 0, msg) # skipped to end of slice # . . push args 68/push "F - test-skip-until-close-paren-in-slice-stops-at-end"/imm32 68/push 0/imm32 # . . push ecx-eax 29/subtract 3/mod/direct 1/rm32/ecx . . . 0/r32/eax . . # subtract eax from ecx 51/push-ecx # . . call e8/call check-ints-equal/disp32 # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32 # add to esp # . epilogue 89/copy 3/mod/direct 4/rm32/esp . . . 5/r32/ebp . . # copy ebp to esp 5d/pop-to-ebp c3/return # . . vim:nowrap:textwidth=0