diff options
Diffstat (limited to 'linux/109stream-equal.subx')
-rw-r--r-- | linux/109stream-equal.subx | 595 |
1 files changed, 595 insertions, 0 deletions
diff --git a/linux/109stream-equal.subx b/linux/109stream-equal.subx new file mode 100644 index 00000000..8f6cf1bf --- /dev/null +++ b/linux/109stream-equal.subx @@ -0,0 +1,595 @@ +# some primitives for checking stream contents + +== 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 + +# compare all the data in a stream (ignoring the read pointer) +stream-data-equal?: # f: (addr stream byte), s: (addr array byte) -> result/eax: boolean + # . 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 + 56/push-esi + 57/push-edi + # esi = f + 8b/copy 1/mod/*+disp8 5/rm32/ebp . . . 6/r32/esi 8/disp8 . # copy *(ebp+8) to esi + # eax = f->write + 8b/copy 0/mod/indirect 6/rm32/esi . . . 0/r32/eax . . # copy *esi to eax + # var maxf/edx: (addr byte) = &f->data[f->write] + 8d/copy-address 1/mod/*+disp8 4/rm32/sib 6/base/esi 0/index/eax . 2/r32/edx 0xc/disp8 . # copy esi+eax+12 to edx + # var currf/esi: (addr byte) = f->data + 81 0/subop/add 3/mod/direct 6/rm32/esi . . . . . 0xc/imm32 # add to esi + # edi = s + 8b/copy 1/mod/*+disp8 5/rm32/ebp . . . 7/r32/edi 0xc/disp8 . # copy *(ebp+12) to edi +$stream-data-equal?:compare-sizes: + # if (f->write != s->size) return false + 39/compare 0/mod/indirect 7/rm32/edi . . . 0/r32/eax . . # compare *edi and eax + 75/jump-if-!= $stream-data-equal?:false/disp8 + # var currs/edi: (addr byte) = s->data + 81 0/subop/add 3/mod/direct 7/rm32/edi . . . . . 4/imm32 # add to edi + # var eax: byte = 0 + 31/xor 3/mod/direct 0/rm32/eax . . . 0/r32/eax . . # clear eax + # var ecx: byte = 0 + 31/xor 3/mod/direct 1/rm32/ecx . . . 1/r32/ecx . . # clear ecx +$stream-data-equal?:loop: + # if (currf >= maxf) return true + 39/compare 3/mod/direct 6/rm32/esi . . . 2/r32/edx . . # compare esi with edx + 73/jump-if-addr>= $stream-data-equal?:true/disp8 + # AL = *currs + 8a/copy-byte 0/mod/indirect 6/rm32/esi . . . 0/r32/AL . . # copy byte at *esi to AL + # CL = *curr + 8a/copy-byte 0/mod/indirect 7/rm32/edi . . . 1/r32/CL . . # copy byte at *edi to CL + # if (eax != ecx) return false + 39/compare 3/mod/direct 0/rm32/eax . . . 1/r32/ecx . . # compare eax and ecx + 75/jump-if-!= $stream-data-equal?:false/disp8 + # ++f + 46/increment-esi + # ++curr + 47/increment-edi + eb/jump $stream-data-equal?:loop/disp8 +$stream-data-equal?:false: + b8/copy-to-eax 0/imm32 + eb/jump $stream-data-equal?:end/disp8 +$stream-data-equal?:true: + b8/copy-to-eax 1/imm32 +$stream-data-equal?:end: + # . restore registers + 5f/pop-to-edi + 5e/pop-to-esi + 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-stream-data-equal: + # . prologue + 55/push-ebp + 89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp + # 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") + # . . push args + 68/push "Abc"/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 + # eax = stream-data-equal?(_test-stream, "Abc") + # . . push args + 68/push "Abc"/imm32 + 68/push _test-stream/imm32 + # . . call + e8/call stream-data-equal?/disp32 + # . . discard args + 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp + # check-ints-equal(eax, 1, msg) + # . . push args + 68/push "F - test-stream-data-equal"/imm32 + 68/push 1/imm32 + 50/push-eax + # . . 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-stream-data-equal-2: + # . prologue + 55/push-ebp + 89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp + # 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") + # . . push args + 68/push "Abc"/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 + # eax = stream-data-equal?(_test-stream, "Abd") + # . . push args + 68/push "Abd"/imm32 + 68/push _test-stream/imm32 + # . . call + e8/call stream-data-equal?/disp32 + # . . discard args + 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp + # check-ints-equal(eax, 0, msg) + # . . push args + 68/push "F - test-stream-data-equal-2"/imm32 + 68/push 0/imm32 + 50/push-eax + # . . 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-stream-data-equal-size-check: + # . prologue + 55/push-ebp + 89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp + # 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") + # . . push args + 68/push "Abc"/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 + # eax = stream-data-equal?(_test-stream, "Abcd") + # . . push args + 68/push "Abcd"/imm32 + 68/push _test-stream/imm32 + # . . call + e8/call stream-data-equal?/disp32 + # . . discard args + 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp + # check-ints-equal(eax, 0, msg) + # . . push args + 68/push "F - test-stream-data-equal-size-check"/imm32 + 68/push 0/imm32 + 50/push-eax + # . . 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 + +# helper for later tests +check-stream-equal: # f: (addr stream byte), s: (addr array byte), msg: (addr array 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 + # eax = stream-data-equal?(f, s) + # . . push args + ff 6/subop/push 1/mod/*+disp8 5/rm32/ebp . . . . 0xc/disp8 . # push *(ebp+12) + ff 6/subop/push 1/mod/*+disp8 5/rm32/ebp . . . . 8/disp8 . # push *(ebp+8) + # . . call + e8/call stream-data-equal?/disp32 + # . . discard args + 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp + # check-ints-equal(eax, 1, msg) + # . . push args + ff 6/subop/push 1/mod/*+disp8 5/rm32/ebp . . . . 0x10/disp8 . # push *(ebp+16) + 68/push 1/imm32 + 50/push-eax + # . . call + e8/call check-ints-equal/disp32 + # . . discard args + 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32 # add to esp +$check-stream-equal:end: + # . restore registers + 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 + +# scan the next line until newline starting from f->read and compare it with +# 's' (ignoring the trailing newline) +# on success, set f->read to after the next newline +# on failure, leave f->read unmodified +# this function is usually used only in tests, so we repeatedly write f->read +next-stream-line-equal?: # f: (addr stream byte), s: (addr array byte) -> result/eax: boolean + # pseudocode: + # currf = f->read # bound: f->write + # currs = 0 # bound: s->size + # while true + # if currf >= f->write + # return currs >= s->size + # if f[currf] == '\n' + # ++currf + # return currs >= s->size + # if (currs >= s->size) return false # the current line of f still has data to match + # if (f[currf] != s[currs]) return false + # ++currf + # ++currs + # + # collapsing the two branches that can return true: + # currf = f->read # bound: f->write + # currs = 0 # bound: s->size + # while true + # if (currf >= f->write) break + # if (f[currf] == '\n') break + # if (currs >= s->size) return false # the current line of f still has data to match + # if (f[currf] != s[currs]) return false + # ++currf + # ++currs + # ++currf # skip '\n' + # return currs >= s->size + # Here the final `++currf` is sometimes unnecessary (if we're already at the end of the stream) + # + # registers: + # f: esi + # s: edi + # currf: ecx + # currs: edx + # f[currf]: eax + # s[currs]: ebx + # + # . 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 + 56/push-esi + 57/push-edi + # esi = f + 8b/copy 1/mod/*+disp8 5/rm32/ebp . . . 6/r32/esi 8/disp8 . # copy *(ebp+8) to esi + # var currf/ecx: int = f->read + 8b/copy 1/mod/*+disp8 6/rm32/esi . . . 1/r32/ecx 4/disp8 . # copy *(esi+4) to ecx + # edi = s + 8b/copy 1/mod/*+disp8 5/rm32/ebp . . . 7/r32/edi 0xc/disp8 . # copy *(ebp+12) to edi + # var currs/edx: int = 0 + 31/xor 3/mod/direct 2/rm32/edx . . . 2/r32/edx . . # clear edx + # var c1/eax: byte = 0 + 31/xor 3/mod/direct 0/rm32/eax . . . 0/r32/eax . . # clear eax + # var c2/ebx: byte = 0 + 31/xor 3/mod/direct 3/rm32/ebx . . . 3/r32/ebx . . # clear ebx +$next-stream-line-equal?:loop: + # if (currf >= f->write) break + 3b/compare 0/mod/indirect 6/rm32/esi . . . 1/r32/ecx . . # compare ecx with *esi + 7d/jump-if->= $next-stream-line-equal?:break/disp8 + # c1 = f->data[f->read] + 8a/copy-byte 1/mod/*+disp8 4/rm32/sib 6/base/esi 1/index/ecx . 0/r32/AL 0xc/disp8 . # copy byte at *(esi+ecx+12) to AL + # if (c1 == '\n') break + 3d/compare-eax-and 0xa/imm32/newline + 74/jump-if-= $next-stream-line-equal?:break/disp8 + # if (currs >= s->size) return false + 3b/compare 0/mod/indirect 7/rm32/edi . . . 2/r32/edx . . # compare edx with *edi + 7d/jump-if->= $next-stream-line-equal?:false/disp8 + # c2 = s->data[currs] + 8a/copy-byte 1/mod/*+disp8 4/rm32/sib 7/base/edi 2/index/edx . 3/r32/BL 4/disp8 . # copy byte at *(edi+edx+4) to BL + # if (c1 != c2) return false + 39/compare 3/mod/direct 0/rm32/eax . . . 3/r32/ebx . . # compare eax and ebx + 75/jump-if-!= $next-stream-line-equal?:false/disp8 + # ++currf + 41/increment-ecx + # ++currs + 42/increment-edx + eb/jump $next-stream-line-equal?:loop/disp8 +$next-stream-line-equal?:break: + # ++currf + 41/increment-ecx + # if (currs >= s->size) return true + 3b/compare 0/mod/indirect 7/rm32/edi . . . 2/r32/edx . . # compare edx with *edi + 7c/jump-if-< $next-stream-line-equal?:false/disp8 +$next-stream-line-equal?:true: + b8/copy-to-eax 1/imm32 + # persist f->read on success + 89/copy 1/mod/*+disp8 6/rm32/esi . . . 1/r32/ecx 4/disp8 . # copy ecx to *(esi+4) + eb/jump $next-stream-line-equal?:end/disp8 +$next-stream-line-equal?:false: + b8/copy-to-eax 0/imm32 +$next-stream-line-equal?:end: + # . restore registers + 5f/pop-to-edi + 5e/pop-to-esi + 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-next-stream-line-equal-stops-at-newline: + # . prologue + 55/push-ebp + 89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp + # 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\ndef") + # . . push args + 68/push "Abc\ndef"/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 + # eax = next-stream-line-equal?(_test-stream, "Abc") + # . . push args + 68/push "Abc"/imm32 + 68/push _test-stream/imm32 + # . . call + e8/call next-stream-line-equal?/disp32 + # . . discard args + 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp + # check-ints-equal(eax, 1, msg) + # . . push args + 68/push "F - test-next-stream-line-equal-stops-at-newline"/imm32 + 68/push 1/imm32 + 50/push-eax + # . . 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-next-stream-line-equal-stops-at-newline-2: + # . prologue + 55/push-ebp + 89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp + # 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\ndef") + # . . push args + 68/push "Abc\ndef"/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 + # eax = next-stream-line-equal?(_test-stream, "def") + # . . push args + 68/push "def"/imm32 + 68/push _test-stream/imm32 + # . . call + e8/call next-stream-line-equal?/disp32 + # . . discard args + 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp + # check-ints-equal(eax, 0, msg) + # . . push args + 68/push "F - test-next-stream-line-equal-stops-at-newline-2"/imm32 + 68/push 0/imm32 + 50/push-eax + # . . 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-next-stream-line-equal-skips-newline: + # . prologue + 55/push-ebp + 89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp + # 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\ndef\n") + # . . push args + 68/push "Abc\ndef\n"/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 + # next-stream-line-equal?(_test-stream, "Abc") + # . . push args + 68/push "Abc"/imm32 + 68/push _test-stream/imm32 + # . . call + e8/call next-stream-line-equal?/disp32 + # . . discard args + 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp + # eax = next-stream-line-equal?(_test-stream, "def") + # . . push args + 68/push "def"/imm32 + 68/push _test-stream/imm32 + # . . call + e8/call next-stream-line-equal?/disp32 + # . . discard args + 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp + # check-ints-equal(eax, 1, msg) + # . . push args + 68/push "F - test-next-stream-line-equal-skips-newline"/imm32 + 68/push 1/imm32 + 50/push-eax + # . . 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-next-stream-line-equal-handles-final-line: + # . prologue + 55/push-ebp + 89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp + # 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\ndef") + # . . push args + 68/push "Abc\ndef"/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 + # next-stream-line-equal?(_test-stream, "Abc") + # . . push args + 68/push "Abc"/imm32 + 68/push _test-stream/imm32 + # . . call + e8/call next-stream-line-equal?/disp32 + # . . discard args + 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp + # eax = next-stream-line-equal?(_test-stream, "def") + # . . push args + 68/push "def"/imm32 + 68/push _test-stream/imm32 + # . . call + e8/call next-stream-line-equal?/disp32 + # . . discard args + 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp + # check-ints-equal(eax, 1, msg) + # . . push args + 68/push "F - test-next-stream-line-equal-skips-newline"/imm32 + 68/push 1/imm32 + 50/push-eax + # . . 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-next-stream-line-equal-always-fails-after-Eof: + # . prologue + 55/push-ebp + 89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp + # 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 nothing + # eax = next-stream-line-equal?(_test-stream, "") + # . . push args + 68/push ""/imm32 + 68/push _test-stream/imm32 + # . . call + e8/call next-stream-line-equal?/disp32 + # . . discard args + 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp + # check-ints-equal(eax, 0, msg) + # . . push args + 68/push "F - test-next-stream-line-equal-always-fails-after-Eof"/imm32 + 68/push 1/imm32 + 50/push-eax + # . . call + e8/call check-ints-equal/disp32 + # . . discard args + 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32 # add to esp + # eax = next-stream-line-equal?(_test-stream, "") + # . . push args + 68/push ""/imm32 + 68/push _test-stream/imm32 + # . . call + e8/call next-stream-line-equal?/disp32 + # . . discard args + 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp + # check-ints-equal(eax, 0, msg) + # . . push args + 68/push "F - test-next-stream-line-equal-always-fails-after-Eof/2"/imm32 + 68/push 1/imm32 + 50/push-eax + # . . 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 + +# helper for later tests +check-next-stream-line-equal: # f: (addr stream byte), s: (addr array byte), msg: (addr array 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 + # eax = next-stream-line-equal?(f, s) + # . . push args + ff 6/subop/push 1/mod/*+disp8 5/rm32/ebp . . . . 0xc/disp8 . # push *(ebp+12) + ff 6/subop/push 1/mod/*+disp8 5/rm32/ebp . . . . 8/disp8 . # push *(ebp+8) + # . . call + e8/call next-stream-line-equal?/disp32 + # . . discard args + 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp + # check-ints-equal(eax, 1, msg) + # . . push args + ff 6/subop/push 1/mod/*+disp8 5/rm32/ebp . . . . 0x10/disp8 . # push *(ebp+16) + 68/push 1/imm32 + 50/push-eax + # . . call + e8/call check-ints-equal/disp32 + # . . discard args + 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32 # add to esp + # . restore registers + 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 + +# . . vim:nowrap:textwidth=0 |