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:
parent
f730f2f2c7
commit
bfcc0f858a
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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:
|
||||||
|
|
22
060read.subx
22
060read.subx
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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:
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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:
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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
|
||||||
|
|
BIN
apps/assort
BIN
apps/assort
Binary file not shown.
BIN
apps/braces
BIN
apps/braces
Binary file not shown.
BIN
apps/calls
BIN
apps/calls
Binary file not shown.
BIN
apps/crenshaw2-1
BIN
apps/crenshaw2-1
Binary file not shown.
|
@ -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.
|
@ -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
|
||||||
|
|
BIN
apps/dquotes
BIN
apps/dquotes
Binary file not shown.
|
@ -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
|
||||||
|
|
BIN
apps/factorial
BIN
apps/factorial
Binary file not shown.
BIN
apps/handle
BIN
apps/handle
Binary file not shown.
40
apps/mu.subx
40
apps/mu.subx
|
@ -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/sigils
BIN
apps/sigils
Binary file not shown.
BIN
apps/survey
BIN
apps/survey
Binary file not shown.
|
@ -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:
|
||||||
|
|
BIN
apps/tests
BIN
apps/tests
Binary file not shown.
Loading…
Reference in New Issue