6182 - start of support for safe handles

So far it's unclear how to do this in a series of small commits. Still
nibbling around the edges. In this commit we standardize some terminology:

The length of an array or stream is denominated in the high-level elements.
The _size_ is denominated in bytes.

The thing we encode into the type is always the size, not the length.

There's still an open question of what to do about the Mu `length` operator.
I'd like to modify it to provide the length. Currently it provides the
size. If I can't fix that I'll rename it.
This commit is contained in:
Kartik Agaram 2020-04-03 12:35:53 -07:00
parent f730f2f2c7
commit bfcc0f858a
42 changed files with 221 additions and 221 deletions

View File

@ -1,11 +1,11 @@
# Checking null-terminated ascii strings. # Checking null-terminated ascii strings.
# #
# By default we create strings as arrays of bytes, and all arrays have a 4-byte # By default we create strings as arrays of bytes, and all arrays have a 4-byte
# length prefix. # size prefix.
# #
# However, we sometimes need to deal with null-prefixed strings when interacting # However, we sometimes need to deal with null-prefixed strings when interacting
# with the Linux kernel. This layer implements a function for comparing a # with the Linux kernel. This layer implements a function for comparing a
# null-terminated 'kernel string' with a length-prefixed 'SubX string'. # null-terminated 'kernel string' with a size-prefixed 'SubX string'.
# #
# To run (from the subx directory): # To run (from the subx directory):
# $ ./bootstrap translate 05[0-2]*.subx -o /tmp/tmp52 # $ ./bootstrap translate 05[0-2]*.subx -o /tmp/tmp52
@ -28,11 +28,11 @@ Entry: # run all tests
b8/copy-to-eax 1/imm32/exit b8/copy-to-eax 1/imm32/exit
cd/syscall 0x80/imm8 cd/syscall 0x80/imm8
# compare a null-terminated ascii string with a more idiomatic length-prefixed byte array # compare a null-terminated ascii string with a more idiomatic size-prefixed byte array
# reason for the name: the only place we should have null-terminated ascii strings is from commandline args # reason for the name: the only place we should have null-terminated ascii strings is from commandline args
kernel-string-equal?: # s: (addr kernel-string), benchmark: (addr array byte) -> eax: boolean kernel-string-equal?: # s: (addr kernel-string), benchmark: (addr array byte) -> eax: boolean
# pseudocode: # pseudocode:
# n = benchmark->length # n = benchmark->size
# s1 = s # s1 = s
# s2 = benchmark->data # s2 = benchmark->data
# i = 0 # i = 0
@ -63,7 +63,7 @@ kernel-string-equal?: # s: (addr kernel-string), benchmark: (addr array byte) -
57/push-edi 57/push-edi
# var s1/edi: (addr byte) = s # var s1/edi: (addr byte) = s
8b/copy 1/mod/*+disp8 5/rm32/ebp . . . 7/r32/edi 8/disp8 . # copy *(ebp+8) to edi 8b/copy 1/mod/*+disp8 5/rm32/ebp . . . 7/r32/edi 8/disp8 . # copy *(ebp+8) to edi
# var n/edx: int = benchmark->length # var n/edx: int = benchmark->size
8b/copy 1/mod/*+disp8 5/rm32/ebp . . . 2/r32/edx 0xc/disp8 . # copy *(ebp+12) to edx 8b/copy 1/mod/*+disp8 5/rm32/ebp . . . 2/r32/edx 0xc/disp8 . # copy *(ebp+12) to edx
8b/copy 0/mod/indirect 2/rm32/edx . . . 2/r32/edx . . # copy *edx to edx 8b/copy 0/mod/indirect 2/rm32/edx . . . 2/r32/edx . . # copy *edx to edx
# var s2/esi: (addr byte) = benchmark->data # var s2/esi: (addr byte) = benchmark->data

View File

@ -1,4 +1,4 @@
# Comparing 'regular' length-prefixed strings. # Comparing 'regular' size-prefixed strings.
== code == code
# instruction effective address register displacement immediate # instruction effective address register displacement immediate
@ -15,7 +15,7 @@ Entry: # run all tests
string-equal?: # s: (addr array byte), benchmark: (addr array byte) -> eax: boolean string-equal?: # s: (addr array byte), benchmark: (addr array byte) -> eax: boolean
# pseudocode: # pseudocode:
# if (s->length != benchmark->length) return false # if (s->size != benchmark->size) return false
# return string-starts-with?(s, benchmark) # return string-starts-with?(s, benchmark)
# #
# . prologue # . prologue
@ -29,10 +29,10 @@ string-equal?: # s: (addr array byte), benchmark: (addr array byte) -> eax: boo
8b/copy 1/mod/*+disp8 5/rm32/ebp . . . 6/r32/esi 8/disp8 . # copy *(ebp+8) to esi 8b/copy 1/mod/*+disp8 5/rm32/ebp . . . 6/r32/esi 8/disp8 . # copy *(ebp+8) to esi
# edi = benchmark # edi = benchmark
8b/copy 1/mod/*+disp8 5/rm32/ebp . . . 7/r32/edi 0xc/disp8 . # copy *(ebp+12) to edi 8b/copy 1/mod/*+disp8 5/rm32/ebp . . . 7/r32/edi 0xc/disp8 . # copy *(ebp+12) to edi
# ecx = s->length # ecx = s->size
8b/copy 0/mod/indirect 6/rm32/esi . . . 1/r32/ecx . . # copy *esi to ecx 8b/copy 0/mod/indirect 6/rm32/esi . . . 1/r32/ecx . . # copy *esi to ecx
$string-equal?:lengths: $string-equal?:sizes:
# if (ecx != benchmark->length) return false # if (ecx != benchmark->size) return false
39/compare 0/mod/indirect 7/rm32/edi . . . 1/r32/ecx . . # compare *edi and ecx 39/compare 0/mod/indirect 7/rm32/edi . . . 1/r32/ecx . . # compare *edi and ecx
b8/copy-to-eax 0/imm32/false b8/copy-to-eax 0/imm32/false
75/jump-if-!= $string-equal?:end/disp8 75/jump-if-!= $string-equal?:end/disp8
@ -57,10 +57,10 @@ $string-equal?:end:
string-starts-with?: # s: (addr array byte), benchmark: (addr array byte) -> eax: boolean string-starts-with?: # s: (addr array byte), benchmark: (addr array byte) -> eax: boolean
# pseudocode: # pseudocode:
# if (s->length < benchmark->length) return false # if (s->size < benchmark->size) return false
# currs = s->data # currs = s->data
# currb = benchmark->data # currb = benchmark->data
# maxb = &benchmark->data[benchmark->length] # maxb = &benchmark->data[benchmark->size]
# while currb < maxb # while currb < maxb
# c1 = *currs # c1 = *currs
# c2 = *currb # c2 = *currb
@ -87,17 +87,17 @@ string-starts-with?: # s: (addr array byte), benchmark: (addr array byte) -> ea
8b/copy 1/mod/*+disp8 5/rm32/ebp . . . 6/r32/esi 8/disp8 . # copy *(ebp+8) to esi 8b/copy 1/mod/*+disp8 5/rm32/ebp . . . 6/r32/esi 8/disp8 . # copy *(ebp+8) to esi
# edi = benchmark # edi = benchmark
8b/copy 1/mod/*+disp8 5/rm32/ebp . . . 7/r32/edi 0xc/disp8 . # copy *(ebp+12) to edi 8b/copy 1/mod/*+disp8 5/rm32/ebp . . . 7/r32/edi 0xc/disp8 . # copy *(ebp+12) to edi
# var blen/ecx: int = benchmark->length # var bsize/ecx: int = benchmark->size
8b/copy 0/mod/indirect 7/rm32/edi . . . 1/r32/ecx . . # copy *edi to ecx 8b/copy 0/mod/indirect 7/rm32/edi . . . 1/r32/ecx . . # copy *edi to ecx
$string-starts-with?:lengths: $string-starts-with?:sizes:
# if (s->length < blen) return false # if (s->size < bsize) return false
39/compare 0/mod/indirect 6/rm32/esi . . . 1/r32/ecx . . # compare *esi with ecx 39/compare 0/mod/indirect 6/rm32/esi . . . 1/r32/ecx . . # compare *esi with ecx
7c/jump-if-< $string-starts-with?:false/disp8 7c/jump-if-< $string-starts-with?:false/disp8
# var currs/esi: (addr byte) = s->data # var currs/esi: (addr byte) = s->data
81 0/subop/add 3/mod/direct 6/rm32/esi . . . . . 4/imm32 # add to esi 81 0/subop/add 3/mod/direct 6/rm32/esi . . . . . 4/imm32 # add to esi
# var currb/edi: (addr byte) = benchmark->data # var currb/edi: (addr byte) = benchmark->data
81 0/subop/add 3/mod/direct 7/rm32/edi . . . . . 4/imm32 # add to edi 81 0/subop/add 3/mod/direct 7/rm32/edi . . . . . 4/imm32 # add to edi
# var maxb/ecx: (addr byte) = &benchmark->data[benchmark->length] # var maxb/ecx: (addr byte) = &benchmark->data[benchmark->size]
01/add 3/mod/direct 1/rm32/ecx . . . 7/r32/edi . . # add edi to ecx 01/add 3/mod/direct 1/rm32/ecx . . . 7/r32/edi . . # add edi to ecx
# var c1/eax: byte = 0 # var c1/eax: byte = 0
31/xor 3/mod/direct 0/rm32/eax . . . 0/r32/eax . . # clear eax 31/xor 3/mod/direct 0/rm32/eax . . . 0/r32/eax . . # clear eax
@ -157,7 +157,7 @@ test-compare-empty-with-empty-string:
81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32 # add to esp 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32 # add to esp
c3/return c3/return
test-compare-empty-with-non-empty-string: # also checks length-mismatch code path test-compare-empty-with-non-empty-string: # also checks size-mismatch code path
# eax = string-equal?("", "Abc") # eax = string-equal?("", "Abc")
# . . push args # . . push args
68/push "Abc"/imm32 68/push "Abc"/imm32
@ -197,7 +197,7 @@ test-compare-equal-strings:
81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32 # add to esp 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32 # add to esp
c3/return c3/return
test-compare-inequal-strings-equal-lengths: test-compare-inequal-strings-equal-sizes:
# eax = string-equal?("Abc", "Adc") # eax = string-equal?("Abc", "Adc")
# . . push args # . . push args
68/push "Adc"/imm32 68/push "Adc"/imm32
@ -208,7 +208,7 @@ test-compare-inequal-strings-equal-lengths:
81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp
# check-ints-equal(eax, 0, msg) # check-ints-equal(eax, 0, msg)
# . . push args # . . push args
68/push "F - test-compare-inequal-strings-equal-lengths"/imm32 68/push "F - test-compare-inequal-strings-equal-sizes"/imm32
68/push 0/imm32/false 68/push 0/imm32/false
50/push-eax 50/push-eax
# . . call # . . call

View File

@ -3,10 +3,10 @@
# A stream looks like this: # A stream looks like this:
# write: int # index at which writes go # write: int # index at which writes go
# read: int # index that we've read until # read: int # index that we've read until
# data: (array byte) # prefixed by length as usual # data: (array byte) # prefixed by size as usual
# #
# some primitives for operating on streams: # some primitives for operating on streams:
# - clear-stream (clears everything but the data length) # - clear-stream (clears everything but the data size)
# - rewind-stream (resets read pointer) # - rewind-stream (resets read pointer)
== code == code
@ -23,9 +23,9 @@ clear-stream: # f: (addr stream byte)
51/push-ecx 51/push-ecx
# eax = f # eax = f
8b/copy 1/mod/*+disp8 5/rm32/ebp . . 0/r32/eax 8/disp8 . # copy *(ebp+8) to eax 8b/copy 1/mod/*+disp8 5/rm32/ebp . . 0/r32/eax 8/disp8 . # copy *(ebp+8) to eax
# var count/ecx: int = f->length # var count/ecx: int = f->size
8b/copy 1/mod/*+disp8 0/rm32/eax . . . 1/r32/ecx 8/disp8 . # copy *(eax+8) to ecx 8b/copy 1/mod/*+disp8 0/rm32/eax . . . 1/r32/ecx 8/disp8 . # copy *(eax+8) to ecx
# var max/ecx: (addr byte) = &f->data[f->length] # var max/ecx: (addr byte) = &f->data[f->size]
8d/copy-address 1/mod/*+disp8 4/rm32/sib 0/base/eax 1/index/ecx . 1/r32/ecx 0xc/disp8 . # copy eax+ecx+12 to ecx 8d/copy-address 1/mod/*+disp8 4/rm32/sib 0/base/eax 1/index/ecx . 1/r32/ecx 0xc/disp8 . # copy eax+ecx+12 to ecx
# f->write = 0 # f->write = 0
c7 0/subop/copy 0/mod/direct 0/rm32/eax . . . . . 0/imm32 # copy to *eax c7 0/subop/copy 0/mod/direct 0/rm32/eax . . . . . 0/imm32 # copy to *eax

View File

@ -3,7 +3,7 @@
# A trace stream looks like a regular stream: # A trace stream looks like a regular stream:
# write: int # index at which writes go # write: int # index at which writes go
# read: int # index that we've read until # read: int # index that we've read until
# data: (array byte) # prefixed by length as usual # data: (array byte) # prefixed by size as usual
# Usually the trace stream will be in a separate segment set aside for the purpose. # Usually the trace stream will be in a separate segment set aside for the purpose.
# #
# primitives for operating on traces (arguments in quotes): # primitives for operating on traces (arguments in quotes):
@ -33,7 +33,7 @@ _test-trace-stream: # (stream byte)
0/imm32 0/imm32
# current read index # current read index
0/imm32 0/imm32
# length # size
8/imm32 8/imm32
# data # data
00 00 00 00 00 00 00 00 # 8 bytes 00 00 00 00 00 00 00 00 # 8 bytes
@ -43,7 +43,7 @@ _test-trace-stream: # (stream byte)
# . op subop mod rm32 base index scale r32 # . 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 # . 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
# Allocate a new segment for the trace stream, initialize its length, and save its address to Trace-stream. # Allocate a new segment for the trace stream, initialize its size, and save its address to Trace-stream.
# The Trace-stream segment will consist of variable-length lines separated by newlines (0x0a) # The Trace-stream segment will consist of variable-length lines separated by newlines (0x0a)
initialize-trace-stream: # n: int initialize-trace-stream: # n: int
# . prologue # . prologue
@ -67,10 +67,10 @@ initialize-trace-stream: # n: int
#? # watch point to catch Trace-stream leaks #? # watch point to catch Trace-stream leaks
#? $watch-1: #? $watch-1:
89/copy 0/mod/indirect 5/rm32/.disp32 . . 0/r32/eax Trace-stream/disp32 # copy eax to *Trace-stream 89/copy 0/mod/indirect 5/rm32/.disp32 . . 0/r32/eax Trace-stream/disp32 # copy eax to *Trace-stream
# Trace-stream->length = n - 12 # Trace-stream->size = n - 12
# . ecx -= 12 # . ecx -= 12
81 5/subop/subtract 3/mod/direct 1/rm32/ecx . . . . . 0xc/imm32 # subtract from ecx 81 5/subop/subtract 3/mod/direct 1/rm32/ecx . . . . . 0xc/imm32 # subtract from ecx
# . Trace-stream->length = ecx # . Trace-stream->size = ecx
89/copy 1/mod/*+disp8 0/rm32/eax . . . 1/r32/ecx 8/disp8 . # copy ecx to *(eax+8) 89/copy 1/mod/*+disp8 0/rm32/eax . . . 1/r32/ecx 8/disp8 . # copy ecx to *(eax+8)
$initialize-trace-stream:end: $initialize-trace-stream:end:
# . restore registers # . restore registers
@ -100,12 +100,12 @@ trace: # line: (addr array byte)
8b/copy 1/mod/*+disp8 5/rm32/ebp . . 6/r32/esi 8/disp8 . # copy *(ebp+8) to esi 8b/copy 1/mod/*+disp8 5/rm32/ebp . . 6/r32/esi 8/disp8 . # copy *(ebp+8) to esi
# var ecx: int = t->write # var ecx: int = t->write
8b/copy 0/mod/indirect 7/rm32/edi . . . 1/r32/ecx . . # copy *edi to ecx 8b/copy 0/mod/indirect 7/rm32/edi . . . 1/r32/ecx . . # copy *edi to ecx
# var edx: int = t->length # var edx: int = t->size
8b/copy 1/mod/*+disp8 7/rm32/edi . . . 2/r32/edx 8/disp8 . # copy *(edi+8) to edx 8b/copy 1/mod/*+disp8 7/rm32/edi . . . 2/r32/edx 8/disp8 . # copy *(edi+8) to edx
# eax = _append-3(&t->data[t->write], &t->data[t->length], line) # eax = _append-3(&t->data[t->write], &t->data[t->size], line)
# . . push line # . . push line
56/push-esi 56/push-esi
# . . push &t->data[t->length] # . . push &t->data[t->size]
8d/copy-address 1/mod/*+disp8 4/rm32/sib 7/base/edi 2/index/edx . 3/r32/ebx 0xc/disp8 . # copy edi+edx+12 to ebx 8d/copy-address 1/mod/*+disp8 4/rm32/sib 7/base/edi 2/index/edx . 3/r32/ebx 0xc/disp8 . # copy edi+edx+12 to ebx
53/push-ebx 53/push-ebx
# . . push &t->data[t->write] # . . push &t->data[t->write]
@ -122,10 +122,10 @@ trace: # line: (addr array byte)
01/add 0/mod/indirect 7/rm32/edi . . . 0/r32/eax . . # add eax to *edi 01/add 0/mod/indirect 7/rm32/edi . . . 0/r32/eax . . # add eax to *edi
# refresh ecx = t->write # refresh ecx = t->write
8b/copy 0/mod/indirect 7/rm32/edi . . . 1/r32/ecx . . # copy *edi to ecx 8b/copy 0/mod/indirect 7/rm32/edi . . . 1/r32/ecx . . # copy *edi to ecx
# eax = _append-3(&t->data[t->write], &t->data[t->length], line) # eax = _append-3(&t->data[t->write], &t->data[t->size], line)
# . . push line # . . push line
68/push Newline/imm32 68/push Newline/imm32
# . . push &t->data[t->length] # . . push &t->data[t->size]
8d/copy-address 1/mod/*+disp8 4/rm32/sib 7/base/edi 2/index/edx . 3/r32/ebx 0xc/disp8 . # copy edi+edx+12 to ebx 8d/copy-address 1/mod/*+disp8 4/rm32/sib 7/base/edi 2/index/edx . 3/r32/ebx 0xc/disp8 . # copy edi+edx+12 to ebx
53/push-ebx 53/push-ebx
# . . push &t->data[t->write] # . . push &t->data[t->write]
@ -868,8 +868,8 @@ _append-3: # out: (addr byte), outend: (addr byte), s: (addr array byte) -> num
89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp 89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp
# . save registers # . save registers
51/push-ecx 51/push-ecx
# eax = _append-4(out, outend, &s->data[0], &s->data[s->length]) # eax = _append-4(out, outend, &s->data[0], &s->data[s->size])
# . . push &s->data[s->length] # . . push &s->data[s->size]
8b/copy 1/mod/*+disp8 5/rm32/ebp . . 0/r32/eax 0x10/disp8 . # copy *(ebp+16) to eax 8b/copy 1/mod/*+disp8 5/rm32/ebp . . 0/r32/eax 0x10/disp8 . # copy *(ebp+16) to eax
8b/copy 0/mod/indirect 0/rm32/eax . . . 1/r32/ecx . . # copy *eax to ecx 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 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
@ -965,7 +965,7 @@ _test-stream-line-ABABA: # (stream byte)
8/imm32 8/imm32
# read # read
0/imm32 0/imm32
# length # size
8/imm32 8/imm32
# data # data
41 42 41 42 41 0a 00 00 # 8 bytes 41 42 41 42 41 0a 00 00 # 8 bytes
@ -975,7 +975,7 @@ _test-stream-empty: # (stream byte)
0/imm32 0/imm32
# read # read
0/imm32 0/imm32
# length # size
8/imm32 8/imm32
# data # data
00 00 00 00 00 00 00 00 # 8 bytes 00 00 00 00 00 00 00 00 # 8 bytes
@ -985,7 +985,7 @@ _test-stream-filled: # (stream byte)
8/imm32 8/imm32
# read # read
0/imm32 0/imm32
# length # size
8/imm32 8/imm32
# data # data
41 41 41 41 0a 41 41 41 # 8 bytes 41 41 41 41 0a 41 41 41 # 8 bytes

View File

@ -13,7 +13,7 @@
# A stream looks like this: # A stream looks like this:
# read: int # index at which to read next # read: int # index at which to read next
# write: int # index at which writes go # write: int # index at which writes go
# data: (array byte) # prefixed by length as usual # data: (array byte) # prefixed by size as usual
== code == code
# instruction effective address register displacement immediate # instruction effective address register displacement immediate
@ -47,12 +47,12 @@ $write:fake:
8b/copy 1/mod/*+disp8 5/rm32/ebp . . 1/r32/ecx 8/disp8 . # copy *(ebp+8) to ecx 8b/copy 1/mod/*+disp8 5/rm32/ebp . . 1/r32/ecx 8/disp8 . # copy *(ebp+8) to ecx
# edx = f->write # edx = f->write
8b/copy 0/mod/indirect 1/rm32/ecx . . . 2/r32/edx . . # copy *ecx to edx 8b/copy 0/mod/indirect 1/rm32/ecx . . . 2/r32/edx . . # copy *ecx to edx
# ebx = f->length # ebx = f->size
8b/copy 1/mod/*+disp8 1/rm32/ecx . . . 3/r32/ebx 8/disp8 . # copy *(ecx+8) to ebx 8b/copy 1/mod/*+disp8 1/rm32/ecx . . . 3/r32/ebx 8/disp8 . # copy *(ecx+8) to ebx
# eax = _append-3(&f->data[f->write], &f->data[f->length], s) # eax = _append-3(&f->data[f->write], &f->data[f->size], s)
# . . push s # . . push s
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 . . . . 0xc/disp8 . # push *(ebp+12)
# . . push &f->data[f->length] # . . push &f->data[f->size]
8d/copy-address 1/mod/*+disp8 4/rm32/sib 1/base/ecx 3/index/ebx . 3/r32/ebx 0xc/disp8 . # copy ecx+ebx+12 to ebx 8d/copy-address 1/mod/*+disp8 4/rm32/sib 1/base/ecx 3/index/ebx . 3/r32/ebx 0xc/disp8 . # copy ecx+ebx+12 to ebx
53/push-ebx 53/push-ebx
# . . push &f->data[f->write] # . . push &f->data[f->write]
@ -150,7 +150,7 @@ _test-stream: # (stream byte)
0/imm32 0/imm32
# current read index # current read index
0/imm32 0/imm32
# length # size
0x10/imm32 0x10/imm32
# data (2 lines x 8 bytes/line) # data (2 lines x 8 bytes/line)
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

View File

@ -25,8 +25,8 @@ stream-data-equal?: # f: (addr stream byte), s: (addr array byte) -> eax: boole
81 0/subop/add 3/mod/direct 6/rm32/esi . . . . . 0xc/imm32 # add to esi 81 0/subop/add 3/mod/direct 6/rm32/esi . . . . . 0xc/imm32 # add to esi
# edi = s # edi = s
8b/copy 1/mod/*+disp8 5/rm32/ebp . . . 7/r32/edi 0xc/disp8 . # copy *(ebp+12) to edi 8b/copy 1/mod/*+disp8 5/rm32/ebp . . . 7/r32/edi 0xc/disp8 . # copy *(ebp+12) to edi
$stream-data-equal?:compare-lengths: $stream-data-equal?:compare-sizes:
# if (f->write != s->length) return false # if (f->write != s->size) return false
39/compare 0/mod/indirect 7/rm32/edi . . . 0/r32/eax . . # compare *edi and eax 39/compare 0/mod/indirect 7/rm32/edi . . . 0/r32/eax . . # compare *edi and eax
75/jump-if-!= $stream-data-equal?:false/disp8 75/jump-if-!= $stream-data-equal?:false/disp8
# var currs/edi: (addr byte) = s->data # var currs/edi: (addr byte) = s->data
@ -149,7 +149,7 @@ test-stream-data-equal-2:
5d/pop-to-ebp 5d/pop-to-ebp
c3/return c3/return
test-stream-data-equal-length-check: test-stream-data-equal-size-check:
# . prologue # . prologue
55/push-ebp 55/push-ebp
89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp 89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp
@ -178,7 +178,7 @@ test-stream-data-equal-length-check:
81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp
# check-ints-equal(eax, 0, msg) # check-ints-equal(eax, 0, msg)
# . . push args # . . push args
68/push "F - test-stream-data-equal-length-check"/imm32 68/push "F - test-stream-data-equal-size-check"/imm32
68/push 0/imm32 68/push 0/imm32
50/push-eax 50/push-eax
# . . call # . . call
@ -230,30 +230,30 @@ $check-stream-equal:end:
next-stream-line-equal?: # f: (addr stream byte), s: (addr array byte) -> eax: boolean next-stream-line-equal?: # f: (addr stream byte), s: (addr array byte) -> eax: boolean
# pseudocode: # pseudocode:
# currf = f->read # bound: f->write # currf = f->read # bound: f->write
# currs = 0 # bound: s->length # currs = 0 # bound: s->size
# while true # while true
# if currf >= f->write # if currf >= f->write
# return currs >= s->length # return currs >= s->size
# if f[currf] == '\n' # if f[currf] == '\n'
# ++currf # ++currf
# return currs >= s->length # return currs >= s->size
# if (currs >= s->length) return false # the current line of f still has data to match # if (currs >= s->size) return false # the current line of f still has data to match
# if (f[currf] != s[currs]) return false # if (f[currf] != s[currs]) return false
# ++currf # ++currf
# ++currs # ++currs
# #
# collapsing the two branches that can return true: # collapsing the two branches that can return true:
# currf = f->read # bound: f->write # currf = f->read # bound: f->write
# currs = 0 # bound: s->length # currs = 0 # bound: s->size
# while true # while true
# if (currf >= f->write) break # if (currf >= f->write) break
# if (f[currf] == '\n') break # if (f[currf] == '\n') break
# if (currs >= s->length) return false # the current line of f still has data to match # if (currs >= s->size) return false # the current line of f still has data to match
# if (f[currf] != s[currs]) return false # if (f[currf] != s[currs]) return false
# ++currf # ++currf
# ++currs # ++currs
# ++currf # skip '\n' # ++currf # skip '\n'
# return currs >= s->length # return currs >= s->size
# Here the final `++currf` is sometimes unnecessary (if we're already at the end of the stream) # Here the final `++currf` is sometimes unnecessary (if we're already at the end of the stream)
# #
# registers: # registers:
@ -293,7 +293,7 @@ $next-stream-line-equal?:loop:
# if (c1 == '\n') break # if (c1 == '\n') break
3d/compare-eax-and 0xa/imm32/newline 3d/compare-eax-and 0xa/imm32/newline
74/jump-if-= $next-stream-line-equal?:break/disp8 74/jump-if-= $next-stream-line-equal?:break/disp8
# if (currs >= s->length) return false # if (currs >= s->size) return false
3b/compare 0/mod/indirect 7/rm32/edi . . . 2/r32/edx . . # compare edx with *edi 3b/compare 0/mod/indirect 7/rm32/edi . . . 2/r32/edx . . # compare edx with *edi
7d/jump-if->= $next-stream-line-equal?:false/disp8 7d/jump-if->= $next-stream-line-equal?:false/disp8
# c2 = s->data[currs] # c2 = s->data[currs]
@ -309,7 +309,7 @@ $next-stream-line-equal?:loop:
$next-stream-line-equal?:break: $next-stream-line-equal?:break:
# ++currf # ++currf
41/increment-ecx 41/increment-ecx
# if (currs >= s->length) return true # if (currs >= s->size) return true
3b/compare 0/mod/indirect 7/rm32/edi . . . 2/r32/edx . . # compare edx with *edi 3b/compare 0/mod/indirect 7/rm32/edi . . . 2/r32/edx . . # compare edx with *edi
7c/jump-if-< $next-stream-line-equal?:false/disp8 7c/jump-if-< $next-stream-line-equal?:false/disp8
$next-stream-line-equal?:true: $next-stream-line-equal?:true:

View File

@ -38,7 +38,7 @@
# As a reminder, a stream looks like this: # As a reminder, a stream looks like this:
# write: int # index at which to write to next # write: int # index at which to write to next
# read: int # index at which to read next # read: int # index at which to read next
# data: (array byte) # prefixed by length as usual # data: (array byte) # prefixed by size as usual
== code == code
# instruction effective address register displacement immediate # instruction effective address register displacement immediate
@ -70,7 +70,7 @@ $read:fake:
8b/copy 1/mod/*+disp8 5/rm32/ebp . . . 6/r32/esi 8/disp8 . # copy *(ebp+8) to esi 8b/copy 1/mod/*+disp8 5/rm32/ebp . . . 6/r32/esi 8/disp8 . # copy *(ebp+8) to esi
# edi = s # edi = s
8b/copy 1/mod/*+disp8 5/rm32/ebp . . . 7/r32/edi 0xc/disp8 . # copy *(ebp+12) to esi 8b/copy 1/mod/*+disp8 5/rm32/ebp . . . 7/r32/edi 0xc/disp8 . # copy *(ebp+12) to esi
# eax = _buffer-4(out = &s->data[s->write], outend = &s->data[s->length], # eax = _buffer-4(out = &s->data[s->write], outend = &s->data[s->size],
# in = &f->data[f->read], inend = &f->data[f->write]) # in = &f->data[f->read], inend = &f->data[f->write])
# . . push &f->data[f->write] # . . push &f->data[f->write]
8b/copy 0/mod/indirect 6/rm32/esi . . . 0/r32/eax . . # copy *esi to eax 8b/copy 0/mod/indirect 6/rm32/esi . . . 0/r32/eax . . # copy *esi to eax
@ -80,7 +80,7 @@ $read:fake:
8b/copy 1/mod/*+disp8 6/rm32/esi . . . 0/r32/eax 4/disp8 . # copy *(esi+4) to eax 8b/copy 1/mod/*+disp8 6/rm32/esi . . . 0/r32/eax 4/disp8 . # copy *(esi+4) to eax
8d/copy-address 1/mod/*+disp8 4/rm32/sib 6/base/esi 0/index/eax . 0/r32/eax 0xc/disp8 . # copy esi+eax+12 to eax 8d/copy-address 1/mod/*+disp8 4/rm32/sib 6/base/esi 0/index/eax . 0/r32/eax 0xc/disp8 . # copy esi+eax+12 to eax
50/push-eax 50/push-eax
# . . push &s->data[s->length] # . . push &s->data[s->size]
8b/copy 1/mod/*+disp8 7/rm32/edi . . . 0/r32/eax 8/disp8 . # copy *(edi+8) to eax 8b/copy 1/mod/*+disp8 7/rm32/edi . . . 0/r32/eax 8/disp8 . # copy *(edi+8) to eax
8d/copy-address 1/mod/*+disp8 4/rm32/sib 7/base/edi 0/index/eax . 0/r32/eax 0xc/disp8 . # copy edi+eax+12 to eax 8d/copy-address 1/mod/*+disp8 4/rm32/sib 7/base/edi 0/index/eax . 0/r32/eax 0xc/disp8 . # copy edi+eax+12 to eax
50/push-eax 50/push-eax
@ -116,8 +116,8 @@ _buffer-3: # out: address, outend: address, s: (array byte) -> num_bytes_buffer
89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp 89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp
# . save registers # . save registers
51/push-ecx 51/push-ecx
# eax = _buffer-4(out, outend, &s->data[0], &s->data[s->length]) # eax = _buffer-4(out, outend, &s->data[0], &s->data[s->size])
# . . push &s->data[s->length] # . . push &s->data[s->size]
8b/copy 1/mod/*+disp8 5/rm32/ebp . . 0/r32/eax 0x10/disp8 . # copy *(ebp+16) to eax 8b/copy 1/mod/*+disp8 5/rm32/ebp . . 0/r32/eax 0x10/disp8 . # copy *(ebp+16) to eax
8b/copy 0/mod/indirect 0/rm32/eax . . . 1/r32/ecx . . # copy *eax to ecx 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 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
@ -208,14 +208,14 @@ _read: # fd: int, s: (addr stream byte) -> num-bytes-read/eax: int
8b/copy 1/mod/*+disp8 5/rm32/ebp . . . 6/r32/esi 0xc/disp8 . # copy *(ebp+12) to esi 8b/copy 1/mod/*+disp8 5/rm32/ebp . . . 6/r32/esi 0xc/disp8 . # copy *(ebp+12) to esi
# eax = s->write # eax = s->write
8b/copy 0/mod/indirect 6/rm32/esi . . . 0/r32/eax . . # copy *esi to eax 8b/copy 0/mod/indirect 6/rm32/esi . . . 0/r32/eax . . # copy *esi to eax
# edx = s->length # edx = s->size
8b/copy 1/mod/*+disp8 6/rm32/esi . . . 2/r32/edx 8/disp8 . # copy *(esi+8) to edx 8b/copy 1/mod/*+disp8 6/rm32/esi . . . 2/r32/edx 8/disp8 . # copy *(esi+8) to edx
# syscall(read, fd, &s->data[s->write], s->length - s->write) # syscall(read, fd, &s->data[s->write], s->size - s->write)
# . . fd: ebx # . . fd: ebx
8b/copy 1/mod/*+disp8 5/rm32/ebp . . . 3/r32/ebx 8/disp8 . # copy *(ebp+8) to ebx 8b/copy 1/mod/*+disp8 5/rm32/ebp . . . 3/r32/ebx 8/disp8 . # copy *(ebp+8) to ebx
# . . data: ecx = &s->data[s->write] # . . data: ecx = &s->data[s->write]
8d/copy-address 1/mod/*+disp8 4/rm32/sib 6/base/esi 0/index/eax . 1/r32/ecx 0xc/disp8 . # copy esi+eax+12 to ecx 8d/copy-address 1/mod/*+disp8 4/rm32/sib 6/base/esi 0/index/eax . 1/r32/ecx 0xc/disp8 . # copy esi+eax+12 to ecx
# . . size: edx = s->length - s->write # . . size: edx = s->size - s->write
29/subtract 3/mod/direct 2/rm32/edx . . . 0/r32/eax . . # subtract eax from edx 29/subtract 3/mod/direct 2/rm32/edx . . . 0/r32/eax . . # subtract eax from edx
# . . syscall # . . syscall
b8/copy-to-eax 3/imm32/read b8/copy-to-eax 3/imm32/read
@ -237,14 +237,14 @@ $_read:end:
# 1 (what we have above): # 1 (what we have above):
# ecx = s # ecx = s
# eax = s->write # eax = s->write
# edx = s->length # edx = s->size
# # syscall # # syscall
# ecx = lea ecx+eax+12 # ecx = lea ecx+eax+12
# edx = sub edx eax # edx = sub edx eax
# #
# 2: # 2:
# ecx = s # ecx = s
# edx = s->length # edx = s->size
# ecx = &s->data # ecx = &s->data
# # syscall # # syscall
# ecx = add ecx, s->write # ecx = add ecx, s->write
@ -431,7 +431,7 @@ _test-tmp-stream: # (stream byte)
0/imm32 0/imm32
# current read index # current read index
0/imm32 0/imm32
# length # size
8/imm32 8/imm32
# data # data
00 00 00 00 00 00 00 00 # 8 bytes 00 00 00 00 00 00 00 00 # 8 bytes

View File

@ -20,7 +20,7 @@ $Stdin->buffer:
0/imm32 0/imm32
# current read index # current read index
0/imm32 0/imm32
# length # size
8/imm32 8/imm32
# data # data
00 00 00 00 00 00 00 00 # 8 bytes 00 00 00 00 00 00 00 00 # 8 bytes
@ -246,7 +246,7 @@ test-read-byte-buffered-refills-buffer:
# . . discard args # . . discard args
81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp
# pretend buffer is full # pretend buffer is full
# . _test-buffered-file->read = 6 # >= _test-buffered-file->length # . _test-buffered-file->read = 6 # >= _test-buffered-file->size
b8/copy-to-eax _test-buffered-file/imm32 b8/copy-to-eax _test-buffered-file/imm32
c7 0/subop/copy 1/mod/*+disp8 0/rm32/eax . . . . 8/disp8 6/imm32 # copy to *(eax+8) c7 0/subop/copy 1/mod/*+disp8 0/rm32/eax . . . . 8/disp8 6/imm32 # copy to *(eax+8)
# read-byte-buffered(_test-buffered-file) # read-byte-buffered(_test-buffered-file)
@ -279,7 +279,7 @@ $_test-buffered-file->buffer:
0/imm32 0/imm32
# current read index # current read index
0/imm32 0/imm32
# length # size
6/imm32 6/imm32
# data # data
00 00 00 00 00 00 # 6 bytes 00 00 00 00 00 00 # 6 bytes
@ -289,7 +289,7 @@ _test-input-stream: # (stream byte)
0/imm32 0/imm32
# current read index # current read index
0/imm32 0/imm32
# length # size
0x100/imm32 # 256 bytes 0x100/imm32 # 256 bytes
# data (16 lines x 16 bytes/line) # data (16 lines x 16 bytes/line)
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
@ -318,7 +318,7 @@ $_test-input-buffered-file->buffer:
0/imm32 0/imm32
# current read index # current read index
0/imm32 0/imm32
# length # size
6/imm32 6/imm32
# data # data
00 00 00 00 00 00 # 6 bytes 00 00 00 00 00 00 # 6 bytes

View File

@ -40,7 +40,7 @@ $write-stream:fake:
8b/copy 1/mod/*+disp8 5/rm32/ebp . . 7/r32/edi 8/disp8 . # copy *(ebp+8) to edi 8b/copy 1/mod/*+disp8 5/rm32/ebp . . 7/r32/edi 8/disp8 . # copy *(ebp+8) to edi
# esi = s # esi = s
8b/copy 1/mod/*+disp8 5/rm32/ebp . . 6/r32/esi 0xc/disp8 . # copy *(ebp+12) to esi 8b/copy 1/mod/*+disp8 5/rm32/ebp . . 6/r32/esi 0xc/disp8 . # copy *(ebp+12) to esi
# eax = _append-4(&f->data[f->write], &f->data[f->length], &s->data[s->read], &s->data[s->write]) # eax = _append-4(&f->data[f->write], &f->data[f->size], &s->data[s->read], &s->data[s->write])
# . . push &s->data[s->write] # . . push &s->data[s->write]
8b/copy 0/mod/indirect 6/rm32/esi . . . 0/r32/eax . . # copy *esi to eax 8b/copy 0/mod/indirect 6/rm32/esi . . . 0/r32/eax . . # copy *esi to eax
8d/copy-address 1/mod/*+disp8 4/rm32/sib 6/base/esi 0/index/eax . 0/r32/eax 0xc/disp8 . # copy esi+eax+12 to eax 8d/copy-address 1/mod/*+disp8 4/rm32/sib 6/base/esi 0/index/eax . 0/r32/eax 0xc/disp8 . # copy esi+eax+12 to eax
@ -49,7 +49,7 @@ $write-stream:fake:
8b/copy 1/mod/*+disp8 6/rm32/esi . . . 0/r32/eax 4/disp8 . # copy *(esi+4) to eax 8b/copy 1/mod/*+disp8 6/rm32/esi . . . 0/r32/eax 4/disp8 . # copy *(esi+4) to eax
8d/copy-address 1/mod/*+disp8 4/rm32/sib 6/base/esi 0/index/eax . 0/r32/eax 0xc/disp8 . # copy esi+eax+12 to eax 8d/copy-address 1/mod/*+disp8 4/rm32/sib 6/base/esi 0/index/eax . 0/r32/eax 0xc/disp8 . # copy esi+eax+12 to eax
50/push-eax 50/push-eax
# . . push &f->data[f->length] # . . push &f->data[f->size]
8b/copy 1/mod/*+disp8 7/rm32/edi . . . 0/r32/eax 8/disp8 . # copy *(edi+8) to eax 8b/copy 1/mod/*+disp8 7/rm32/edi . . . 0/r32/eax 8/disp8 . # copy *(edi+8) to eax
8d/copy-address 1/mod/*+disp8 4/rm32/sib 7/base/edi 0/index/eax . 0/r32/eax 0xc/disp8 . # copy edi+eax+12 to eax 8d/copy-address 1/mod/*+disp8 4/rm32/sib 7/base/edi 0/index/eax . 0/r32/eax 0xc/disp8 . # copy edi+eax+12 to eax
50/push-eax 50/push-eax
@ -247,7 +247,7 @@ _test-stream2: # (stream byte)
4/imm32 4/imm32
# current read index # current read index
1/imm32 1/imm32
# length # size
8/imm32 8/imm32
# data # data
41/A 42/B 43/C 44/D 00 00 00 00 # 8 bytes 41/A 42/B 43/C 44/D 00 00 00 00 # 8 bytes

View File

@ -16,7 +16,7 @@ $Stdout->buffer:
0/imm32 0/imm32
# current read index # current read index
0/imm32 0/imm32
# length # size
8/imm32 8/imm32
# data # data
00 00 00 00 00 00 00 00 # 8 bytes 00 00 00 00 00 00 00 00 # 8 bytes
@ -41,7 +41,7 @@ write-byte-buffered: # f: (addr buffered-file), n: int
8b/copy 1/mod/*+disp8 5/rm32/ebp . . . 7/r32/edi 8/disp8 . # copy *(ebp+8) to edi 8b/copy 1/mod/*+disp8 5/rm32/ebp . . . 7/r32/edi 8/disp8 . # copy *(ebp+8) to edi
# ecx = f->write # ecx = f->write
8b/copy 1/mod/*+disp8 7/rm32/edi . . . 1/r32/ecx 4/disp8 . # copy *(edi+4) to ecx 8b/copy 1/mod/*+disp8 7/rm32/edi . . . 1/r32/ecx 4/disp8 . # copy *(edi+4) to ecx
# if (f->write >= f->length) flush and clear f's stream # if (f->write >= f->size) flush and clear f's stream
3b/compare 1/mod/*+disp8 7/rm32/edi . . . 1/r32/ecx 0xc/disp8 . # compare ecx with *(edi+12) 3b/compare 1/mod/*+disp8 7/rm32/edi . . . 1/r32/ecx 0xc/disp8 . # compare ecx with *(edi+12)
7c/jump-if-< $write-byte-buffered:to-stream/disp8 7c/jump-if-< $write-byte-buffered:to-stream/disp8
# . flush(f) # . flush(f)
@ -216,7 +216,7 @@ append-byte: # f: (addr stream byte), n: int
8b/copy 1/mod/*+disp8 5/rm32/ebp . . . 7/r32/edi 8/disp8 . # copy *(ebp+8) to edi 8b/copy 1/mod/*+disp8 5/rm32/ebp . . . 7/r32/edi 8/disp8 . # copy *(ebp+8) to edi
# ecx = f->write # ecx = f->write
8b/copy 0/mod/indirect 7/rm32/edi . . . 1/r32/ecx . . # copy *edi to ecx 8b/copy 0/mod/indirect 7/rm32/edi . . . 1/r32/ecx . . # copy *edi to ecx
# if (f->write >= f->length) abort # if (f->write >= f->size) abort
3b/compare 1/mod/*+disp8 7/rm32/edi . . . 1/r32/ecx 8/disp8 . # compare ecx with *(edi+8) 3b/compare 1/mod/*+disp8 7/rm32/edi . . . 1/r32/ecx 8/disp8 . # compare ecx with *(edi+8)
7d/jump-if->= $append-byte:abort/disp8 7d/jump-if->= $append-byte:abort/disp8
$append-byte:to-stream: $append-byte:to-stream:
@ -288,7 +288,7 @@ _test-output-stream: # (stream byte)
0/imm32 0/imm32
# current read index # current read index
0/imm32 0/imm32
# length # size
0x400/imm32 # 1024 bytes 0x400/imm32 # 1024 bytes
# data (64 lines x 16 bytes/line) # data (64 lines x 16 bytes/line)
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
@ -365,7 +365,7 @@ $_test-output-buffered-file->buffer:
0/imm32 0/imm32
# current read index # current read index
0/imm32 0/imm32
# length # size
6/imm32 6/imm32
# data # data
00 00 00 00 00 00 # 6 bytes 00 00 00 00 00 00 # 6 bytes
@ -396,7 +396,7 @@ $_test-error-buffered-file->buffer:
0/imm32 0/imm32
# current read index # current read index
0/imm32 0/imm32
# length # size
6/imm32 6/imm32
# data # data
00 00 00 00 00 00 # 6 bytes 00 00 00 00 00 00 # 6 bytes

View File

@ -8,9 +8,9 @@
write-buffered: # f: (addr buffered-file), msg: (addr array byte) write-buffered: # f: (addr buffered-file), msg: (addr array byte)
# pseudocode: # pseudocode:
# in = msg->data # in = msg->data
# inend = &msg->data[msg->length] # inend = &msg->data[msg->size]
# while (in < inend) # while (in < inend)
# if f->write >= f->length # if f->write >= f->size
# flush(f) # flush(f)
# clear-stream(f) # clear-stream(f)
# c = *in # c = *in
@ -22,7 +22,7 @@ write-buffered: # f: (addr buffered-file), msg: (addr array byte)
# in: esi # in: esi
# inend: ecx # inend: ecx
# f: edi # f: edi
# f->length: edx # f->size: edx
# f->write: ebx (cached; need to keep in sync) # f->write: ebx (cached; need to keep in sync)
# c: eax # c: eax
# #
@ -40,12 +40,12 @@ write-buffered: # f: (addr buffered-file), msg: (addr array byte)
8b/copy 1/mod/*+disp8 5/rm32/ebp . . 0/r32/eax 0xc/disp8 . # copy *(ebp+12) to eax 8b/copy 1/mod/*+disp8 5/rm32/ebp . . 0/r32/eax 0xc/disp8 . # copy *(ebp+12) to eax
# var in/esi: (addr byte) = msg->data # var in/esi: (addr byte) = msg->data
8d/copy-address 1/mod/*+disp8 0/rm32/eax . . . 6/r32/esi 4/disp8 . # copy eax+4 to esi 8d/copy-address 1/mod/*+disp8 0/rm32/eax . . . 6/r32/esi 4/disp8 . # copy eax+4 to esi
# var inend/ecx: (addr byte) = &msg->data[msg->length] # var inend/ecx: (addr byte) = &msg->data[msg->size]
8b/copy 0/mod/indirect 0/rm32/eax . . . 1/r32/ecx . . # copy *eax to ecx 8b/copy 0/mod/indirect 0/rm32/eax . . . 1/r32/ecx . . # copy *eax to ecx
8d/copy-address 0/mod/indirect 4/rm32/sib 6/base/esi 1/index/ecx . 1/r32/ecx . . # copy esi+ecx to ecx 8d/copy-address 0/mod/indirect 4/rm32/sib 6/base/esi 1/index/ecx . 1/r32/ecx . . # copy esi+ecx to ecx
# edi = f # edi = f
8b/copy 1/mod/*+disp8 5/rm32/ebp . . 7/r32/edi 8/disp8 . # copy *(ebp+8) to edi 8b/copy 1/mod/*+disp8 5/rm32/ebp . . 7/r32/edi 8/disp8 . # copy *(ebp+8) to edi
# edx = f->length # edx = f->size
8b/copy 1/mod/*+disp8 7/rm32/edi . . . 2/r32/edx 0xc/disp8 . # copy *(edi+12) to edx 8b/copy 1/mod/*+disp8 7/rm32/edi . . . 2/r32/edx 0xc/disp8 . # copy *(edi+12) to edx
# ebx = f->write # ebx = f->write
8b/copy 1/mod/*+disp8 7/rm32/edi . . . 3/r32/ebx 4/disp8 . # copy *(edi+4) to ebx 8b/copy 1/mod/*+disp8 7/rm32/edi . . . 3/r32/ebx 4/disp8 . # copy *(edi+4) to ebx
@ -53,7 +53,7 @@ $write-buffered:loop:
# if (in >= inend) break # if (in >= inend) break
39/compare 3/mod/direct 6/rm32/esi . . . 1/r32/ecx . . # compare esi with ecx 39/compare 3/mod/direct 6/rm32/esi . . . 1/r32/ecx . . # compare esi with ecx
73/jump-if-addr>= $write-buffered:loop-end/disp8 73/jump-if-addr>= $write-buffered:loop-end/disp8
# if (f->write >= f->length) flush and clear f's stream # if (f->write >= f->size) flush and clear f's stream
39/compare 3/mod/direct 3/rm32/ebx . . . 2/r32/edx . . # compare ebx with edx 39/compare 3/mod/direct 3/rm32/ebx . . . 2/r32/edx . . # compare ebx with edx
7c/jump-if-< $write-buffered:to-stream/disp8 7c/jump-if-< $write-buffered:to-stream/disp8
# . persist f->write # . persist f->write
@ -215,7 +215,7 @@ $Stderr->buffer:
0/imm32 0/imm32
# current read index # current read index
0/imm32 0/imm32
# length # size
8/imm32 8/imm32
# data # data
00 00 00 00 00 00 00 00 # 8 bytes 00 00 00 00 00 00 00 00 # 8 bytes

View File

@ -362,10 +362,10 @@ parse-hex-int: # in: (addr array byte) -> result/eax: int
8b/copy 1/mod/*+disp8 5/rm32/ebp . . . 0/r32/eax 8/disp8 . # copy *(ebp+8) to eax 8b/copy 1/mod/*+disp8 5/rm32/ebp . . . 0/r32/eax 8/disp8 . # copy *(ebp+8) to eax
# var curr/ecx: (addr byte) = &in->data # var curr/ecx: (addr byte) = &in->data
8d/copy-address 1/mod/*+disp8 0/rm32/eax . . . 1/r32/ecx 4/disp8 . # copy eax+4 to ecx 8d/copy-address 1/mod/*+disp8 0/rm32/eax . . . 1/r32/ecx 4/disp8 . # copy eax+4 to ecx
# var max/edx: (addr byte) = &in->data[in->length] # var max/edx: (addr byte) = &in->data[in->size]
# . edx = in->length # . edx = in->size
8b/copy 0/mod/indirect 0/rm32/eax . . . 2/r32/edx . . # copy *eax to edx 8b/copy 0/mod/indirect 0/rm32/eax . . . 2/r32/edx . . # copy *eax to edx
# . edx = in->data + in->length # . edx = in->data + in->size
8d/copy-address 1/mod/*+disp8 4/rm32/sib 0/base/eax 2/index/edx . 2/r32/edx 4/disp8 . # copy eax+edx+4 to edx 8d/copy-address 1/mod/*+disp8 4/rm32/sib 0/base/eax 2/index/edx . 2/r32/edx 4/disp8 . # copy eax+edx+4 to edx
# return parse-hex-int-helper(curr, max) # return parse-hex-int-helper(curr, max)
# . . push args # . . push args

View File

@ -11,7 +11,7 @@ new-stream: # ad: (addr allocation-descriptor), length: int, elemsize: int -> a
89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp 89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp
# . save registers # . save registers
52/push-edx 52/push-edx
# var n/eax: int = elemsize * length + 12 (for read, write and length) # var n/eax: int = elemsize * length + 12 (for read, write and size)
# . eax = elemsize # . eax = elemsize
8b/copy 1/mod/*+disp8 5/rm32/ebp . . . 0/r32/eax 0x10/disp8 . # copy *(ebp+16) to eax 8b/copy 1/mod/*+disp8 5/rm32/ebp . . . 0/r32/eax 0x10/disp8 . # copy *(ebp+16) to eax
# . eax *= length # . eax *= length
@ -32,7 +32,7 @@ new-stream: # ad: (addr allocation-descriptor), length: int, elemsize: int -> a
e8/call allocate/disp32 e8/call allocate/disp32
# . . discard args # . . discard args
81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp
# eax->length = elemsize*length # eax->size = elemsize*length
89/copy 1/mod/*+disp8 0/rm32/eax . . . 2/r32/edx 8/disp8 . # copy edx to *(eax+8) 89/copy 1/mod/*+disp8 0/rm32/eax . . . 2/r32/edx 8/disp8 . # copy edx to *(eax+8)
# clear-stream(eax) # clear-stream(eax)
# . . push args # . . push args
@ -100,9 +100,9 @@ test-new-stream:
e8/call check-ints-equal/disp32 e8/call check-ints-equal/disp32
# . . discard args # . . discard args
81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32 # add to esp 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32 # add to esp
# check-ints-equal(eax->length, 6, msg) # check-ints-equal(eax->size, 6, msg)
# . . push args # . . push args
68/push "F - test-new-stream: sets length correctly"/imm32 68/push "F - test-new-stream: sets size correctly"/imm32
68/push 6/imm32 68/push 6/imm32
ff 6/subop/push 1/mod/*+disp8 0/rm32/eax . . . . . 8/disp8 # push *(eax+8) ff 6/subop/push 1/mod/*+disp8 0/rm32/eax . . . . . 8/disp8 # push *(eax+8)
# . . call # . . call

View File

@ -9,7 +9,7 @@
read-line-buffered: # f: (addr buffered-file), s: (addr stream byte) read-line-buffered: # f: (addr buffered-file), s: (addr stream byte)
# pseudocode: # pseudocode:
# while true # while true
# if (s->write >= s->length) abort # if (s->write >= s->size) abort
# if (f->read >= f->write) populate stream from file # if (f->read >= f->write) populate stream from file
# if (f->write == 0) break # if (f->write == 0) break
# AL = f->data[f->read] # AL = f->data[f->read]
@ -35,7 +35,7 @@ read-line-buffered: # f: (addr buffered-file), s: (addr stream byte)
# edx = s->write # edx = s->write
8b/copy 0/mod/indirect 7/rm32/edi . . . 2/r32/edx . . # copy *edi to edx 8b/copy 0/mod/indirect 7/rm32/edi . . . 2/r32/edx . . # copy *edi to edx
$read-line-buffered:loop: $read-line-buffered:loop:
# if (s->write >= s->length) abort # if (s->write >= s->size) abort
3b/compare 1/mod/*+disp8 7/rm32/edi . . . 2/r32/edx 8/disp8 . # compare edx with *(edi+8) 3b/compare 1/mod/*+disp8 7/rm32/edi . . . 2/r32/edx 8/disp8 . # compare edx with *(edi+8)
7d/jump-if->= $read-line-buffered:abort/disp8 7d/jump-if->= $read-line-buffered:abort/disp8
# if (f->read >= f->write) populate stream from file # if (f->read >= f->write) populate stream from file
@ -219,7 +219,7 @@ test-read-line-buffered-reads-final-line-until-Eof:
read-line: # f: (addr stream byte), s: (addr stream byte) read-line: # f: (addr stream byte), s: (addr stream byte)
# pseudocode: # pseudocode:
# while true # while true
# if (s->write >= s->length) abort # if (s->write >= s->size) abort
# if (f->read >= f->write) break # if (f->read >= f->write) break
# AL = f->data[f->read] # AL = f->data[f->read]
# s->data[s->write] = AL # s->data[s->write] = AL
@ -244,7 +244,7 @@ read-line: # f: (addr stream byte), s: (addr stream byte)
# edx = s->write # edx = s->write
8b/copy 0/mod/indirect 7/rm32/edi . . . 2/r32/edx . . # copy *edi to edx 8b/copy 0/mod/indirect 7/rm32/edi . . . 2/r32/edx . . # copy *edi to edx
$read-line:loop: $read-line:loop:
# if (s->write >= s->length) abort # if (s->write >= s->size) abort
3b/compare 1/mod/*+disp8 7/rm32/edi . . . 2/r32/edx 8/disp8 . # compare edx with *(edi+8) 3b/compare 1/mod/*+disp8 7/rm32/edi . . . 2/r32/edx 8/disp8 . # compare edx with *(edi+8)
0f 8d/jump-if->= $read-line:abort/disp32 0f 8d/jump-if->= $read-line:abort/disp32
# if (f->read >= f->write) break # if (f->read >= f->write) break

View File

@ -122,7 +122,7 @@ slice-equal?: # s: (addr slice), p: (addr array byte) -> eax: boolean
# if (p == 0) return (s == 0) # if (p == 0) return (s == 0)
# currs = s->start # currs = s->start
# maxs = s->end # maxs = s->end
# if (maxs - currs != p->length) return false # if (maxs - currs != p->size) return false
# currp = p->data # currp = p->data
# while currs < maxs # while currs < maxs
# if (*currs != *currp) return false # if (*currs != *currp) return false
@ -151,7 +151,7 @@ slice-equal?: # s: (addr slice), p: (addr array byte) -> eax: boolean
8b/copy 0/mod/indirect 6/rm32/esi . . . 2/r32/edx . . # copy *esi to edx 8b/copy 0/mod/indirect 6/rm32/esi . . . 2/r32/edx . . # copy *esi to edx
# var maxs/esi: (addr byte) = s->end # var maxs/esi: (addr byte) = s->end
8b/copy 1/mod/*+disp8 6/rm32/esi . . . 6/r32/esi 4/disp8 . # copy *(esi+4) to esi 8b/copy 1/mod/*+disp8 6/rm32/esi . . . 6/r32/esi 4/disp8 . # copy *(esi+4) to esi
# var slen/eax: int = maxs - currs # var ssize/eax: int = maxs - currs
89/copy 3/mod/direct 0/rm32/eax . . . 6/r32/esi . . # copy esi to eax 89/copy 3/mod/direct 0/rm32/eax . . . 6/r32/esi . . # copy esi to eax
29/subtract 3/mod/direct 0/rm32/eax . . . 2/r32/edx . . # subtract edx from eax 29/subtract 3/mod/direct 0/rm32/eax . . . 2/r32/edx . . # subtract edx from eax
# ebx = p # ebx = p
@ -165,7 +165,7 @@ $slice-equal?:null-string:
74/jump-if-= $slice-equal?:true/disp8 74/jump-if-= $slice-equal?:true/disp8
eb/jump $slice-equal?:false/disp8 eb/jump $slice-equal?:false/disp8
$slice-equal?:nonnull-string: $slice-equal?:nonnull-string:
# if (slen != p->length) return false # if (ssize != p->size) return false
39/compare 0/mod/indirect 3/rm32/ebx . . . 0/r32/eax . . # compare *ebx and eax 39/compare 0/mod/indirect 3/rm32/ebx . . . 0/r32/eax . . # compare *ebx and eax
75/jump-if-!= $slice-equal?:false/disp8 75/jump-if-!= $slice-equal?:false/disp8
# var currp/ebx: (addr byte) = p->data # var currp/ebx: (addr byte) = p->data
@ -486,12 +486,12 @@ test-slice-equal-with-null:
slice-starts-with?: # s: (addr slice), head: (addr array byte) -> eax: boolean slice-starts-with?: # s: (addr slice), head: (addr array byte) -> eax: boolean
# pseudocode # pseudocode
# lenh = head->length # hsize = head->size
# if (lenh > s->end - s->start) return false # if (hsize > s->end - s->start) return false
# i = 0 # i = 0
# currs = s->start # currs = s->start
# currp = head->data # currp = head->data
# while i < lenh # while i < hsize
# if (*currs != *currh) return false # if (*currs != *currh) return false
# ++i # ++i
# ++currs # ++currs
@ -504,7 +504,7 @@ slice-starts-with?: # s: (addr slice), head: (addr array byte) -> eax: boolean
# *currs: eax # *currs: eax
# *currh: ebx # *currh: ebx
# i: ecx # i: ecx
# lenh: edx # hsize: edx
# #
# . prologue # . prologue
55/push-ebp 55/push-ebp
@ -522,9 +522,9 @@ slice-starts-with?: # s: (addr slice), head: (addr array byte) -> eax: boolean
2b/subtract 0/mod/indirect 6/rm32/esi . . . 1/r32/ecx . . # subtract *esi from ecx 2b/subtract 0/mod/indirect 6/rm32/esi . . . 1/r32/ecx . . # subtract *esi from ecx
# edi = head # edi = head
8b/copy 1/mod/*+disp8 5/rm32/ebp . . . 7/r32/edi 0xc/disp8 . # copy *(ebp+12) to edi 8b/copy 1/mod/*+disp8 5/rm32/ebp . . . 7/r32/edi 0xc/disp8 . # copy *(ebp+12) to edi
# var lenh/edx: int = head->length # var hsize/edx: int = head->size
8b/copy 0/mod/indirect 7/rm32/edi . . . 2/r32/edx . . # copy *edi to edx 8b/copy 0/mod/indirect 7/rm32/edi . . . 2/r32/edx . . # copy *edi to edx
# if (lenh > lens) return false # if (hsize > lens) return false
39/compare 3/mod/direct 2/rm32/edx . . . 1/r32/ecx . . # compare edx with ecx 39/compare 3/mod/direct 2/rm32/edx . . . 1/r32/ecx . . # compare edx with ecx
7f/jump-if-> $slice-starts-with?:false/disp8 7f/jump-if-> $slice-starts-with?:false/disp8
# var currs/esi: (addr byte) = s->start # var currs/esi: (addr byte) = s->start
@ -538,7 +538,7 @@ slice-starts-with?: # s: (addr slice), head: (addr array byte) -> eax: boolean
# var c2/ebx: byte = 0 # var c2/ebx: byte = 0
31/xor 3/mod/direct 3/rm32/ebx . . . 3/r32/ebx . . # clear ebx 31/xor 3/mod/direct 3/rm32/ebx . . . 3/r32/ebx . . # clear ebx
$slice-starts-with?:loop: $slice-starts-with?:loop:
# if (i >= lenh) return true # if (i >= hsize) return true
39/compare 3/mod/direct 1/rm32/ecx . . . 2/r32/edx . . # compare ecx with edx 39/compare 3/mod/direct 1/rm32/ecx . . . 2/r32/edx . . # compare ecx with edx
7d/jump-if->= $slice-starts-with?:true/disp8 7d/jump-if->= $slice-starts-with?:true/disp8
# c1 = *currs # c1 = *currs
@ -809,7 +809,7 @@ write-slice: # out: (addr stream byte), s: (addr slice)
8b/copy 1/mod/*+disp8 6/rm32/esi . . . 6/r32/esi 4/disp8 . # copy *(esi+4) to esi 8b/copy 1/mod/*+disp8 6/rm32/esi . . . 6/r32/esi 4/disp8 . # copy *(esi+4) to esi
# edi = out # edi = out
8b/copy 1/mod/*+disp8 5/rm32/ebp . . 7/r32/edi 8/disp8 . # copy *(ebp+8) to edi 8b/copy 1/mod/*+disp8 5/rm32/ebp . . 7/r32/edi 8/disp8 . # copy *(ebp+8) to edi
# edx = out->length # edx = out->size
8b/copy 1/mod/*+disp8 7/rm32/edi . . . 2/r32/edx 8/disp8 . # copy *(edi+8) to edx 8b/copy 1/mod/*+disp8 7/rm32/edi . . . 2/r32/edx 8/disp8 . # copy *(edi+8) to edx
# ebx = out->write # ebx = out->write
8b/copy 0/mod/indirect 7/rm32/edi . . . 3/r32/ebx . . # copy *edi to ebx 8b/copy 0/mod/indirect 7/rm32/edi . . . 3/r32/ebx . . # copy *edi to ebx
@ -817,7 +817,7 @@ $write-slice:loop:
# if (curr >= max) break # if (curr >= max) break
39/compare 3/mod/direct 1/rm32/ecx . . . 6/r32/esi . . # compare ecx with esi 39/compare 3/mod/direct 1/rm32/ecx . . . 6/r32/esi . . # compare ecx with esi
73/jump-if-addr>= $write-slice:loop-end/disp8 73/jump-if-addr>= $write-slice:loop-end/disp8
# if (out->write >= out->length) abort # if (out->write >= out->size) abort
39/compare 3/mod/direct 3/rm32/ebx . . . 2/r32/edx . . # compare ebx with edx 39/compare 3/mod/direct 3/rm32/ebx . . . 2/r32/edx . . # compare ebx with edx
7d/jump-if->= $write-slice:abort/disp8 7d/jump-if->= $write-slice:abort/disp8
# out->data[out->write] = *in # out->data[out->write] = *in
@ -925,7 +925,7 @@ write-slice-buffered: # out: (addr buffered-file), s: (addr slice)
8b/copy 1/mod/*+disp8 6/rm32/esi . . . 6/r32/esi 4/disp8 . # copy *(esi+4) to esi 8b/copy 1/mod/*+disp8 6/rm32/esi . . . 6/r32/esi 4/disp8 . # copy *(esi+4) to esi
# edi = out # edi = out
8b/copy 1/mod/*+disp8 5/rm32/ebp . . 7/r32/edi 8/disp8 . # copy *(ebp+8) to edi 8b/copy 1/mod/*+disp8 5/rm32/ebp . . 7/r32/edi 8/disp8 . # copy *(ebp+8) to edi
# edx = out->length # edx = out->size
8b/copy 1/mod/*+disp8 7/rm32/edi . . . 2/r32/edx 0xc/disp8 . # copy *(edi+12) to edx 8b/copy 1/mod/*+disp8 7/rm32/edi . . . 2/r32/edx 0xc/disp8 . # copy *(edi+12) to edx
# ebx = out->write # ebx = out->write
8b/copy 1/mod/*+disp8 7/rm32/edi . . . 3/r32/ebx 4/disp8 . # copy *(edi+4) to ebx 8b/copy 1/mod/*+disp8 7/rm32/edi . . . 3/r32/ebx 4/disp8 . # copy *(edi+4) to ebx
@ -933,7 +933,7 @@ $write-slice-buffered:loop:
# if (curr >= max) break # if (curr >= max) break
39/compare 3/mod/direct 1/rm32/ecx . . . 6/r32/esi . . # compare ecx with esi 39/compare 3/mod/direct 1/rm32/ecx . . . 6/r32/esi . . # compare ecx with esi
73/jump-if-addr>= $write-slice-buffered:loop-end/disp8 73/jump-if-addr>= $write-slice-buffered:loop-end/disp8
# if (out->write >= out->length) flush and clear out's stream # if (out->write >= out->size) flush and clear out's stream
39/compare 3/mod/direct 3/rm32/ebx . . . 2/r32/edx . . # compare ebx with edx 39/compare 3/mod/direct 3/rm32/ebx . . . 2/r32/edx . . # compare ebx with edx
7c/jump-if-< $write-slice-buffered:to-stream/disp8 7c/jump-if-< $write-slice-buffered:to-stream/disp8
# . persist out->write # . persist out->write
@ -1056,7 +1056,7 @@ slice-to-string: # ad: (addr allocation-descriptor), in: (addr slice) -> out/ea
8b/copy 0/mod/indirect 6/rm32/esi . . . 2/r32/edx . . # copy *esi to edx 8b/copy 0/mod/indirect 6/rm32/esi . . . 2/r32/edx . . # copy *esi to edx
# var max/ebx: (addr byte) = in->end # var max/ebx: (addr byte) = in->end
8b/copy 1/mod/*+disp8 6/rm32/esi . . . 3/r32/ebx 4/disp8 . # copy *(esi+4) to ebx 8b/copy 1/mod/*+disp8 6/rm32/esi . . . 3/r32/ebx 4/disp8 . # copy *(esi+4) to ebx
# var size/ecx: int = max - curr + 4 # total size of output string (including the initial length) # var size/ecx: int = max - curr + 4 # total size of output string (including the initial 'size' field)
89/copy 3/mod/direct 1/rm32/ecx . . . 3/r32/ebx . . # copy ebx to ecx 89/copy 3/mod/direct 1/rm32/ecx . . . 3/r32/ebx . . # copy ebx to ecx
29/subtract 3/mod/direct 1/rm32/ecx . . . 2/r32/edx . . # subtract edx from ecx 29/subtract 3/mod/direct 1/rm32/ecx . . . 2/r32/edx . . # subtract edx from ecx
81 0/subop/add 3/mod/direct 1/rm32/ecx . . . . . 4/imm32 # add to ecx 81 0/subop/add 3/mod/direct 1/rm32/ecx . . . . . 4/imm32 # add to ecx
@ -1071,7 +1071,7 @@ slice-to-string: # ad: (addr allocation-descriptor), in: (addr slice) -> out/ea
# if (eax == 0) abort # if (eax == 0) abort
3d/compare-eax-and 0/imm32 3d/compare-eax-and 0/imm32
74/jump-if-= $slice-to-string:abort/disp8 74/jump-if-= $slice-to-string:abort/disp8
# out->length = size-4 # out->size = size-4
89/copy 0/mod/indirect 0/rm32/eax . . . 1/r32/ecx . . # copy ecx to *eax 89/copy 0/mod/indirect 0/rm32/eax . . . 1/r32/ecx . . # copy ecx to *eax
81 5/subop/subtract 0/mod/indirect 0/rm32/eax . . . . . 4/imm32 # subtract 4 from *eax 81 5/subop/subtract 0/mod/indirect 0/rm32/eax . . . . . 4/imm32 # subtract 4 from *eax
# save out # save out

View File

@ -22,7 +22,7 @@ print-int32-decimal: # out: (addr stream byte), n: int32
# push '-' # push '-'
# w = out->write # w = out->write
# curr = &out->data[out->write] # curr = &out->data[out->write]
# max = &out->data[out->length] # max = &out->data[out->size]
# while true # while true
# pop into eax # pop into eax
# if (eax == sentinel) break # if (eax == sentinel) break
@ -78,7 +78,7 @@ $print-int32-decimal:write:
8b/copy 0/mod/indirect 7/rm32/edi . . . 2/r32/edx . . # copy *edi to edx 8b/copy 0/mod/indirect 7/rm32/edi . . . 2/r32/edx . . # copy *edi to edx
# var curr/ecx: (addr byte) = &out->data[out->write] # var curr/ecx: (addr byte) = &out->data[out->write]
8d/copy-address 1/mod/*+disp8 4/rm32/sib 7/base/edi 2/index/edx . 1/r32/ecx 0xc/disp8 . # copy ebx+edx+12 to ecx 8d/copy-address 1/mod/*+disp8 4/rm32/sib 7/base/edi 2/index/edx . 1/r32/ecx 0xc/disp8 . # copy ebx+edx+12 to ecx
# var max/ebx: (addr byte) = &out->data[out->length] # var max/ebx: (addr byte) = &out->data[out->size]
8b/copy 1/mod/*+disp8 7/rm32/edi . . . 3/r32/ebx 8/disp8 . # copy *(edi+8) to ebx 8b/copy 1/mod/*+disp8 7/rm32/edi . . . 3/r32/ebx 8/disp8 . # copy *(edi+8) to ebx
8d/copy-address 1/mod/*+disp8 4/rm32/sib 7/base/edi 3/index/ebx . 3/r32/ebx 0xc/disp8 . # copy edi+ebx+12 to ebx 8d/copy-address 1/mod/*+disp8 4/rm32/sib 7/base/edi 3/index/ebx . 3/r32/ebx 0xc/disp8 . # copy edi+ebx+12 to ebx
$print-int32-decimal:write-loop: $print-int32-decimal:write-loop:

View File

@ -127,7 +127,7 @@ test-get:
# - setup: create a table with a couple of keys # - setup: create a table with a couple of keys
# var table/ecx: (stream {string, number} 16) # 2 rows * 8 bytes/row # var table/ecx: (stream {string, number} 16) # 2 rows * 8 bytes/row
81 5/subop/subtract 3/mod/direct 4/rm32/esp . . . . . 0x10/imm32 # subtract from esp 81 5/subop/subtract 3/mod/direct 4/rm32/esp . . . . . 0x10/imm32 # subtract from esp
68/push 0x10/imm32/length 68/push 0x10/imm32/size
68/push 0/imm32/read 68/push 0/imm32/read
68/push 0/imm32/write 68/push 0/imm32/write
89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx 89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx
@ -308,7 +308,7 @@ test-get-slice:
# - setup: create a table with a couple of keys # - setup: create a table with a couple of keys
# var table/ecx: (stream {string, number} 16) # 2 rows * 8 bytes/row # var table/ecx: (stream {string, number} 16) # 2 rows * 8 bytes/row
81 5/subop/subtract 3/mod/direct 4/rm32/esp . . . . . 0x10/imm32 # subtract from esp 81 5/subop/subtract 3/mod/direct 4/rm32/esp . . . . . 0x10/imm32 # subtract from esp
68/push 0x10/imm32/length 68/push 0x10/imm32/size
68/push 0/imm32/read 68/push 0/imm32/read
68/push 0/imm32/write 68/push 0/imm32/write
89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx 89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx
@ -409,7 +409,7 @@ get-or-insert: # table: (addr stream {string_key, T}), key: string_key, row-siz
# if string-equal?(key, *curr) # if string-equal?(key, *curr)
# return curr+4 # return curr+4
# curr += row-size # curr += row-size
# if table->write >= table->length # if table->write >= table->size
# abort # abort
# zero-out(max, row-size) # zero-out(max, row-size)
# *max = key # *max = key
@ -456,7 +456,7 @@ $get-or-insert:mismatch:
$get-or-insert:not-found: $get-or-insert:not-found:
# result/eax = 0 # result/eax = 0
31/xor 3/mod/direct 0/rm32/eax . . . 0/r32/eax . . # clear eax 31/xor 3/mod/direct 0/rm32/eax . . . 0/r32/eax . . # clear eax
# if (table->write >= table->length) abort # if (table->write >= table->size) abort
8b/copy 0/mod/indirect 6/rm32/esi . . . 1/r32/ecx . . # copy *esi to ecx 8b/copy 0/mod/indirect 6/rm32/esi . . . 1/r32/ecx . . # copy *esi to ecx
3b/compare 1/mod/*+disp8 6/rm32/esi . . . 1/r32/ecx 8/disp8 . # compare ecx with *(esi+8) 3b/compare 1/mod/*+disp8 6/rm32/esi . . . 1/r32/ecx 8/disp8 . # compare ecx with *(esi+8)
73/jump-if-addr>= $get-or-insert:abort/disp8 73/jump-if-addr>= $get-or-insert:abort/disp8
@ -514,7 +514,7 @@ test-get-or-insert:
89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp 89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp
# var table/ecx: (stream {string, number} 16) # 2 rows * 8 bytes/row # var table/ecx: (stream {string, number} 16) # 2 rows * 8 bytes/row
81 5/subop/subtract 3/mod/direct 4/rm32/esp . . . . . 0x10/imm32 # subtract from esp 81 5/subop/subtract 3/mod/direct 4/rm32/esp . . . . . 0x10/imm32 # subtract from esp
68/push 0x10/imm32/length 68/push 0x10/imm32/size
68/push 0/imm32/read 68/push 0/imm32/read
68/push 0/imm32/write 68/push 0/imm32/write
89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx 89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx
@ -658,7 +658,7 @@ get-or-insert-slice: # table: (addr stream {string_key, T}), key: (addr slice),
# if slice-equal?(key, *curr) # if slice-equal?(key, *curr)
# return curr+4 # return curr+4
# curr += row-size # curr += row-size
# if table->write >= table->length # if table->write >= table->size
# abort # abort
# zero-out(max, row-size) # zero-out(max, row-size)
# *max = slice-to-string(ad, key) # *max = slice-to-string(ad, key)
@ -705,7 +705,7 @@ $get-or-insert-slice:mismatch:
$get-or-insert-slice:not-found: $get-or-insert-slice:not-found:
# result/eax = 0 # result/eax = 0
31/xor 3/mod/direct 0/rm32/eax . . . 0/r32/eax . . # clear eax 31/xor 3/mod/direct 0/rm32/eax . . . 0/r32/eax . . # clear eax
# if (table->write >= table->length) abort # if (table->write >= table->size) abort
8b/copy 0/mod/indirect 6/rm32/esi . . . 1/r32/ecx . . # copy *esi to ecx 8b/copy 0/mod/indirect 6/rm32/esi . . . 1/r32/ecx . . # copy *esi to ecx
3b/compare 1/mod/*+disp8 6/rm32/esi . . . 1/r32/ecx 8/disp8 . # compare ecx with *(esi+8) 3b/compare 1/mod/*+disp8 6/rm32/esi . . . 1/r32/ecx 8/disp8 . # compare ecx with *(esi+8)
7d/jump-if->= $get-or-insert-slice:abort/disp8 7d/jump-if->= $get-or-insert-slice:abort/disp8
@ -769,7 +769,7 @@ test-get-or-insert-slice:
89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp 89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp
# var table/ecx: (stream {string, number} 16) # 2 rows * 8 bytes/row # var table/ecx: (stream {string, number} 16) # 2 rows * 8 bytes/row
81 5/subop/subtract 3/mod/direct 4/rm32/esp . . . . . 0x10/imm32 # subtract from esp 81 5/subop/subtract 3/mod/direct 4/rm32/esp . . . . . 0x10/imm32 # subtract from esp
68/push 0x10/imm32/length 68/push 0x10/imm32/size
68/push 0/imm32/read 68/push 0/imm32/read
68/push 0/imm32/write 68/push 0/imm32/write
89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx 89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx
@ -1054,7 +1054,7 @@ test-get-or-stop:
81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp
# var table/ecx: (stream {string, number} 16) # 2 rows * 8 bytes/row # var table/ecx: (stream {string, number} 16) # 2 rows * 8 bytes/row
81 5/subop/subtract 3/mod/direct 4/rm32/esp . . . . . 0x10/imm32 # subtract from esp 81 5/subop/subtract 3/mod/direct 4/rm32/esp . . . . . 0x10/imm32 # subtract from esp
68/push 0x10/imm32/length 68/push 0x10/imm32/size
68/push 0/imm32/read 68/push 0/imm32/read
68/push 0/imm32/write 68/push 0/imm32/write
89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx 89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx
@ -1270,7 +1270,7 @@ test-get-slice-or-stop:
81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp
# var table/ecx: (stream {string, number} 16) # 2 rows * 8 bytes/row # var table/ecx: (stream {string, number} 16) # 2 rows * 8 bytes/row
81 5/subop/subtract 3/mod/direct 4/rm32/esp . . . . . 0x10/imm32 # subtract from esp 81 5/subop/subtract 3/mod/direct 4/rm32/esp . . . . . 0x10/imm32 # subtract from esp
68/push 0x10/imm32/length 68/push 0x10/imm32/size
68/push 0/imm32/read 68/push 0/imm32/read
68/push 0/imm32/write 68/push 0/imm32/write
89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx 89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx
@ -1446,7 +1446,7 @@ test-maybe-get:
# - setup: create a table with one row # - setup: create a table with one row
# var table/ecx: (stream {string, number} 16) # 2 rows * 8 bytes/row # var table/ecx: (stream {string, number} 16) # 2 rows * 8 bytes/row
81 5/subop/subtract 3/mod/direct 4/rm32/esp . . . . . 0x10/imm32 # subtract from esp 81 5/subop/subtract 3/mod/direct 4/rm32/esp . . . . . 0x10/imm32 # subtract from esp
68/push 0x10/imm32/length 68/push 0x10/imm32/size
68/push 0/imm32/read 68/push 0/imm32/read
68/push 0/imm32/write 68/push 0/imm32/write
89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx 89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx
@ -1593,7 +1593,7 @@ test-maybe-get-slice:
# - setup: create a table with one row # - setup: create a table with one row
# var table/ecx: (stream {string, number} 16) # 2 rows * 8 bytes/row # var table/ecx: (stream {string, number} 16) # 2 rows * 8 bytes/row
81 5/subop/subtract 3/mod/direct 4/rm32/esp . . . . . 0x10/imm32 # subtract from esp 81 5/subop/subtract 3/mod/direct 4/rm32/esp . . . . . 0x10/imm32 # subtract from esp
68/push 0x10/imm32/length 68/push 0x10/imm32/size
68/push 0/imm32/read 68/push 0/imm32/read
68/push 0/imm32/write 68/push 0/imm32/write
89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx 89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx

View File

@ -8,7 +8,7 @@
slurp: # f: (addr buffered-file), s: (addr stream byte) slurp: # f: (addr buffered-file), s: (addr stream byte)
# pseudocode: # pseudocode:
# while true # while true
# if (s->write >= s->length) abort # if (s->write >= s->size) abort
# if (f->read >= f->write) populate stream from file # if (f->read >= f->write) populate stream from file
# if (f->write == 0) break # if (f->write == 0) break
# AL = f->data[f->read] # AL = f->data[f->read]
@ -33,7 +33,7 @@ slurp: # f: (addr buffered-file), s: (addr stream byte)
# edx = s->write # edx = s->write
8b/copy 0/mod/indirect 7/rm32/edi . . . 2/r32/edx . . # copy *edi to edx 8b/copy 0/mod/indirect 7/rm32/edi . . . 2/r32/edx . . # copy *edi to edx
$slurp:loop: $slurp:loop:
# if (s->write >= s->length) abort # if (s->write >= s->size) abort
3b/compare 1/mod/*+disp8 7/rm32/edi . . . 2/r32/edx 8/disp8 . # compare edx with *(edi+8) 3b/compare 1/mod/*+disp8 7/rm32/edi . . . 2/r32/edx 8/disp8 . # compare edx with *(edi+8)
7d/jump-if->= $slurp:abort/disp8 7d/jump-if->= $slurp:abort/disp8
# if (f->read >= f->write) populate stream from file # if (f->read >= f->write) populate stream from file

View File

@ -16,7 +16,7 @@ compute-width: # word: (addr array byte) -> eax: int
51/push-ecx 51/push-ecx
# eax = word # eax = word
8b/copy 1/mod/*+disp8 5/rm32/ebp . . . 0/r32/eax 8/disp8 . # copy *(ebp+8) to ecx 8b/copy 1/mod/*+disp8 5/rm32/ebp . . . 0/r32/eax 8/disp8 . # copy *(ebp+8) to ecx
# var ecx: (addr byte) = &word[word->length] # var ecx: (addr byte) = &word[word->size]
8b/copy 0/mod/indirect 0/rm32/eax . . . 1/r32/ecx . . # copy *eax to ecx 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 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
# eax = word->data # eax = word->data

View File

@ -19,7 +19,7 @@ emit-hex-array: # out: (addr buffered-file), arr: (addr array byte)
8b/copy 1/mod/*+disp8 5/rm32/ebp . . . 2/r32/edx 0xc/disp8 . # copy *(ebp+12) to edx 8b/copy 1/mod/*+disp8 5/rm32/ebp . . . 2/r32/edx 0xc/disp8 . # copy *(ebp+12) to edx
# var curr/ecx: (addr byte) = arr->data # var curr/ecx: (addr byte) = arr->data
8d/copy-address 1/mod/*+disp8 2/rm32/edx . . . 1/r32/ecx 4/disp8 . # copy edx+4 to ecx 8d/copy-address 1/mod/*+disp8 2/rm32/edx . . . 1/r32/ecx 4/disp8 . # copy edx+4 to ecx
# var max/edx: (addr byte) = &arr->data[arr->length] # var max/edx: (addr byte) = &arr->data[arr->size]
8b/copy 0/mod/indirect 2/rm32/edx . . . 2/r32/edx . . # copy *edx to edx 8b/copy 0/mod/indirect 2/rm32/edx . . . 2/r32/edx . . # copy *edx to edx
01/add 3/mod/direct 2/rm32/edx . . . 1/r32/ecx . . # add ecx to edx 01/add 3/mod/direct 2/rm32/edx . . . 1/r32/ecx . . # add ecx to edx
# var c/eax: byte = 0 # var c/eax: byte = 0
@ -73,7 +73,7 @@ test-emit-hex-array:
81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp
# var arr/ecx (array byte) = [01, 02, 03] # var arr/ecx (array byte) = [01, 02, 03]
68/push 0x00030201/imm32 # bytes 01 02 03 68/push 0x00030201/imm32 # bytes 01 02 03
68/push 3/imm32/length 68/push 3/imm32/size
89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx 89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx
# emit-hex-array(_test-output-buffered-file, arr) # emit-hex-array(_test-output-buffered-file, arr)
# . . push args # . . push args

View File

@ -17,7 +17,7 @@ write-int: # out: (addr stream byte), n: int
8b/copy 1/mod/*+disp8 5/rm32/ebp . . . 7/r32/edi 8/disp8 . # copy *(ebp+8) to edi 8b/copy 1/mod/*+disp8 5/rm32/ebp . . . 7/r32/edi 8/disp8 . # copy *(ebp+8) to edi
# ecx = out->write # ecx = out->write
8b/copy 0/mod/indirect 7/rm32/edi . . . 1/r32/ecx . . # copy *edi to ecx 8b/copy 0/mod/indirect 7/rm32/edi . . . 1/r32/ecx . . # copy *edi to ecx
# if (out->write >= out->length) abort # if (out->write >= out->size) abort
3b/compare 1/mod/*+disp8 7/rm32/edi . . . 1/r32/ecx 8/disp8 . # compare ecx with *(edi+8) 3b/compare 1/mod/*+disp8 7/rm32/edi . . . 1/r32/ecx 8/disp8 . # compare ecx with *(edi+8)
7d/jump-if->= $write-int:abort/disp8 7d/jump-if->= $write-int:abort/disp8
$write-int:to-stream: $write-int:to-stream:

View File

@ -1,6 +1,6 @@
# A stack looks like this: # A stack looks like this:
# top: int # top: int
# data: (array byte) # prefixed by length as usual # data: (array byte) # prefixed by size as usual
== code == code
# instruction effective address register displacement immediate # instruction effective address register displacement immediate
@ -16,7 +16,7 @@ clear-stack: # s: (addr stack)
51/push-ecx 51/push-ecx
# eax = s # eax = s
8b/copy 1/mod/*+disp8 5/rm32/ebp . . . 0/r32/eax 8/disp8 . # copy *(ebp+8) to eax 8b/copy 1/mod/*+disp8 5/rm32/ebp . . . 0/r32/eax 8/disp8 . # copy *(ebp+8) to eax
# var max/ecx: (addr byte) = &s->data[s->length] # var max/ecx: (addr byte) = &s->data[s->size]
8b/copy 1/mod/*+disp8 0/rm32/eax . . . 1/r32/ecx 4/disp8 . # copy *(eax+4) to eax 8b/copy 1/mod/*+disp8 0/rm32/eax . . . 1/r32/ecx 4/disp8 . # copy *(eax+4) to eax
8d/copy-address 1/mod/*+disp8 4/rm32/sib 0/base/eax 1/index/ecx . 1/r32/ecx 8/disp8 . # copy eax+ecx+8 to ecx 8d/copy-address 1/mod/*+disp8 4/rm32/sib 0/base/eax 1/index/ecx . 1/r32/ecx 8/disp8 . # copy eax+ecx+8 to ecx
# s->top = 0 # s->top = 0
@ -48,7 +48,7 @@ test-clear-stack:
# var stack/ecx = stack of size 8 with random data in it # var stack/ecx = stack of size 8 with random data in it
68/push 34/imm32 68/push 34/imm32
68/push 35/imm32 68/push 35/imm32
68/push 8/imm32/length 68/push 8/imm32/size
68/push 14/imm32/top 68/push 14/imm32/top
89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx 89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx
# clear(stack) # clear(stack)
@ -69,11 +69,11 @@ test-clear-stack:
e8/call check-ints-equal/disp32 e8/call check-ints-equal/disp32
# . . discard args # . . discard args
81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32 # add to esp 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32 # add to esp
# length should remain 8 # size should remain 8
58/pop-to-eax 58/pop-to-eax
# . check-ints-equal(eax, 8, msg) # . check-ints-equal(eax, 8, msg)
# . . push args # . . push args
68/push "F - test-clear-stack: length"/imm32 68/push "F - test-clear-stack: size"/imm32
68/push 8/imm32 68/push 8/imm32
50/push-eax 50/push-eax
# . . call # . . call
@ -119,7 +119,7 @@ push: # s: (addr stack), n: int
8b/copy 1/mod/*+disp8 5/rm32/ebp . . . 6/r32/esi 8/disp8 . # copy *(ebp+8) to esi 8b/copy 1/mod/*+disp8 5/rm32/ebp . . . 6/r32/esi 8/disp8 . # copy *(ebp+8) to esi
# ecx = s->top # ecx = s->top
8b/copy 0/mod/indirect 6/rm32/esi . . . 1/r32/ecx . . # copy *esi to ecx 8b/copy 0/mod/indirect 6/rm32/esi . . . 1/r32/ecx . . # copy *esi to ecx
# if (s->top >= s->length) abort # if (s->top >= s->size) abort
39/compare 1/mod/*+disp8 6/rm32/esi . . . 1/r32/ecx 4/disp8 . # compare *(esi+4) and ecx 39/compare 1/mod/*+disp8 6/rm32/esi . . . 1/r32/ecx 4/disp8 . # compare *(esi+4) and ecx
7e/jump-if-<= $push:abort/disp8 7e/jump-if-<= $push:abort/disp8
# s->data[s->top] = n # s->data[s->top] = n
@ -167,7 +167,7 @@ test-push:
# var stack/ecx = empty stack of size 8 # var stack/ecx = empty stack of size 8
68/push 0/imm32 68/push 0/imm32
68/push 0/imm32 68/push 0/imm32
68/push 8/imm32/length 68/push 8/imm32/size
68/push 0/imm32/top 68/push 0/imm32/top
89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx 89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx
# push(stack, 0x42) # push(stack, 0x42)
@ -189,11 +189,11 @@ test-push:
e8/call check-ints-equal/disp32 e8/call check-ints-equal/disp32
# . . discard args # . . discard args
81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32 # add to esp 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32 # add to esp
# check length # check size
58/pop-to-eax 58/pop-to-eax
# . check-ints-equal(eax, 8, msg) # . check-ints-equal(eax, 8, msg)
# . . push args # . . push args
68/push "F - test-push: length"/imm32 68/push "F - test-push: size"/imm32
68/push 8/imm32 68/push 8/imm32
50/push-eax 50/push-eax
# . . call # . . call
@ -285,7 +285,7 @@ test-pop:
# var stack/ecx = stack of size 8 containing just 0x42 # var stack/ecx = stack of size 8 containing just 0x42
68/push 0/imm32 68/push 0/imm32
68/push 0x42/imm32 68/push 0x42/imm32
68/push 8/imm32/length 68/push 8/imm32/size
68/push 4/imm32/top 68/push 4/imm32/top
89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx 89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx
# eax = pop(stack) # eax = pop(stack)
@ -315,11 +315,11 @@ test-pop:
e8/call check-ints-equal/disp32 e8/call check-ints-equal/disp32
# . . discard args # . . discard args
81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32 # add to esp 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32 # add to esp
# check length # check size
58/pop-to-eax 58/pop-to-eax
# . check-ints-equal(eax, 8, msg) # . check-ints-equal(eax, 8, msg)
# . . push args # . . push args
68/push "F - test-pop: length"/imm32 68/push "F - test-pop: size"/imm32
68/push 8/imm32 68/push 8/imm32
50/push-eax 50/push-eax
# . . call # . . call
@ -386,7 +386,7 @@ test-top:
# var stack/ecx = stack of size 8 containing just 0x42 # var stack/ecx = stack of size 8 containing just 0x42
68/push 0/imm32 68/push 0/imm32
68/push 0x42/imm32 68/push 0x42/imm32
68/push 8/imm32/length 68/push 8/imm32/size
68/push 4/imm32/top 68/push 4/imm32/top
89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx 89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx
# eax = top(stack) # eax = top(stack)

View File

@ -4,12 +4,12 @@
array-equal?: # a: (addr array int), b: (addr array int) -> eax: boolean array-equal?: # a: (addr array int), b: (addr array int) -> eax: boolean
# pseudocode: # pseudocode:
# lena = a->length # asize = a->size
# if (lena != b->length) return false # if (asize != b->size) return false
# i = 0 # i = 0
# curra = a->data # curra = a->data
# currb = b->data # currb = b->data
# while i < lena # while i < asize
# i1 = *curra # i1 = *curra
# i2 = *currb # i2 = *currb
# if (c1 != c2) return false # if (c1 != c2) return false
@ -18,7 +18,7 @@ array-equal?: # a: (addr array int), b: (addr array int) -> eax: boolean
# #
# registers: # registers:
# i: ecx # i: ecx
# lena: edx # asize: edx
# curra: esi # curra: esi
# currb: edi # currb: edi
# i1: eax # i1: eax
@ -37,10 +37,10 @@ array-equal?: # a: (addr array int), b: (addr array int) -> eax: boolean
8b/-> *(ebp+8) 6/r32/esi 8b/-> *(ebp+8) 6/r32/esi
# edi = b # edi = b
8b/-> *(ebp+0xc) 7/r32/edi 8b/-> *(ebp+0xc) 7/r32/edi
# var lena/edx: int = a->length # var asize/edx: int = a->size
8b/-> *esi 2/r32/edx 8b/-> *esi 2/r32/edx
$array-equal?:lengths: $array-equal?:sizes:
# if (lena != b->length) return false # if (asize != b->size) return false
39/compare *edi 2/r32/edx 39/compare *edi 2/r32/edx
75/jump-if-!= $array-equal?:false/disp8 75/jump-if-!= $array-equal?:false/disp8
# var curra/esi: (addr byte) = a->data # var curra/esi: (addr byte) = a->data
@ -52,7 +52,7 @@ $array-equal?:lengths:
# var vala/eax: int # var vala/eax: int
# var valb/ebx: int # var valb/ebx: int
$array-equal?:loop: $array-equal?:loop:
# if (i >= lena) return true # if (i >= asize) return true
39/compare %ecx 2/r32/edx 39/compare %ecx 2/r32/edx
7d/jump-if->= $array-equal?:true/disp8 7d/jump-if->= $array-equal?:true/disp8
# var vala/eax: int = *curra # var vala/eax: int = *curra
@ -104,7 +104,7 @@ test-compare-empty-with-empty-array:
5d/pop-to-ebp 5d/pop-to-ebp
c3/return c3/return
test-compare-empty-with-non-empty-array: # also checks length-mismatch code path test-compare-empty-with-non-empty-array: # also checks size-mismatch code path
# . prologue # . prologue
55/push-ebp 55/push-ebp
89/<- %ebp 4/r32/esp 89/<- %ebp 4/r32/esp
@ -147,7 +147,7 @@ test-compare-equal-arrays:
5d/pop-to-ebp 5d/pop-to-ebp
c3/return c3/return
test-compare-inequal-arrays-equal-lengths: test-compare-inequal-arrays-equal-sizes:
# . prologue # . prologue
55/push-ebp 55/push-ebp
89/<- %ebp 4/r32/esp 89/<- %ebp 4/r32/esp
@ -165,7 +165,7 @@ test-compare-inequal-arrays-equal-lengths:
89/<- %edx 4/r32/esp 89/<- %edx 4/r32/esp
# #
(array-equal? %ecx %edx) # => eax (array-equal? %ecx %edx) # => eax
(check-ints-equal %eax 0 "F - test-compare-inequal-arrays-equal-lengths") (check-ints-equal %eax 0 "F - test-compare-inequal-arrays-equal-sizes")
# . epilogue # . epilogue
89/<- %esp 5/r32/ebp 89/<- %esp 5/r32/ebp
5d/pop-to-ebp 5d/pop-to-ebp
@ -173,7 +173,7 @@ test-compare-inequal-arrays-equal-lengths:
parse-array-of-ints: # ad: (addr allocation-descriptor), s: (addr string) -> result/eax: (handle array int) parse-array-of-ints: # ad: (addr allocation-descriptor), s: (addr string) -> result/eax: (handle array int)
# pseudocode # pseudocode
# end = &s->data[s->length] # end = &s->data[s->size]
# curr = s->data # curr = s->data
# size = 0 # size = 0
# while true # while true
@ -209,8 +209,8 @@ parse-array-of-ints: # ad: (addr allocation-descriptor), s: (addr string) -> re
8b/-> *(ebp+0xc) 6/r32/esi 8b/-> *(ebp+0xc) 6/r32/esi
# var curr/ecx: (addr byte) = s->data # var curr/ecx: (addr byte) = s->data
8d/copy-address *(esi+4) 1/r32/ecx 8d/copy-address *(esi+4) 1/r32/ecx
# var end/edx: (addr byte) = &s->data[s->length] # var end/edx: (addr byte) = &s->data[s->size]
# . edx = s->length # . edx = s->size
8b/-> *esi 2/r32/edx 8b/-> *esi 2/r32/edx
# . edx += curr # . edx += curr
01/add-to %edx 1/r32/ecx 01/add-to %edx 1/r32/ecx

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -108,12 +108,12 @@ compile: # in: (addr buffered-file), out: fd or (addr stream byte), err: fd or
# var num/ecx: (stream byte 7) # var num/ecx: (stream byte 7)
# Numbers can be 32 bits or 8 hex bytes long. One of them will be in 'Look', so we need space for 7 bytes. # Numbers can be 32 bits or 8 hex bytes long. One of them will be in 'Look', so we need space for 7 bytes.
# Sizing the stream just right buys us overflow-handling for free inside 'get-num'. # Sizing the stream just right buys us overflow-handling for free inside 'get-num'.
# Add 12 bytes for 'read', 'write' and 'length' fields, for a total of 19 bytes, or 0x13 in hex. # Add 12 bytes for 'read', 'write' and 'size' fields, for a total of 19 bytes, or 0x13 in hex.
# The stack pointer is no longer aligned, so dump_stack() can be misleading past this point. # The stack pointer is no longer aligned, so dump_stack() can be misleading past this point.
81 5/subop/subtract 3/mod/direct 4/rm32/esp . . . . . 0x13/imm32 # subtract from esp 81 5/subop/subtract 3/mod/direct 4/rm32/esp . . . . . 0x13/imm32 # subtract from esp
89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx 89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx
# initialize the stream # initialize the stream
# . num->length = 7 # . num->size = 7
c7 0/subop/copy 1/mod/*+disp8 1/rm32/ecx . . . . 8/disp8 7/imm32 # copy to *(ecx+8) c7 0/subop/copy 1/mod/*+disp8 1/rm32/ecx . . . . 8/disp8 7/imm32 # copy to *(ecx+8)
# . clear-stream(num) # . clear-stream(num)
# . . push args # . . push args
@ -194,7 +194,7 @@ $compile:end:
get-num: # in: (addr buffered-file), out: (addr stream byte), err: fd or (addr stream byte), ed: (addr exit-descriptor) get-num: # in: (addr buffered-file), out: (addr stream byte), err: fd or (addr stream byte), ed: (addr exit-descriptor)
# pseudocode: # pseudocode:
# if (!is-digit?(Look)) expected(ed, err, "integer") # if (!is-digit?(Look)) expected(ed, err, "integer")
# if out->write >= out->length # if out->write >= out->size
# write(err, "Error: too many digits in number\n") # write(err, "Error: too many digits in number\n")
# stop(ed, 1) # stop(ed, 1)
# out->data[out->write] = LSB(Look) # out->data[out->write] = LSB(Look)
@ -205,7 +205,7 @@ get-num: # in: (addr buffered-file), out: (addr stream byte), err: fd or (addr
# in: esi # in: esi
# out: edi # out: edi
# out->write: ecx (cached copy; need to keep in sync) # out->write: ecx (cached copy; need to keep in sync)
# out->length: edx # out->size: edx
# temporaries: eax, ebx # temporaries: eax, ebx
# We can't allocate Look to a register because it gets written implicitly in # We can't allocate Look to a register because it gets written implicitly in
# get-char in each iteration of the loop. (Thereby demonstrating that it's # get-char in each iteration of the loop. (Thereby demonstrating that it's
@ -250,10 +250,10 @@ $get-num:main:
8b/copy 1/mod/*+disp8 5/rm32/ebp . . . 7/r32/edi 0xc/disp8 . # copy *(ebp+12) to edi 8b/copy 1/mod/*+disp8 5/rm32/ebp . . . 7/r32/edi 0xc/disp8 . # copy *(ebp+12) to edi
# ecx = out->write # ecx = out->write
8b/copy 0/mod/indirect 7/rm32/edi . . . 1/r32/ecx . . # copy *edi to ecx 8b/copy 0/mod/indirect 7/rm32/edi . . . 1/r32/ecx . . # copy *edi to ecx
# edx = out->length # edx = out->size
8b/copy 1/mod/*+disp8 7/rm32/edi . . . 2/r32/edx 8/disp8 . # copy *(edi+8) to edx 8b/copy 1/mod/*+disp8 7/rm32/edi . . . 2/r32/edx 8/disp8 . # copy *(edi+8) to edx
$get-num:loop: $get-num:loop:
# if (out->write >= out->length) error # if (out->write >= out->size) error
39/compare 3/mod/direct 2/rm32/edx . . . 1/r32/ecx . . # compare edx with ecx 39/compare 3/mod/direct 2/rm32/edx . . . 1/r32/ecx . . # compare edx with ecx
7d/jump-if-< $get-num:stage2/disp8 7d/jump-if-< $get-num:stage2/disp8
# . error(ed, err, msg) # TODO: show full number # . error(ed, err, msg) # TODO: show full number

Binary file not shown.

View File

@ -108,12 +108,12 @@ compile: # in: (addr buffered-file), out: fd or (addr stream byte), err: fd or
# var num/ecx: (stream byte 7) # var num/ecx: (stream byte 7)
# Numbers can be 32 bits or 8 hex bytes long. One of them will be in 'Look', so we need space for 7 bytes. # Numbers can be 32 bits or 8 hex bytes long. One of them will be in 'Look', so we need space for 7 bytes.
# Sizing the stream just right buys us overflow-handling for free inside 'get-num'. # Sizing the stream just right buys us overflow-handling for free inside 'get-num'.
# Add 12 bytes for 'read', 'write' and 'length' fields, for a total of 19 bytes, or 0x13 in hex. # Add 12 bytes for 'read', 'write' and 'size' fields, for a total of 19 bytes, or 0x13 in hex.
# The stack pointer is no longer aligned, so dump_stack() can be misleading past this point. # The stack pointer is no longer aligned, so dump_stack() can be misleading past this point.
81 5/subop/subtract 3/mod/direct 4/rm32/esp . . . . . 0x13/imm32 # subtract from esp 81 5/subop/subtract 3/mod/direct 4/rm32/esp . . . . . 0x13/imm32 # subtract from esp
89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx 89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx
# initialize the stream # initialize the stream
# . num->length = 7 # . num->size = 7
c7 0/subop/copy 1/mod/*+disp8 1/rm32/ecx . . . . 8/disp8 7/imm32 # copy to *(ecx+8) c7 0/subop/copy 1/mod/*+disp8 1/rm32/ecx . . . . 8/disp8 7/imm32 # copy to *(ecx+8)
# . clear-stream(num) # . clear-stream(num)
# . . push args # . . push args
@ -195,7 +195,7 @@ get-num: # in: (addr buffered-file), out: (addr stream byte), err: fd or (addr
# pseudocode: # pseudocode:
# if (!is-digit?(Look)) expected(ed, err, "integer") # if (!is-digit?(Look)) expected(ed, err, "integer")
# do # do
# if out->write >= out->length # if out->write >= out->size
# write(err, "Error: too many digits in number\n") # write(err, "Error: too many digits in number\n")
# stop(ed, 1) # stop(ed, 1)
# out->data[out->write] = LSB(Look) # out->data[out->write] = LSB(Look)
@ -210,7 +210,7 @@ get-num: # in: (addr buffered-file), out: (addr stream byte), err: fd or (addr
# in: esi # in: esi
# out: edi # out: edi
# out->write: ecx (cached copy; need to keep in sync) # out->write: ecx (cached copy; need to keep in sync)
# out->length: edx # out->size: edx
# temporaries: eax, ebx # temporaries: eax, ebx
# We can't allocate Look to a register because it gets written implicitly in # We can't allocate Look to a register because it gets written implicitly in
# get-char in each iteration of the loop. (Thereby demonstrating that it's # get-char in each iteration of the loop. (Thereby demonstrating that it's
@ -255,10 +255,10 @@ $get-num:main:
8b/copy 1/mod/*+disp8 5/rm32/ebp . . . 7/r32/edi 0xc/disp8 . # copy *(ebp+12) to edi 8b/copy 1/mod/*+disp8 5/rm32/ebp . . . 7/r32/edi 0xc/disp8 . # copy *(ebp+12) to edi
# ecx = out->write # ecx = out->write
8b/copy 0/mod/indirect 7/rm32/edi . . . 1/r32/ecx . . # copy *edi to ecx 8b/copy 0/mod/indirect 7/rm32/edi . . . 1/r32/ecx . . # copy *edi to ecx
# edx = out->length # edx = out->size
8b/copy 1/mod/*+disp8 7/rm32/edi . . . 2/r32/edx 8/disp8 . # copy *(edi+8) to edx 8b/copy 1/mod/*+disp8 7/rm32/edi . . . 2/r32/edx 8/disp8 . # copy *(edi+8) to edx
$get-num:loop: $get-num:loop:
# if (out->write >= out->length) error # if (out->write >= out->size) error
39/compare 3/mod/direct 2/rm32/edx . . . 1/r32/ecx . . # compare edx with ecx 39/compare 3/mod/direct 2/rm32/edx . . . 1/r32/ecx . . # compare edx with ecx
7d/jump-if-< $get-num:loop-stage2/disp8 7d/jump-if-< $get-num:loop-stage2/disp8
# . error(ed, err, msg) # TODO: show full number # . error(ed, err, msg) # TODO: show full number

Binary file not shown.

View File

@ -1,9 +1,9 @@
# Null-terminated vs length-prefixed ascii strings. # Null-terminated vs size-prefixed ascii strings.
# #
# By default we create strings with a 4-byte length prefix rather than a null suffix. # By default we create strings with a 4-byte size prefix rather than a null suffix.
# However we still need null-prefixed strings when interacting with the Linux # However we still need null-prefixed strings when interacting with the Linux
# kernel in a few places. This layer implements a function for comparing # kernel in a few places. This layer implements a function for comparing
# a null-terminated 'kernel string' with a length-prefixed 'SubX string'. # a null-terminated 'kernel string' with a size-prefixed 'SubX string'.
# #
# To run: # To run:
# $ ./bootstrap translate init.linux apps/ex11.subx -o apps/ex11 # $ ./bootstrap translate init.linux apps/ex11.subx -o apps/ex11
@ -25,11 +25,11 @@ Entry: # run all tests
89/copy 3/mod/direct 3/rm32/ebx . . . 0/r32/eax . . # copy eax to ebx 89/copy 3/mod/direct 3/rm32/ebx . . . 0/r32/eax . . # copy eax to ebx
e8/call syscall_exit/disp32 e8/call syscall_exit/disp32
# compare a null-terminated ascii string with a more idiomatic length-prefixed byte array # compare a null-terminated ascii string with a more idiomatic size-prefixed byte array
# reason for the name: the only place we should have null-terminated ascii strings is from commandline args # reason for the name: the only place we should have null-terminated ascii strings is from commandline args
kernel-string-equal?: # s: null-terminated ascii string, benchmark: length-prefixed ascii string -> eax: boolean kernel-string-equal?: # s: null-terminated ascii string, benchmark: size-prefixed ascii string -> eax: boolean
# pseudocode: # pseudocode:
# n = benchmark->length # n = benchmark->size
# s1 = s # s1 = s
# s2 = benchmark->data # s2 = benchmark->data
# i = 0 # i = 0
@ -60,7 +60,7 @@ kernel-string-equal?: # s: null-terminated ascii string, benchmark: length-pref
57/push-edi 57/push-edi
# s1/edi = s # s1/edi = s
8b/copy 1/mod/*+disp8 5/rm32/ebp . . . 7/r32/edi 8/disp8 . # copy *(ebp+8) to edi 8b/copy 1/mod/*+disp8 5/rm32/ebp . . . 7/r32/edi 8/disp8 . # copy *(ebp+8) to edi
# n/edx = benchmark->length # n/edx = benchmark->size
8b/copy 1/mod/*+disp8 5/rm32/ebp . . . 2/r32/edx 0xc/disp8 . # copy *(ebp+12) to edx 8b/copy 1/mod/*+disp8 5/rm32/ebp . . . 2/r32/edx 0xc/disp8 . # copy *(ebp+12) to edx
8b/copy 0/mod/indirect 2/rm32/edx . . . 2/r32/edx . . # copy *edx to edx 8b/copy 0/mod/indirect 2/rm32/edx . . . 2/r32/edx . . # copy *edx to edx
# s2/esi = benchmark->data # s2/esi = benchmark->data

Binary file not shown.

Binary file not shown.

BIN
apps/hex

Binary file not shown.

BIN
apps/mu

Binary file not shown.

View File

@ -380,7 +380,7 @@ Max-type-id:
Type-id: # (stream (address array byte)) Type-id: # (stream (address array byte))
0x1c/imm32/write 0x1c/imm32/write
0/imm32/read 0/imm32/read
0x100/imm32/length 0x100/imm32/size
# data # data
"literal"/imm32 # 0 "literal"/imm32 # 0
"int"/imm32 # 1 "int"/imm32 # 1
@ -2478,7 +2478,7 @@ test-convert-index-into-array-with-literal:
(check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-index-into-array-with-literal/5") (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-index-into-array-with-literal/5")
(check-next-stream-line-equal _test-output-stream " ff 6/subop/push %eax" "F - test-convert-index-into-array-with-literal/6") (check-next-stream-line-equal _test-output-stream " ff 6/subop/push %eax" "F - test-convert-index-into-array-with-literal/6")
(check-next-stream-line-equal _test-output-stream " b8/copy-to-eax 0/imm32" "F - test-convert-index-into-array-with-literal/7") (check-next-stream-line-equal _test-output-stream " b8/copy-to-eax 0/imm32" "F - test-convert-index-into-array-with-literal/7")
# 2 * 4 bytes/elem + 4 bytes for length = offset 12 # 2 * 4 bytes/elem + 4 bytes for size = offset 12
(check-next-stream-line-equal _test-output-stream " 8d/copy-address *(eax + 0x0000000c) 0x00000000/r32" "F - test-convert-index-into-array-with-literal/8") (check-next-stream-line-equal _test-output-stream " 8d/copy-address *(eax + 0x0000000c) 0x00000000/r32" "F - test-convert-index-into-array-with-literal/8")
(check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %eax" "F - test-convert-index-into-array-with-literal/9") (check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %eax" "F - test-convert-index-into-array-with-literal/9")
(check-next-stream-line-equal _test-output-stream " }" "F - test-convert-index-into-array-with-literal/10") (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-index-into-array-with-literal/10")
@ -3163,7 +3163,7 @@ parse-mu: # in: (addr buffered-file)
57/push-edi 57/push-edi
# var line/ecx: (stream byte 512) # var line/ecx: (stream byte 512)
81 5/subop/subtract %esp 0x200/imm32 81 5/subop/subtract %esp 0x200/imm32
68/push 0x200/imm32/length 68/push 0x200/imm32/size
68/push 0/imm32/read 68/push 0/imm32/read
68/push 0/imm32/write 68/push 0/imm32/write
89/<- %ecx 4/r32/esp 89/<- %ecx 4/r32/esp
@ -3177,7 +3177,7 @@ parse-mu: # in: (addr buffered-file)
be/copy-to-esi _Program-types/imm32 be/copy-to-esi _Program-types/imm32
# var vars/ebx: (stack (addr var) 256) # var vars/ebx: (stack (addr var) 256)
81 5/subop/subtract %esp 0x400/imm32 81 5/subop/subtract %esp 0x400/imm32
68/push 0x400/imm32/length 68/push 0x400/imm32/size
68/push 0/imm32/top 68/push 0/imm32/top
89/<- %ebx 4/r32/esp 89/<- %ebx 4/r32/esp
{ {
@ -3486,7 +3486,7 @@ test-function-header-with-arg:
(zero-out %ecx *Function-size) (zero-out %ecx *Function-size)
# var vars/ebx: (stack (addr var) 16) # var vars/ebx: (stack (addr var) 16)
81 5/subop/subtract %esp 0x10/imm32 81 5/subop/subtract %esp 0x10/imm32
68/push 0x10/imm32/length 68/push 0x10/imm32/size
68/push 0/imm32/top 68/push 0/imm32/top
89/<- %ebx 4/r32/esp 89/<- %ebx 4/r32/esp
# convert # convert
@ -3519,7 +3519,7 @@ test-function-header-with-multiple-args:
(zero-out %ecx *Function-size) (zero-out %ecx *Function-size)
# var vars/ebx: (stack (addr var) 16) # var vars/ebx: (stack (addr var) 16)
81 5/subop/subtract %esp 0x10/imm32 81 5/subop/subtract %esp 0x10/imm32
68/push 0x10/imm32/length 68/push 0x10/imm32/size
68/push 0/imm32/top 68/push 0/imm32/top
89/<- %ebx 4/r32/esp 89/<- %ebx 4/r32/esp
# convert # convert
@ -3571,7 +3571,7 @@ test-function-with-multiple-args-and-outputs:
(zero-out %ecx *Function-size) (zero-out %ecx *Function-size)
# var vars/ebx: (stack (addr var) 16) # var vars/ebx: (stack (addr var) 16)
81 5/subop/subtract %esp 0x10/imm32 81 5/subop/subtract %esp 0x10/imm32
68/push 0x10/imm32/length 68/push 0x10/imm32/size
68/push 0/imm32/top 68/push 0/imm32/top
89/<- %ebx 4/r32/esp 89/<- %ebx 4/r32/esp
# convert # convert
@ -4666,7 +4666,7 @@ parse-mu-block: # in: (addr buffered-file), vars: (addr stack (handle var)), fn
57/push-edi 57/push-edi
# var line/ecx: (stream byte 512) # var line/ecx: (stream byte 512)
81 5/subop/subtract %esp 0x200/imm32 81 5/subop/subtract %esp 0x200/imm32
68/push 0x200/imm32/length 68/push 0x200/imm32/size
68/push 0/imm32/read 68/push 0/imm32/read
68/push 0/imm32/write 68/push 0/imm32/write
89/<- %ecx 4/r32/esp 89/<- %ecx 4/r32/esp
@ -4809,7 +4809,7 @@ new-block-name: # fn: (handle function) -> result/eax: (handle var)
# var n/ecx: int = len(fn->name) + 10 for an int + 2 for '$:' # var n/ecx: int = len(fn->name) + 10 for an int + 2 for '$:'
8b/-> *(ebp+8) 0/r32/eax 8b/-> *(ebp+8) 0/r32/eax
8b/-> *eax 0/r32/eax # Function-name 8b/-> *eax 0/r32/eax # Function-name
8b/-> *eax 0/r32/eax # String-length 8b/-> *eax 0/r32/eax # String-size
05/add-to-eax 0xd/imm32 # 10 + 2 for '$:' 05/add-to-eax 0xd/imm32 # 10 + 2 for '$:'
89/<- %ecx 0/r32/eax 89/<- %ecx 0/r32/eax
# var name/edx: (stream byte n) # var name/edx: (stream byte n)
@ -5019,7 +5019,7 @@ test-parse-mu-var-def:
(write _test-input-stream "n: int\n") # caller has consumed the 'var' (write _test-input-stream "n: int\n") # caller has consumed the 'var'
# var vars/ecx: (stack (addr var) 4) # var vars/ecx: (stack (addr var) 4)
81 5/subop/subtract %esp 0x10/imm32 81 5/subop/subtract %esp 0x10/imm32
68/push 0x10/imm32/length 68/push 0x10/imm32/size
68/push 0/imm32/top 68/push 0/imm32/top
89/<- %ecx 4/r32/esp 89/<- %ecx 4/r32/esp
(clear-stack %ecx) (clear-stack %ecx)
@ -5049,7 +5049,7 @@ test-parse-mu-reg-var-def:
(write _test-input-stream "n/eax: int <- copy 0\n") # caller has consumed the 'var' (write _test-input-stream "n/eax: int <- copy 0\n") # caller has consumed the 'var'
# var vars/ecx: (stack (addr var) 4) # var vars/ecx: (stack (addr var) 4)
81 5/subop/subtract %esp 0x10/imm32 81 5/subop/subtract %esp 0x10/imm32
68/push 0x10/imm32/length 68/push 0x10/imm32/size
68/push 0/imm32/top 68/push 0/imm32/top
89/<- %ecx 4/r32/esp 89/<- %ecx 4/r32/esp
(clear-stack %ecx) (clear-stack %ecx)
@ -5428,7 +5428,7 @@ lookup-var-helper: # name: (addr array byte), vars: (addr stack (handle var)) -
8b/-> *(ebp+0xc) 6/r32/esi 8b/-> *(ebp+0xc) 6/r32/esi
# ebx = vars->top # ebx = vars->top
8b/-> *esi 3/r32/ebx 8b/-> *esi 3/r32/ebx
# if (vars->top > vars->length) abort # if (vars->top > vars->size) abort
3b/compare<- *(esi+4) 0/r32/eax 3b/compare<- *(esi+4) 0/r32/eax
0f 8f/jump-if-> $lookup-var-helper:error1/disp32 0f 8f/jump-if-> $lookup-var-helper:error1/disp32
# var min/edx: (addr handle var) = vars->data # var min/edx: (addr handle var) = vars->data
@ -5548,7 +5548,7 @@ test-parse-mu-stmt:
(write _test-input-stream "increment n\n") (write _test-input-stream "increment n\n")
# var vars/ecx: (stack (addr var) 4) # var vars/ecx: (stack (addr var) 4)
81 5/subop/subtract %esp 0x10/imm32 81 5/subop/subtract %esp 0x10/imm32
68/push 0x10/imm32/length 68/push 0x10/imm32/size
68/push 0/imm32/top 68/push 0/imm32/top
89/<- %ecx 4/r32/esp 89/<- %ecx 4/r32/esp
(clear-stack %ecx) (clear-stack %ecx)
@ -5584,7 +5584,7 @@ test-parse-mu-stmt-with-comma:
(write _test-input-stream "copy-to n, 3\n") (write _test-input-stream "copy-to n, 3\n")
# var vars/ecx: (stack (addr var) 4) # var vars/ecx: (stack (addr var) 4)
81 5/subop/subtract %esp 0x10/imm32 81 5/subop/subtract %esp 0x10/imm32
68/push 0x10/imm32/length 68/push 0x10/imm32/size
68/push 0/imm32/top 68/push 0/imm32/top
89/<- %ecx 4/r32/esp 89/<- %ecx 4/r32/esp
(clear-stack %ecx) (clear-stack %ecx)
@ -6141,7 +6141,7 @@ populate-mu-type: # in: (addr stream byte), t: (handle typeinfo)
8b/-> *(ebp+0xc) 7/r32/edi 8b/-> *(ebp+0xc) 7/r32/edi
# var line/ecx: (stream byte 512) # var line/ecx: (stream byte 512)
81 5/subop/subtract %esp 0x200/imm32 81 5/subop/subtract %esp 0x200/imm32
68/push 0x200/imm32/length 68/push 0x200/imm32/size
68/push 0/imm32/read 68/push 0/imm32/read
68/push 0/imm32/write 68/push 0/imm32/write
89/<- %ecx 4/r32/esp 89/<- %ecx 4/r32/esp
@ -6685,7 +6685,7 @@ size-of-array: # a: (handle tree type-id) -> result/eax: int
# return array-size * size-of(elem-type) # return array-size * size-of(elem-type)
(size-of-type-id %edx) # => eax (size-of-type-id %edx) # => eax
f7 4/subop/multiply-into-eax %ecx f7 4/subop/multiply-into-eax %ecx
05/add-to-eax 4/imm32 # for array length 05/add-to-eax 4/imm32 # for array size
$size-of-array:end: $size-of-array:end:
# . restore registers # . restore registers
5a/pop-to-edx 5a/pop-to-edx
@ -6822,7 +6822,7 @@ emit-subx-function: # out: (addr buffered-file), f: (handle function)
8b/-> *(ebp+0xc) 1/r32/ecx 8b/-> *(ebp+0xc) 1/r32/ecx
# var vars/edx: (stack (addr var) 256) # var vars/edx: (stack (addr var) 256)
81 5/subop/subtract %esp 0x400/imm32 81 5/subop/subtract %esp 0x400/imm32
68/push 0x400/imm32/length 68/push 0x400/imm32/size
68/push 0/imm32/top 68/push 0/imm32/top
89/<- %edx 4/r32/esp 89/<- %edx 4/r32/esp
# #
@ -7223,7 +7223,7 @@ Reverse-branch: # (table string string)
# a table is a stream # a table is a stream
0xa0/imm32/write 0xa0/imm32/write
0/imm32/read 0/imm32/read
0xa0/imm32/length 0xa0/imm32/size
# data # data
"break-if-="/imm32 "0f 85/jump-if-!="/imm32 "break-if-="/imm32 "0f 85/jump-if-!="/imm32
"loop-if-="/imm32 "0f 85/jump-if-!="/imm32 "loop-if-="/imm32 "0f 85/jump-if-!="/imm32
@ -7689,7 +7689,7 @@ emit-subx-var-def: # out: (addr buffered-file), stmt: (handle stmt)
(is-mu-array? *(ecx+4)) # Var-type => eax (is-mu-array? *(ecx+4)) # Var-type => eax
3d/compare-eax-and 0/imm32/false 3d/compare-eax-and 0/imm32/false
0f 84/jump-if-= break/disp32 0f 84/jump-if-= break/disp32
# var array-size-without-length/edx: int = n-4 # var array-size-without-size/edx: int = n-4
81 5/subop/subtract %edx 4/imm32 81 5/subop/subtract %edx 4/imm32
(emit-indent *(ebp+8) *Curr-block-depth) (emit-indent *(ebp+8) *Curr-block-depth)
(write-buffered *(ebp+8) "(push-n-zero-bytes ") (write-buffered *(ebp+8) "(push-n-zero-bytes ")
@ -7732,7 +7732,7 @@ emit-subx-stmt: # out: (addr buffered-file), stmt: (handle stmt), primitives: (
# - some special-case primitives that don't actually use the 'primitives' data structure # - some special-case primitives that don't actually use the 'primitives' data structure
# ecx = stmt # ecx = stmt
8b/-> *(ebp+0xc) 1/r32/ecx 8b/-> *(ebp+0xc) 1/r32/ecx
# array length # array size
{ {
# if (!string-equal?(stmt->operation, "length")) break # if (!string-equal?(stmt->operation, "length")) break
(string-equal? *(ecx+4) "length") # Stmt1-operation => eax (string-equal? *(ecx+4) "length") # Stmt1-operation => eax

BIN
apps/pack

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -133,14 +133,14 @@ subx-survey: # infile: (addr buffered-file), out: (addr buffered-file)
56/push-esi 56/push-esi
# var segments/ecx: (stream {string, segment-info} 160) # 10 rows * 16 bytes/row # var segments/ecx: (stream {string, segment-info} 160) # 10 rows * 16 bytes/row
81 5/subop/subtract 3/mod/direct 4/rm32/esp . . . . . 0xa0/imm32 # subtract from esp 81 5/subop/subtract 3/mod/direct 4/rm32/esp . . . . . 0xa0/imm32 # subtract from esp
68/push 0xa0/imm32/length 68/push 0xa0/imm32/size
68/push 0/imm32/read 68/push 0/imm32/read
68/push 0/imm32/write 68/push 0/imm32/write
89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx 89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx
# var labels/edx: (stream label-info Max-labels*16) # var labels/edx: (stream label-info Max-labels*16)
# . data # . data
2b/subtract 0/mod/indirect 5/rm32/.disp32 . . 4/r32/esp Max-labels/disp32 # subtract *Max-labels from esp 2b/subtract 0/mod/indirect 5/rm32/.disp32 . . 4/r32/esp Max-labels/disp32 # subtract *Max-labels from esp
# . length # . size
ff 6/subop/push 0/mod/indirect 5/rm32/.disp32 . . . Max-labels/disp32 # push *Max-labels ff 6/subop/push 0/mod/indirect 5/rm32/.disp32 . . . Max-labels/disp32 # push *Max-labels
# . read # . read
68/push 0/imm32/read 68/push 0/imm32/read
@ -150,7 +150,7 @@ subx-survey: # infile: (addr buffered-file), out: (addr buffered-file)
# var in/esi: (stream byte Input-size) # var in/esi: (stream byte Input-size)
# . data # . data
2b/subtract 0/mod/indirect 5/rm32/.disp32 . . 4/r32/esp Input-size/disp32 # subtract *Input-size from esp 2b/subtract 0/mod/indirect 5/rm32/.disp32 . . 4/r32/esp Input-size/disp32 # subtract *Input-size from esp
# . length # . size
ff 6/subop/push 0/mod/indirect 5/rm32/.disp32 . . . Input-size/disp32 # push *Input-size ff 6/subop/push 0/mod/indirect 5/rm32/.disp32 . . . Input-size/disp32 # push *Input-size
# . read # . read
68/push 0/imm32/read 68/push 0/imm32/read
@ -690,7 +690,7 @@ compute-offsets: # in: (addr stream byte), segments: (addr stream {string, segm
c7 0/subop/copy 0/mod/indirect 5/rm32/.disp32 . . . compute-offsets:segment-offset/disp32 0/imm32 # copy to *compute-offsets:word-slice c7 0/subop/copy 0/mod/indirect 5/rm32/.disp32 . . . compute-offsets:segment-offset/disp32 0/imm32 # copy to *compute-offsets:word-slice
# var line/ecx: (stream byte 512) # var line/ecx: (stream byte 512)
81 5/subop/subtract 3/mod/direct 4/rm32/esp . . . . . 0x200/imm32 # subtract from esp 81 5/subop/subtract 3/mod/direct 4/rm32/esp . . . . . 0x200/imm32 # subtract from esp
68/push 0x200/imm32/length 68/push 0x200/imm32/size
68/push 0/imm32/read 68/push 0/imm32/read
68/push 0/imm32/write 68/push 0/imm32/write
89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx 89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx
@ -1222,13 +1222,13 @@ test-compute-offsets:
81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp
# var segments/ecx: (stream byte 2*16) # var segments/ecx: (stream byte 2*16)
81 5/subop/subtract 3/mod/direct 4/rm32/esp . . . . . 0x20/imm32 # subtract from esp 81 5/subop/subtract 3/mod/direct 4/rm32/esp . . . . . 0x20/imm32 # subtract from esp
68/push 0x20/imm32/length 68/push 0x20/imm32/size
68/push 0/imm32/read 68/push 0/imm32/read
68/push 0/imm32/write 68/push 0/imm32/write
89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx 89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx
# var labels/edx: (stream byte 2*16) # var labels/edx: (stream byte 2*16)
81 5/subop/subtract 3/mod/direct 4/rm32/esp . . . . . 0x20/imm32 # subtract from esp 81 5/subop/subtract 3/mod/direct 4/rm32/esp . . . . . 0x20/imm32 # subtract from esp
68/push 0x20/imm32/length 68/push 0x20/imm32/size
68/push 0/imm32/read 68/push 0/imm32/read
68/push 0/imm32/write 68/push 0/imm32/write
89/copy 3/mod/direct 2/rm32/edx . . . 4/r32/esp . . # copy esp to edx 89/copy 3/mod/direct 2/rm32/edx . . . 4/r32/esp . . # copy esp to edx
@ -1624,13 +1624,13 @@ test-compute-addresses:
# setup # setup
# . var segments/ecx: (stream byte 10*16) # . var segments/ecx: (stream byte 10*16)
81 5/subop/subtract 3/mod/direct 4/rm32/esp . . . . . 0xa0/imm32 # subtract from esp 81 5/subop/subtract 3/mod/direct 4/rm32/esp . . . . . 0xa0/imm32 # subtract from esp
68/push 0xa0/imm32/length 68/push 0xa0/imm32/size
68/push 0/imm32/read 68/push 0/imm32/read
68/push 0/imm32/write 68/push 0/imm32/write
89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx 89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx
# . var labels/edx: (stream byte 512*16) # . var labels/edx: (stream byte 512*16)
81 5/subop/subtract 3/mod/direct 4/rm32/esp . . . . . 0x2000/imm32 # subtract from esp 81 5/subop/subtract 3/mod/direct 4/rm32/esp . . . . . 0x2000/imm32 # subtract from esp
68/push 0x2000/imm32/length 68/push 0x2000/imm32/size
68/push 0/imm32/read 68/push 0/imm32/read
68/push 0/imm32/write 68/push 0/imm32/write
89/copy 3/mod/direct 2/rm32/edx . . . 4/r32/esp . . # copy esp to edx 89/copy 3/mod/direct 2/rm32/edx . . . 4/r32/esp . . # copy esp to edx
@ -1793,13 +1793,13 @@ test-compute-addresses-large-segments:
# setup # setup
# . var segments/ecx: (stream byte 10*16) # . var segments/ecx: (stream byte 10*16)
81 5/subop/subtract 3/mod/direct 4/rm32/esp . . . . . 0xa0/imm32 # subtract from esp 81 5/subop/subtract 3/mod/direct 4/rm32/esp . . . . . 0xa0/imm32 # subtract from esp
68/push 0xa0/imm32/length 68/push 0xa0/imm32/size
68/push 0/imm32/read 68/push 0/imm32/read
68/push 0/imm32/write 68/push 0/imm32/write
89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx 89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx
# . var labels/edx: (stream byte 512*16) # . var labels/edx: (stream byte 512*16)
81 5/subop/subtract 3/mod/direct 4/rm32/esp . . . . . 0x2000/imm32 # subtract from esp 81 5/subop/subtract 3/mod/direct 4/rm32/esp . . . . . 0x2000/imm32 # subtract from esp
68/push 0x2000/imm32/length 68/push 0x2000/imm32/size
68/push 0/imm32/read 68/push 0/imm32/read
68/push 0/imm32/write 68/push 0/imm32/write
89/copy 3/mod/direct 2/rm32/edx . . . 4/r32/esp . . # copy esp to edx 89/copy 3/mod/direct 2/rm32/edx . . . 4/r32/esp . . # copy esp to edx
@ -1989,7 +1989,7 @@ emit-segments: # in: (addr stream byte), out: (addr buffered-file), labels: (ad
57/push-edi 57/push-edi
# var line/ecx: (stream byte 512) # var line/ecx: (stream byte 512)
81 5/subop/subtract 3/mod/direct 4/rm32/esp . . . . . 0x200/imm32 # subtract from esp 81 5/subop/subtract 3/mod/direct 4/rm32/esp . . . . . 0x200/imm32 # subtract from esp
68/push 0x200/imm32/length 68/push 0x200/imm32/size
68/push 0/imm32/read 68/push 0/imm32/read
68/push 0/imm32/write 68/push 0/imm32/write
89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx 89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx
@ -2156,8 +2156,8 @@ $emit-segments:check-for-segment-header:
3d/compare-eax-and 0/imm32/false 3d/compare-eax-and 0/imm32/false
0f 85/jump-if-!= $emit-segments:line-loop/disp32 0f 85/jump-if-!= $emit-segments:line-loop/disp32
$emit-segments:2-character: $emit-segments:2-character:
# if (length(word-slice) != 2) goto next check # if (size(word-slice) != 2) goto next check
# . eax = length(word-slice) # . eax = size(word-slice)
8b/copy 1/mod/*+disp8 2/rm32/edx . . . 0/r32/eax 4/disp8 . # copy *(edx+4) to eax 8b/copy 1/mod/*+disp8 2/rm32/edx . . . 0/r32/eax 4/disp8 . # copy *(edx+4) to eax
2b/subtract 0/mod/indirect 2/rm32/edx . . . 0/r32/eax . . # subtract *edx from eax 2b/subtract 0/mod/indirect 2/rm32/edx . . . 0/r32/eax . . # subtract *edx from eax
# . if (eax != 2) goto next check # . if (eax != 2) goto next check
@ -2579,7 +2579,7 @@ test-emit-segments-global-variable:
81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp
# . var labels/edx: (stream byte 512*16) # . var labels/edx: (stream byte 512*16)
81 5/subop/subtract 3/mod/direct 4/rm32/esp . . . . . 0x2000/imm32 # subtract from esp 81 5/subop/subtract 3/mod/direct 4/rm32/esp . . . . . 0x2000/imm32 # subtract from esp
68/push 0x2000/imm32/length 68/push 0x2000/imm32/size
68/push 0/imm32/read 68/push 0/imm32/read
68/push 0/imm32/write 68/push 0/imm32/write
89/copy 3/mod/direct 2/rm32/edx . . . 4/r32/esp . . # copy esp to edx 89/copy 3/mod/direct 2/rm32/edx . . . 4/r32/esp . . # copy esp to edx
@ -2789,7 +2789,7 @@ test-emit-segments-code-label:
81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp
# . var labels/edx: (stream byte 512*16) # . var labels/edx: (stream byte 512*16)
81 5/subop/subtract 3/mod/direct 4/rm32/esp . . . . . 0x2000/imm32 # subtract from esp 81 5/subop/subtract 3/mod/direct 4/rm32/esp . . . . . 0x2000/imm32 # subtract from esp
68/push 0x2000/imm32/length 68/push 0x2000/imm32/size
68/push 0/imm32/read 68/push 0/imm32/read
68/push 0/imm32/write 68/push 0/imm32/write
89/copy 3/mod/direct 2/rm32/edx . . . 4/r32/esp . . # copy esp to edx 89/copy 3/mod/direct 2/rm32/edx . . . 4/r32/esp . . # copy esp to edx
@ -2974,7 +2974,7 @@ test-emit-segments-code-label-absolute:
81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp
# . var labels/edx: (stream byte 512*16) # . var labels/edx: (stream byte 512*16)
81 5/subop/subtract 3/mod/direct 4/rm32/esp . . . . . 0x2000/imm32 # subtract from esp 81 5/subop/subtract 3/mod/direct 4/rm32/esp . . . . . 0x2000/imm32 # subtract from esp
68/push 0x2000/imm32/length 68/push 0x2000/imm32/size
68/push 0/imm32/read 68/push 0/imm32/read
68/push 0/imm32/write 68/push 0/imm32/write
89/copy 3/mod/direct 2/rm32/edx . . . 4/r32/esp . . # copy esp to edx 89/copy 3/mod/direct 2/rm32/edx . . . 4/r32/esp . . # copy esp to edx
@ -3423,8 +3423,8 @@ stream-add4: # in: (addr stream byte), key: addr, val1: addr, val2: addr, val3:
8b/copy 0/mod/indirect 6/rm32/esi . . . 0/r32/eax . . # copy *esi to eax 8b/copy 0/mod/indirect 6/rm32/esi . . . 0/r32/eax . . # copy *esi to eax
# . eax = esi+eax+12 # . eax = esi+eax+12
8d/copy-address 1/mod/*+disp8 4/rm32/sib 6/base/esi 0/index/eax . 0/r32/eax 0xc/disp8 . # copy esi+eax+12 to eax 8d/copy-address 1/mod/*+disp8 4/rm32/sib 6/base/esi 0/index/eax . 0/r32/eax 0xc/disp8 . # copy esi+eax+12 to eax
# max/edx = &in->data[in->length] # max/edx = &in->data[in->size]
# . edx = in->length # . edx = in->size
8b/copy 1/mod/*+disp8 6/rm32/esi . . . 2/r32/edx 8/disp8 . # copy *(esi+8) to edx 8b/copy 1/mod/*+disp8 6/rm32/esi . . . 2/r32/edx 8/disp8 . # copy *(esi+8) to edx
# . edx = esi+edx+12 # . edx = esi+edx+12
8d/copy-address 1/mod/*+disp8 4/rm32/sib 6/base/esi 2/index/edx . 2/r32/edx 0xc/disp8 . # copy esi+edx+12 to edx 8d/copy-address 1/mod/*+disp8 4/rm32/sib 6/base/esi 2/index/edx . 2/r32/edx 0xc/disp8 . # copy esi+edx+12 to edx
@ -4609,7 +4609,7 @@ test-num-bytes-handles-imm32:
# some fields (the ones with labels capitalized) filled in. # some fields (the ones with labels capitalized) filled in.
# http://www.sco.com/developers/gabi/latest/ch4.eheader.html # http://www.sco.com/developers/gabi/latest/ch4.eheader.html
Elf_header: Elf_header:
# - length # - size
0x34/imm32 0x34/imm32
# - data # - data
$e_ident: $e_ident:
@ -4647,7 +4647,7 @@ $e_shstrndx:
# Some fields need filling in each time. # Some fields need filling in each time.
# https://docs.oracle.com/cd/E19683-01/816-1386/chapter6-83432/index.html # https://docs.oracle.com/cd/E19683-01/816-1386/chapter6-83432/index.html
Elf_program_header_entry: Elf_program_header_entry:
# - length # - size
0x20/imm32 0x20/imm32
# - data # - data
$p_type: $p_type:

Binary file not shown.