5804
Try to make the comments consistent with the type system we'll eventually have.
This commit is contained in:
parent
a93cd189c9
commit
2a2a5b1e43
|
@ -11,6 +11,26 @@ Entry: # just exit; can't test _write just yet
|
|||
b8/copy-to-eax 1/imm32/exit
|
||||
cd/syscall 0x80/imm8
|
||||
|
||||
# Since this is the first file of SubX code, a note about type comments.
|
||||
# Eventually we'll build a slightly higher-level safe language atop SubX.
|
||||
# Even though we don't have the safe language yet, we'll start thinking in
|
||||
# terms of the higher-level types in comments.
|
||||
#
|
||||
# Mu will have two kinds of addresses:
|
||||
# - 'ref' which is used to point to a unique element, because machine
|
||||
# code can't store large types in registers.
|
||||
# - 'handle' which can point to a heap allocation, different heap allocations
|
||||
# at different times, or even at times nothing at all.
|
||||
#
|
||||
# The type 'address' can be obtained from either a ref or handle, but it can
|
||||
# only be stored on the stack (say to pass objects by reference).
|
||||
# Conversely, a ref can't be copied into another ref, only to an address (which
|
||||
# by construction has a shorter lifetime).
|
||||
#
|
||||
# Beginnings of a lattice of types:
|
||||
# You can convert a ref or handle to an address, but not the other way around.
|
||||
# You can convert addresses to ints, but not the other way around.
|
||||
|
||||
_write: # fd : int, s : (address array byte)
|
||||
# . prologue
|
||||
55/push-ebp
|
||||
|
|
14
051test.subx
14
051test.subx
|
@ -80,26 +80,26 @@ $check-ints-equal:end:
|
|||
|
||||
# length-prefixed string containing just a single newline
|
||||
# convenient to have when printing messages and so on
|
||||
Newline:
|
||||
# size
|
||||
Newline: # (ref array byte)
|
||||
# size : int
|
||||
1/imm32
|
||||
# data
|
||||
0a/newline
|
||||
|
||||
# every test failure increments this counter
|
||||
Num-test-failures:
|
||||
Num-test-failures: # int
|
||||
0/imm32
|
||||
|
||||
# length-prefixed string containing just a single space
|
||||
Space:
|
||||
# size
|
||||
Space: # (ref array byte)
|
||||
# size : int
|
||||
1/imm32
|
||||
# data
|
||||
20/space
|
||||
|
||||
# length-prefixed string containing just a single slash
|
||||
Slash:
|
||||
# size
|
||||
Slash: # (ref array byte)
|
||||
# size : int
|
||||
1/imm32
|
||||
# data
|
||||
2f/slash
|
||||
|
|
|
@ -1,9 +1,11 @@
|
|||
# Checking null-terminated ascii strings.
|
||||
#
|
||||
# By default we create strings with a 4-byte length prefix rather than a null suffix.
|
||||
# However we still need null-prefixed strings when interacting with the Linux
|
||||
# kernel in a few places. This layer implements a function for comparing
|
||||
# a null-terminated 'kernel string' with a length-prefixed 'SubX string'.
|
||||
# By default we create strings as arrays of bytes, and all arrays have a 4-byte
|
||||
# length prefix.
|
||||
#
|
||||
# However, we sometimes need to deal with null-prefixed strings when interacting
|
||||
# with the Linux kernel. This layer implements a function for comparing a
|
||||
# null-terminated 'kernel string' with a length-prefixed 'SubX string'.
|
||||
#
|
||||
# To run (from the subx directory):
|
||||
# $ ./subx translate 05[0-2]*.subx -o /tmp/tmp52
|
||||
|
@ -28,7 +30,7 @@ Entry: # run all tests
|
|||
|
||||
# compare a null-terminated ascii string with a more idiomatic length-prefixed byte array
|
||||
# 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 : (address kernel-string), benchmark : (address array byte) -> eax : boolean
|
||||
# pseudocode:
|
||||
# n = benchmark->length
|
||||
# s1 = s
|
||||
|
@ -59,17 +61,19 @@ kernel-string-equal?: # s : null-terminated ascii string, benchmark : length-pr
|
|||
53/push-ebx
|
||||
56/push-esi
|
||||
57/push-edi
|
||||
# s1/edi = s
|
||||
# var s1/edi : (address byte) = s
|
||||
8b/copy 1/mod/*+disp8 5/rm32/ebp . . . 7/r32/edi 8/disp8 . # copy *(ebp+8) to edi
|
||||
# n/edx = benchmark->length
|
||||
# var n/edx : int = benchmark->length
|
||||
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
|
||||
# s2/esi = benchmark->data
|
||||
# var s2/esi : (address byte) = benchmark->data
|
||||
8b/copy 1/mod/*+disp8 5/rm32/ebp . . . 6/r32/esi 0xc/disp8 . # copy *(ebp+12) to esi
|
||||
81 0/subop/add 3/mod/direct 6/rm32/esi . . . . . 4/imm32 # add to esi
|
||||
# i/ecx = c1/eax = c2/ebx = 0
|
||||
# var i/ecx : int = 0
|
||||
b9/copy-to-ecx 0/imm32/exit
|
||||
# var c1/eax : byte = 0
|
||||
b8/copy-to-eax 0/imm32
|
||||
# var c2/ebx : byte = 0
|
||||
bb/copy-to-ebx 0/imm32
|
||||
$kernel-string-equal?:loop:
|
||||
# if (i >= n) break
|
||||
|
@ -258,10 +262,10 @@ test-compare-kernel-string-with-longer-array:
|
|||
|
||||
== data
|
||||
|
||||
Null-kernel-string:
|
||||
Null-kernel-string: # (address kernel-string)
|
||||
00/null
|
||||
|
||||
_test-Abc-kernel-string:
|
||||
_test-Abc-kernel-string: # (address kernel-string)
|
||||
41/A 62/b 63/c 00/null
|
||||
|
||||
# . . vim:nowrap:textwidth=0
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
# . 1-3 bytes 3 bits 2 bits 3 bits 3 bits 3 bits 2 bits 2 bits 0/1/2/4 bytes 0/1/2/4 bytes
|
||||
|
||||
Entry: # manual test
|
||||
# var ad/ecx : (address allocation-descriptor) = {0, 0}
|
||||
# var ad/ecx : (ref allocation-descriptor)
|
||||
68/push 0/imm32/limit
|
||||
68/push 0/imm32/curr
|
||||
89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx
|
||||
|
@ -29,7 +29,7 @@ Entry: # manual test
|
|||
e8/call new-segment/disp32
|
||||
# . . discard args
|
||||
81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp
|
||||
# eax = ad->curr
|
||||
# var eax : (address _) = ad->curr
|
||||
8b/copy 0/mod/indirect 1/rm32/ecx . . . 0/r32/eax . . # copy *ecx to eax
|
||||
# write to *eax to check that we have access to the newly-allocated segment
|
||||
c7 0/subop/copy 0/mod/direct 0/rm32/eax . . . . . 0x34/imm32 # copy to *eax
|
||||
|
@ -38,7 +38,7 @@ Entry: # manual test
|
|||
b8/copy-to-eax 1/imm32/exit
|
||||
cd/syscall 0x80/imm8
|
||||
|
||||
new-segment: # len : int, ad : (address allocation-descriptor)
|
||||
new-segment: # len : int, ad : (ref allocation-descriptor)
|
||||
# . prologue
|
||||
55/push-ebp
|
||||
89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp
|
||||
|
@ -72,7 +72,7 @@ $new-segment:end:
|
|||
== data
|
||||
|
||||
# various constants used here were found in the Linux sources (search for file mman-common.h)
|
||||
_mmap-new-segment: # type mmap_arg_struct
|
||||
_mmap-new-segment: # (ref mmap_arg_struct)
|
||||
# addr
|
||||
0/imm32
|
||||
$_mmap-new-segment:len:
|
||||
|
|
|
@ -13,12 +13,12 @@ Entry: # run all tests
|
|||
b8/copy-to-eax 1/imm32/exit
|
||||
cd/syscall 0x80/imm8
|
||||
|
||||
string-equal?: # s : (address string), benchmark : (address string) -> eax : boolean
|
||||
string-equal?: # s : (address array byte), benchmark : (address array byte) -> eax : boolean
|
||||
# pseudocode:
|
||||
# if (s->length != benchmark->length) return false
|
||||
# currs = s->data
|
||||
# currb = benchmark->data
|
||||
# maxs = s->data + s->length
|
||||
# maxs = &s->data[s->length]
|
||||
# while currs < maxs
|
||||
# c1 = *currs
|
||||
# c2 = *currb
|
||||
|
@ -51,14 +51,15 @@ $string-equal?:lengths:
|
|||
# if (ecx != benchmark->length) return false
|
||||
39/compare 0/mod/indirect 7/rm32/edi . . . 1/r32/ecx . . # compare *edi and ecx
|
||||
75/jump-if-not-equal $string-equal?:false/disp8
|
||||
# currs/esi = s->data
|
||||
# var currs/esi : (address byte) = s->data
|
||||
81 0/subop/add 3/mod/direct 6/rm32/esi . . . . . 4/imm32 # add to esi
|
||||
# maxs/ecx = s->data + s->length
|
||||
# var maxs/ecx : (address byte) = &s->data[s->length]
|
||||
01/add 3/mod/direct 1/rm32/ecx . . . 6/r32/esi . . # add esi to ecx
|
||||
# currb/edi = benchmark->data
|
||||
# var currb/edi : (address byte) = benchmark->data
|
||||
81 0/subop/add 3/mod/direct 7/rm32/edi . . . . . 4/imm32 # add to edi
|
||||
# c1/eax = c2/edx = 0
|
||||
# var c1/eax : byte = 0
|
||||
31/xor 3/mod/direct 0/rm32/eax . . . 0/r32/eax . . # clear eax
|
||||
# var c2/edx : byte = 0
|
||||
31/xor 3/mod/direct 2/rm32/edx . . . 2/r32/edx . . # clear edx
|
||||
$string-equal?:loop:
|
||||
# if (currs >= maxs) return true
|
||||
|
@ -175,13 +176,13 @@ test-compare-inequal-strings-equal-lengths:
|
|||
c3/return
|
||||
|
||||
# helper for later tests
|
||||
check-strings-equal: # s : (address string), expected : (address string), msg : (address string)
|
||||
check-strings-equal: # s : (address array byte), expected : (address array byte), msg : (address array byte)
|
||||
# . prologue
|
||||
55/push-ebp
|
||||
89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp
|
||||
# . save registers
|
||||
50/push-eax
|
||||
# eax = string-equal?(s, expected)
|
||||
# var eax : boolean = string-equal?(s, expected)
|
||||
# . . push args
|
||||
ff 6/subop/push 1/mod/*+disp8 5/rm32/ebp . . . . 0xc/disp8 . # push *(ebp+12)
|
||||
ff 6/subop/push 1/mod/*+disp8 5/rm32/ebp . . . . 8/disp8 . # push *(ebp+8)
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
# A stream looks like this:
|
||||
# write : int # index at which writes go
|
||||
# read : int # index that we've read until
|
||||
# data : (array byte) # prefixed by length as usual
|
||||
# data : (ref array byte) # prefixed by length as usual
|
||||
#
|
||||
# some primitives for operating on streams:
|
||||
# - clear-stream (clears everything but the data length)
|
||||
|
@ -14,7 +14,7 @@
|
|||
# . 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
|
||||
|
||||
clear-stream: # f : (address stream)
|
||||
clear-stream: # f : (address stream byte)
|
||||
# . prologue
|
||||
55/push-ebp
|
||||
89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp
|
||||
|
@ -23,23 +23,23 @@ clear-stream: # f : (address stream)
|
|||
51/push-ecx
|
||||
# eax = f
|
||||
8b/copy 1/mod/*+disp8 5/rm32/ebp . . 0/r32/eax 8/disp8 . # copy *(ebp+8) to eax
|
||||
# ecx = f->length
|
||||
# var count/ecx : int = f->length
|
||||
8b/copy 1/mod/*+disp8 0/rm32/eax . . . 1/r32/ecx 8/disp8 . # copy *(eax+8) to ecx
|
||||
# ecx = &f->data[f->length]
|
||||
# var max/ecx : (address byte) = &f->data[f->length]
|
||||
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
|
||||
c7 0/subop/copy 0/mod/direct 0/rm32/eax . . . . . 0/imm32 # copy to *eax
|
||||
# f->read = 0
|
||||
c7 0/subop/copy 1/mod/*+disp8 0/rm32/eax . . . . 4/disp8 0/imm32 # copy to *(eax+4)
|
||||
# eax = f->data
|
||||
# var curr/eax : (address byte) = f->data
|
||||
81 0/subop/add 3/mod/direct 0/rm32/eax . . . . . 0xc/imm32 # add to eax
|
||||
$clear-stream:loop:
|
||||
# if (eax >= ecx) break
|
||||
# if (curr >= max) break
|
||||
39/compare 3/mod/direct 0/rm32/eax . . . 1/r32/ecx . . # compare eax with ecx
|
||||
73/jump-if-greater-or-equal-unsigned $clear-stream:end/disp8
|
||||
# *eax = 0
|
||||
# *curr = 0
|
||||
c6 0/subop/copy-byte 0/mod/direct 0/rm32/eax . . . . . 0/imm8 # copy byte to *eax
|
||||
# ++eax
|
||||
# ++curr
|
||||
40/increment-eax
|
||||
eb/jump $clear-stream:loop/disp8
|
||||
$clear-stream:end:
|
||||
|
@ -51,7 +51,7 @@ $clear-stream:end:
|
|||
5d/pop-to-ebp
|
||||
c3/return
|
||||
|
||||
rewind-stream: # f : (address stream)
|
||||
rewind-stream: # f : (address stream byte)
|
||||
# . prologue
|
||||
55/push-ebp
|
||||
89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp
|
||||
|
|
|
@ -14,9 +14,9 @@
|
|||
|
||||
== data
|
||||
|
||||
# We'll save the address of the trace segment here.
|
||||
Trace-stream:
|
||||
Trace-stream: # (handle stream byte)
|
||||
0/imm32
|
||||
# we don't have safe handles (fat pointers) yet
|
||||
|
||||
Trace-segment:
|
||||
0/imm32/curr
|
||||
|
@ -24,7 +24,7 @@ Trace-segment:
|
|||
|
||||
# Fake trace-stream for tests.
|
||||
# Also illustrates the layout of the real trace-stream (segment).
|
||||
_test-trace-stream:
|
||||
_test-trace-stream: # (ref stream byte)
|
||||
# current write index
|
||||
0/imm32
|
||||
# current read index
|
||||
|
@ -60,7 +60,7 @@ initialize-trace-stream: # n : int
|
|||
81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp
|
||||
# copy Trace-segment->curr to *Trace-stream
|
||||
8b/copy 0/mod/indirect 5/rm32/.disp32 . . 0/r32/eax Trace-segment/disp32 # copy *Trace-segment to eax
|
||||
# watch point to catch Trace-stream leaks
|
||||
#? # watch point to catch Trace-stream leaks
|
||||
#? $watch-1:
|
||||
89/copy 0/mod/indirect 5/rm32/.disp32 . . 0/r32/eax Trace-stream/disp32 # copy eax to *Trace-stream
|
||||
# Trace-stream->length = n - 12
|
||||
|
@ -79,7 +79,7 @@ $initialize-trace-stream:end:
|
|||
|
||||
# Append a string to the given trace stream.
|
||||
# Silently give up if it's already full. Or truncate the string if there isn't enough room.
|
||||
trace: # line : (address string)
|
||||
trace: # line : (address array byte)
|
||||
# . prologue
|
||||
55/push-ebp
|
||||
89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp
|
||||
|
@ -90,13 +90,13 @@ trace: # line : (address string)
|
|||
53/push-ebx
|
||||
56/push-esi
|
||||
57/push-edi
|
||||
# edi = *Trace-stream
|
||||
# var edi : (address stream byte) = *Trace-stream
|
||||
8b/copy 0/mod/indirect 5/rm32/.disp32 . . 7/r32/edi Trace-stream/disp32 # copy *Trace-stream to edi
|
||||
# esi = line
|
||||
8b/copy 1/mod/*+disp8 5/rm32/ebp . . 6/r32/esi 8/disp8 . # copy *(ebp+8) to esi
|
||||
# ecx = t->write
|
||||
# var ecx : int = t->write
|
||||
8b/copy 0/mod/indirect 7/rm32/edi . . . 1/r32/ecx . . # copy *edi to ecx
|
||||
# edx = t->length
|
||||
# var edx : int = t->length
|
||||
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)
|
||||
# . . push line
|
||||
|
@ -302,7 +302,7 @@ $check-trace-scans-to:end:
|
|||
c3/return
|
||||
|
||||
# Start scanning from Trace-stream->read for 'line'. If found, update Trace-stream->read and return true.
|
||||
trace-scan: # line : (address string) -> result/eax : boolean
|
||||
trace-scan: # line : (address array byte) -> result/eax : boolean
|
||||
# pseudocode:
|
||||
# push Trace-stream->read
|
||||
# while true:
|
||||
|
@ -340,8 +340,8 @@ $trace-scan:loop:
|
|||
e8/call next-line-matches?/disp32
|
||||
# . . discard args
|
||||
81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp
|
||||
# if (eax == 0) continue
|
||||
3d/compare-eax-and 0/imm32
|
||||
# if (eax == false) continue
|
||||
3d/compare-eax-and 0/imm32/false
|
||||
74/jump-if-equal $trace-scan:continue/disp8
|
||||
$trace-scan:true:
|
||||
# skip-next-line(Trace-stream)
|
||||
|
@ -554,7 +554,7 @@ test-trace-scan-failure-leaves-read-index-untouched:
|
|||
# . end
|
||||
c3/return
|
||||
|
||||
next-line-matches?: # t : (address stream), line : (address string) -> result/eax : boolean
|
||||
next-line-matches?: # t : (address stream byte), line : (address array byte) -> result/eax : boolean
|
||||
# pseudocode:
|
||||
# while true:
|
||||
# if (currl >= maxl) break
|
||||
|
@ -575,58 +575,58 @@ next-line-matches?: # t : (address stream), line : (address string) -> result/e
|
|||
57/push-edi
|
||||
# edx = line
|
||||
8b/copy 1/mod/*+disp8 5/rm32/ebp . . 2/r32/edx 0xc/disp8 . # copy *(ebp+12) to edx
|
||||
# currl/esi = line->data
|
||||
# var currl/esi : (address byte) = line->data
|
||||
# . esi = line/edx->data
|
||||
8d/copy-address 1/mod/*+disp8 2/rm32/edx . . . 6/r32/esi 4/disp8 . # copy edx+4 to esi
|
||||
# maxl/ecx = line->data + line->size
|
||||
# var maxl/ecx : (address byte) = &line->data[line->size]
|
||||
# . eax = line/edx->size
|
||||
8b/copy 0/mod/indirect 2/rm32/edx . . 0/r32/eax . . # copy *edx to eax
|
||||
# . maxl/ecx = line->data/esi + line->size/eax
|
||||
# . maxl = &line->data[line->size]
|
||||
8d/copy-address 0/mod/indirect 4/rm32/sib 6/base/esi 0/index/eax . 1/r32/ecx . . # copy edx+eax to ecx
|
||||
# edi = t
|
||||
8b/copy 1/mod/*+disp8 5/rm32/ebp . . 7/r32/edi 8/disp8 . # copy *(ebp+8) to edi
|
||||
# ebx = t->data
|
||||
# var ebx : (address byte) = t->data
|
||||
8d/copy-address 1/mod/*+disp8 7/rm32/edi . . . 3/r32/ebx 0xc/disp8 . # copy edi+12 to ebx
|
||||
# maxt/edx = t->data + t->write
|
||||
# var maxt/edx : (address byte) = &t->data[t->write]
|
||||
# . eax = t->write
|
||||
8b/copy 0/mod/indirect 7/rm32/edi . . 0/r32/eax . . # copy *edi to eax
|
||||
# . maxt/edx = t->data/ebx + t->write/eax
|
||||
# . maxt = &t->data[t->write]
|
||||
8d/copy-address 0/mod/indirect 4/rm32/sib 3/base/ebx 0/index/eax . 2/r32/edx . . # copy ebx+eax to edx
|
||||
# currt/edi = t->data + t->read
|
||||
# var currt/edi : (address byte) = &t->data[t->read]
|
||||
# . eax = t/edi->read
|
||||
8b/copy 1/mod/*+disp8 7/rm32/edi . . 0/r32/eax 4/disp8 . # copy *(edi+4) to eax
|
||||
# . currt/edi = t->data/ebx + t->read/eax
|
||||
# . currt = &t->data[t->read]
|
||||
8d/copy-address 0/mod/indirect 4/rm32/sib 3/base/ebx 0/index/eax . 7/r32/edi . . # copy ebx+eax to edi
|
||||
$next-line-matches?:loop:
|
||||
# if (currl/esi >= maxl/ecx) break
|
||||
# if (currl >= maxl) break
|
||||
39/compare 3/mod/direct 6/rm32/esi . . . 1/r32/ecx . . # compare esi and ecx
|
||||
73/jump-if-greater-or-equal-unsigned $next-line-matches?:break/disp8
|
||||
# if (currt/edi >= maxt/edx) return false
|
||||
# if (currt >= maxt) return false
|
||||
# . eax = false
|
||||
b8/copy-to-eax 0/imm32/false
|
||||
39/compare 3/mod/direct 7/rm32/edi . . . 2/r32/edx . . # compare edi and edx
|
||||
73/jump-if-greater-or-equal-unsigned $next-line-matches?:end/disp8
|
||||
# if (*currt/edi != *currl/esi) return false
|
||||
# if (*currt != *currl) return false
|
||||
31/xor 3/mod/direct 0/rm32/eax . . . 0/r32/eax . . # clear eax
|
||||
31/xor 3/mod/direct 3/rm32/eax . . . 3/r32/eax . . # clear ebx
|
||||
# . eax = (char) *currt/edi
|
||||
# . eax : byte = *currt
|
||||
8a/copy-byte 0/mod/indirect 7/rm32/edi . . 0/r32/eax . . # copy *edi to eax
|
||||
# . ebx = (char) *currl/esi
|
||||
# . ebx : byte = *currl
|
||||
8a/copy-byte 0/mod/indirect 6/rm32/esi . . 3/r32/ebx . . # copy *esi to ebx
|
||||
# . eax >= ebx
|
||||
39/compare 3/mod/direct 0/rm32/eax . . . 3/r32/ebx . . # compare eax and ebx
|
||||
# . eax = false
|
||||
b8/copy-to-eax 0/imm32/false
|
||||
75/jump-if-not-equal $next-line-matches?:end/disp8
|
||||
# ++currt/edi
|
||||
# ++currt
|
||||
47/increment-edi
|
||||
# ++currl/esi
|
||||
# ++currl
|
||||
46/increment-esi
|
||||
eb/jump $next-line-matches?:loop/disp8
|
||||
$next-line-matches?:break:
|
||||
# return *currt == '\n'
|
||||
31/xor 3/mod/direct 0/rm32/eax . . . 0/r32/eax . . # clear eax
|
||||
# . eax = (char) *currt
|
||||
# . eax : byte = *currt
|
||||
8a/copy-byte 0/mod/indirect 7/rm32/edi . . 0/r32/eax . . # copy *edi to eax
|
||||
3d/compare-eax-and 0xa/imm32/newline
|
||||
# . eax = false
|
||||
|
@ -730,11 +730,11 @@ test-next-line-matches?-match:
|
|||
c3/return
|
||||
|
||||
# move t->read to _after_ next newline
|
||||
skip-next-line: # t : (address stream)
|
||||
skip-next-line: # t : (address stream byte)
|
||||
# pseudocode:
|
||||
# max = t->data + t->write
|
||||
# max = &t->data[t->write]
|
||||
# i = t->read
|
||||
# curr = t->data + t->read
|
||||
# curr = &t->data[t->read]
|
||||
# while true
|
||||
# if (curr >= max) break
|
||||
# ++i
|
||||
|
@ -752,37 +752,37 @@ skip-next-line: # t : (address stream)
|
|||
53/push-ebx
|
||||
# ecx = t
|
||||
8b/copy 1/mod/*+disp8 5/rm32/ebp . . 1/r32/ecx 8/disp8 . # copy *(ebp+8) to ecx
|
||||
# edx = t/ecx->data
|
||||
# edx = t->data
|
||||
8d/copy-address 1/mod/*+disp8 1/rm32/ecx . . . 2/r32/edx 0xc/disp8 . # copy ecx+12 to edx
|
||||
# eax = t/ecx->write
|
||||
# eax = t->write
|
||||
8b/copy 0/mod/indirect 1/rm32/ecx . . . 0/r32/eax . . # copy *ecx to eax
|
||||
# max/ebx = t->data/edx + t->write/eax
|
||||
# var max/ebx : (address byte) = &t->data[t->write]
|
||||
8d/copy-address 0/mod/indirect 4/rm32/sib 2/base/edx 0/index/eax . 3/r32/ebx . . # copy edx+eax to ebx
|
||||
# eax = t/ecx->read
|
||||
# eax = t->read
|
||||
8b/copy 1/mod/*+disp8 1/rm32/ecx . . . 0/r32/eax 4/disp8 . # copy *(ecx+4) to edx
|
||||
# curr/ecx = t->data/edx + t->read/eax
|
||||
# var curr/ecx : (address byte) = &t->data[t->read]
|
||||
8d/copy-address 0/mod/indirect 4/rm32/sib 2/base/edx 0/index/eax . 1/r32/ecx . . # copy edx+eax to ecx
|
||||
# i/edx = eax
|
||||
# var i/edx : int = t->read
|
||||
89/copy 3/mod/direct 2/rm32/edx . . . 0/r32/eax . . # copy eax to edx
|
||||
$skip-next-line:loop:
|
||||
# if (curr/ecx >= max/ebx) break
|
||||
# if (curr >= max) break
|
||||
39/compare 3/mod/direct 1/rm32/ecx . . . 3/r32/ebx . . # compare ecx and ebx
|
||||
73/jump-if-greater-or-equal-unsigned $skip-next-line:end/disp8
|
||||
# ++i/edx
|
||||
# ++i
|
||||
42/increment-edx
|
||||
# if (*curr/ecx == '\n') break
|
||||
# if (*curr == '\n') break
|
||||
31/xor 3/mod/direct 0/rm32/eax . . . 0/r32/eax . . # clear eax
|
||||
8a/copy-byte 0/mod/indirect 1/rm32/ecx . . . 0/r32/eax . . # copy *ecx to eax
|
||||
3d/compare-eax-and 0a/imm32/newline
|
||||
74/jump-if-equal $skip-next-line:end/disp8
|
||||
# ++curr/ecx
|
||||
# ++curr
|
||||
41/increment-ecx
|
||||
# loop
|
||||
eb/jump $skip-next-line:loop/disp8
|
||||
$skip-next-line:end:
|
||||
# ecx = t
|
||||
8b/copy 1/mod/*+disp8 5/rm32/ebp . . 1/r32/ecx 8/disp8 . # copy *(ebp+8) to ecx
|
||||
# t/ecx->read = i/edx
|
||||
# t->read = i
|
||||
89/copy 1/mod/*+disp8 1/rm32/ecx . . . 2/r32/edx 4/disp8 . # copy edx to *(ecx+4)
|
||||
# . restore registers
|
||||
5b/pop-to-ebx
|
||||
|
@ -858,7 +858,7 @@ $clear-trace-stream:end:
|
|||
# - helpers
|
||||
|
||||
# 3-argument variant of _append
|
||||
_append-3: # out : address, outend : address, s : (array byte) -> num_bytes_appended/eax
|
||||
_append-3: # out : (address byte), outend : (address byte), s : (address array byte) -> num_bytes_appended/eax
|
||||
# . prologue
|
||||
55/push-ebp
|
||||
89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp
|
||||
|
@ -890,7 +890,7 @@ $_append-3:end:
|
|||
c3/return
|
||||
|
||||
# 4-argument variant of _append
|
||||
_append-4: # out : address, outend : address, in : address, inend : address -> num_bytes_appended/eax
|
||||
_append-4: # out : (address byte), outend : (address byte), in : (address byte), inend : (address byte) -> num_bytes_appended/eax : int
|
||||
# . prologue
|
||||
55/push-ebp
|
||||
89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp
|
||||
|
@ -900,7 +900,7 @@ _append-4: # out : address, outend : address, in : address, inend : address ->
|
|||
53/push-ebx
|
||||
56/push-esi
|
||||
57/push-edi
|
||||
# eax/num_bytes_appended = 0
|
||||
# num_bytes_appended = 0
|
||||
b8/copy-to-eax 0/imm32
|
||||
# edi = out
|
||||
8b/copy 1/mod/*+disp8 5/rm32/ebp . . . 7/r32/edi 8/disp8 . # copy *(ebp+8) to edi
|
||||
|
@ -956,7 +956,7 @@ $_append-4:abort:
|
|||
|
||||
== data
|
||||
|
||||
_test-stream-line-ABABA:
|
||||
_test-stream-line-ABABA: # (ref stream byte)
|
||||
# write
|
||||
8/imm32
|
||||
# read
|
||||
|
@ -966,7 +966,7 @@ _test-stream-line-ABABA:
|
|||
# data
|
||||
41 42 41 42 41 0a 00 00 # 8 bytes
|
||||
|
||||
_test-stream-empty:
|
||||
_test-stream-empty: # (ref stream byte)
|
||||
# write
|
||||
0/imm32
|
||||
# read
|
||||
|
@ -976,7 +976,7 @@ _test-stream-empty:
|
|||
# data
|
||||
00 00 00 00 00 00 00 00 # 8 bytes
|
||||
|
||||
_test-stream-filled:
|
||||
_test-stream-filled: # (ref stream byte)
|
||||
# write
|
||||
8/imm32
|
||||
# read
|
||||
|
|
|
@ -21,7 +21,7 @@
|
|||
# . 1-3 bytes 3 bits 2 bits 3 bits 3 bits 3 bits 2 bits 2 bits 0/1/2/4 bytes 0/1/2/4 bytes
|
||||
|
||||
# TODO: come up with a way to signal when a write to disk fails
|
||||
write: # f : fd or (address stream), s : (address array byte)
|
||||
write: # f : fd or (address stream byte), s : (address array byte)
|
||||
# . prologue
|
||||
55/push-ebp
|
||||
89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp
|
||||
|
@ -145,7 +145,7 @@ test-write-appends:
|
|||
|
||||
== data
|
||||
|
||||
_test-stream:
|
||||
_test-stream: # (ref stream byte)
|
||||
# current write index
|
||||
0/imm32
|
||||
# current read index
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
# . 1-3 bytes 3 bits 2 bits 3 bits 3 bits 3 bits 2 bits 2 bits 0/1/2/4 bytes 0/1/2/4 bytes
|
||||
|
||||
# compare all the data in a stream (ignoring the read pointer)
|
||||
stream-data-equal?: # f : (address stream), s : (address string) -> eax : boolean
|
||||
stream-data-equal?: # f : (address stream byte), s : (address array byte) -> eax : boolean
|
||||
# . prologue
|
||||
55/push-ebp
|
||||
89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp
|
||||
|
@ -19,20 +19,21 @@ stream-data-equal?: # f : (address stream), s : (address string) -> eax : boole
|
|||
8b/copy 1/mod/*+disp8 5/rm32/ebp . . . 6/r32/esi 8/disp8 . # copy *(ebp+8) to esi
|
||||
# eax = f->write
|
||||
8b/copy 0/mod/indirect 6/rm32/esi . . . 0/r32/eax . . # copy *esi to eax
|
||||
# maxf/edx = f->data + f->write
|
||||
# var maxf/edx : (address byte) = &f->data[f->write]
|
||||
8d/copy-address 1/mod/*+disp8 4/rm32/sib 6/base/esi 0/index/eax . 2/r32/edx 0xc/disp8 . # copy esi+eax+12 to edx
|
||||
# currf/esi = f->data
|
||||
# var currf/esi : (address byte) = f->data
|
||||
81 0/subop/add 3/mod/direct 6/rm32/esi . . . . . 0xc/imm32 # add to esi
|
||||
# edi = s
|
||||
8b/copy 1/mod/*+disp8 5/rm32/ebp . . . 7/r32/edi 0xc/disp8 . # copy *(ebp+12) to edi
|
||||
# if (f->write != s->length) return false
|
||||
$stream-data-equal?:compare-lengths:
|
||||
# if (f->write != s->length) return false
|
||||
39/compare 0/mod/indirect 7/rm32/edi . . . 0/r32/eax . . # compare *edi and eax
|
||||
75/jump-if-not-equal $stream-data-equal?:false/disp8
|
||||
# currs/edi = s->data
|
||||
# var currs/edi : (address byte) = s->data
|
||||
81 0/subop/add 3/mod/direct 7/rm32/edi . . . . . 4/imm32 # add to edi
|
||||
# eax = ecx = 0
|
||||
# var eax : byte = 0
|
||||
31/xor 3/mod/direct 0/rm32/eax . . . 0/r32/eax . . # clear eax
|
||||
# var ecx : byte = 0
|
||||
31/xor 3/mod/direct 1/rm32/ecx . . . 1/r32/ecx . . # clear ecx
|
||||
$stream-data-equal?:loop:
|
||||
# if (currf >= maxf) return true
|
||||
|
@ -190,7 +191,7 @@ test-stream-data-equal-length-check:
|
|||
c3/return
|
||||
|
||||
# helper for later tests
|
||||
check-stream-equal: # f : (address stream), s : (address string), msg : (address string)
|
||||
check-stream-equal: # f : (address stream byte), s : (address array byte), msg : (address array byte)
|
||||
# . prologue
|
||||
55/push-ebp
|
||||
89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp
|
||||
|
@ -226,7 +227,7 @@ $check-stream-equal:end:
|
|||
# on success, set f->read to after the next newline
|
||||
# on failure, leave f->read unmodified
|
||||
# this function is usually used only in tests, so we repeatedly write f->read
|
||||
next-stream-line-equal?: # f : (address stream), s : (address string) -> eax : boolean
|
||||
next-stream-line-equal?: # f : (address stream byte), s : (address array byte) -> eax : boolean
|
||||
# pseudocode:
|
||||
# currf = f->read # bound: f->write
|
||||
# currs = 0 # bound : s->length
|
||||
|
@ -273,30 +274,31 @@ next-stream-line-equal?: # f : (address stream), s : (address string) -> eax :
|
|||
57/push-edi
|
||||
# esi = f
|
||||
8b/copy 1/mod/*+disp8 5/rm32/ebp . . . 6/r32/esi 8/disp8 . # copy *(ebp+8) to esi
|
||||
# currf/ecx = f->read
|
||||
# var currf/ecx : int = f->read
|
||||
8b/copy 1/mod/*+disp8 6/rm32/esi . . . 1/r32/ecx 4/disp8 . # copy *(esi+4) to ecx
|
||||
# edi = s
|
||||
8b/copy 1/mod/*+disp8 5/rm32/ebp . . . 7/r32/edi 0xc/disp8 . # copy *(ebp+12) to edi
|
||||
# currs/edx = 0
|
||||
# var currs/edx : int = 0
|
||||
31/xor 3/mod/direct 2/rm32/edx . . . 2/r32/edx . . # clear edx
|
||||
# eax = ebx = 0
|
||||
# var c1/eax : byte = 0
|
||||
31/xor 3/mod/direct 0/rm32/eax . . . 0/r32/eax . . # clear eax
|
||||
# var c2/ebx : byte = 0
|
||||
31/xor 3/mod/direct 3/rm32/ebx . . . 3/r32/ebx . . # clear ebx
|
||||
$next-stream-line-equal?:loop:
|
||||
# if (currf >= f->write) break
|
||||
3b/compare 0/mod/indirect 6/rm32/esi . . . 1/r32/ecx . . # compare ecx with *esi
|
||||
7d/jump-if-greater-or-equal $next-stream-line-equal?:break/disp8
|
||||
# AL = *(f->data + f->read)
|
||||
# c1 = f->data[f->read]
|
||||
8a/copy-byte 1/mod/*+disp8 4/rm32/sib 6/base/esi 1/index/ecx . 0/r32/AL 0xc/disp8 . # copy byte at *(esi+ecx+12) to AL
|
||||
# if (eax == '\n') break
|
||||
# if (c1 == '\n') break
|
||||
3d/compare-eax-and 0xa/imm32/newline
|
||||
74/jump-if-equal $next-stream-line-equal?:break/disp8
|
||||
# if (currs >= s->length) return false
|
||||
3b/compare 0/mod/indirect 7/rm32/edi . . . 2/r32/edx . . # compare edx with *edi
|
||||
7d/jump-if-greater-or-equal $next-stream-line-equal?:false/disp8
|
||||
# BL = *(s->data + currs)
|
||||
# c2 = s->data[currs]
|
||||
8a/copy-byte 1/mod/*+disp8 4/rm32/sib 7/base/edi 2/index/edx . 3/r32/BL 4/disp8 . # copy byte at *(edi+edx+4) to BL
|
||||
# if (eax != ebx) return false
|
||||
# if (c1 != c2) return false
|
||||
39/compare 3/mod/direct 0/rm32/eax . . . 3/r32/ebx . . # compare eax and ebx
|
||||
75/jump-if-not-equal $next-stream-line-equal?:false/disp8
|
||||
# ++currf
|
||||
|
|
|
@ -123,7 +123,7 @@ test-stop-skips-returns-on-exit:
|
|||
# Make room for an exit descriptor on the stack. That's almost always the
|
||||
# right place for it, available only as long as it's legal to use. Once this
|
||||
# containing function returns we'll need a new exit descriptor.
|
||||
# var ed/eax : (address exit-descriptor)
|
||||
# var ed/eax : (ref exit-descriptor)
|
||||
68/push 0/imm32
|
||||
68/push 0/imm32
|
||||
89/copy 3/mod/direct 0/rm32/eax . . . 4/r32/esp . . # copy esp to eax
|
||||
|
|
|
@ -45,7 +45,7 @@
|
|||
# . 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
|
||||
|
||||
read: # f : fd or (address stream), s : (address stream) -> num-bytes-read/eax
|
||||
read: # f : fd or (address stream byte), s : (address stream byte) -> num-bytes-read/eax : int
|
||||
# . prologue
|
||||
55/push-ebp
|
||||
89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp
|
||||
|
@ -191,12 +191,11 @@ $_buffer-4:end:
|
|||
5d/pop-to-ebp
|
||||
c3/return
|
||||
|
||||
|
||||
# idea: a clear-if-empty method on streams that clears only if f->read == f->write
|
||||
# Unclear how I'd use it, though. Callers seem to need the check anyway.
|
||||
# Maybe a better helper would be 'empty-stream?'
|
||||
|
||||
_read: # fd : int, s : (address stream) -> num-bytes-read/eax
|
||||
_read: # fd : int, s : (address stream byte) -> num-bytes-read/eax : int
|
||||
# . prologue
|
||||
55/push-ebp
|
||||
89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp
|
||||
|
@ -427,7 +426,7 @@ test-read-returns-0-on-end-of-file:
|
|||
|
||||
== data
|
||||
|
||||
_test-tmp-stream:
|
||||
_test-tmp-stream: # (ref stream byte)
|
||||
# current write index
|
||||
0/imm32
|
||||
# current read index
|
||||
|
|
|
@ -11,8 +11,8 @@
|
|||
|
||||
# The buffered file for standard input. Also illustrates the layout for
|
||||
# buffered-file: a pointer to the backing store, followed by a 'buffer' stream
|
||||
Stdin:
|
||||
# file descriptor or (address stream)
|
||||
Stdin: # (ref buffered-file)
|
||||
# file descriptor or (address stream byte)
|
||||
0/imm32 # standard input
|
||||
$Stdin->buffer:
|
||||
# inlined fields for a stream
|
||||
|
@ -73,8 +73,7 @@ read-byte-buffered: # f : (address buffered-file) -> byte-or-Eof/eax
|
|||
b8/copy-to-eax 0xffffffff/imm32/Eof
|
||||
eb/jump $read-byte-buffered:end/disp8
|
||||
$read-byte-buffered:from-stream:
|
||||
# read byte from stream
|
||||
# AL = f->data[f->read]
|
||||
# byte-or-Eof = f->data[f->read]
|
||||
31/xor 3/mod/direct 0/rm32/eax . . . 0/r32/eax . . # clear eax
|
||||
8a/copy-byte 1/mod/*+disp8 4/rm32/sib 6/base/esi 1/index/ecx . 0/r32/AL 0x10/disp8 . # copy byte at *(esi+ecx+16) to AL
|
||||
# ++f->read
|
||||
|
@ -272,8 +271,8 @@ test-read-byte-buffered-refills-buffer:
|
|||
== data
|
||||
|
||||
# a test buffered file for _test-stream
|
||||
_test-buffered-file:
|
||||
# file descriptor or (address stream)
|
||||
_test-buffered-file: # (ref buffered-file)
|
||||
# file descriptor or (address stream byte)
|
||||
_test-stream/imm32
|
||||
$_test-buffered-file->buffer:
|
||||
# current write index
|
||||
|
@ -285,7 +284,7 @@ $_test-buffered-file->buffer:
|
|||
# data
|
||||
00 00 00 00 00 00 # 6 bytes
|
||||
|
||||
_test-input-stream:
|
||||
_test-input-stream: # (ref stream byte)
|
||||
# current write index
|
||||
0/imm32
|
||||
# current read index
|
||||
|
@ -311,8 +310,8 @@ _test-input-stream:
|
|||
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
|
||||
|
||||
# a test buffered file for _test-input-stream
|
||||
_test-input-buffered-file:
|
||||
# file descriptor or (address stream)
|
||||
_test-input-buffered-file: # (ref buffered-file)
|
||||
# file descriptor or (address stream byte)
|
||||
_test-input-stream/imm32
|
||||
$_test-input-buffered-file->buffer:
|
||||
# current write index
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
#? b8/copy-to-eax 1/imm32/exit
|
||||
#? cd/syscall 0x80/imm8
|
||||
|
||||
write-stream: # f : fd or (address stream), s : (address stream)
|
||||
write-stream: # f : fd or (address stream byte), s : (address stream byte)
|
||||
# . prologue
|
||||
55/push-ebp
|
||||
89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp
|
||||
|
@ -75,7 +75,7 @@ $write-stream:end:
|
|||
5d/pop-to-ebp
|
||||
c3/return
|
||||
|
||||
_write-stream: # fd : int, s : (address stream)
|
||||
_write-stream: # fd : int, s : (address stream byte)
|
||||
# . prologue
|
||||
55/push-ebp
|
||||
89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp
|
||||
|
@ -242,7 +242,7 @@ test-write-stream-appends:
|
|||
|
||||
== data
|
||||
|
||||
_test-stream2:
|
||||
_test-stream2: # (ref stream byte)
|
||||
# current write index
|
||||
4/imm32
|
||||
# current read index
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
# . 1-3 bytes 3 bits 2 bits 3 bits 3 bits 3 bits 2 bits 2 bits 0/1/2/4 bytes 0/1/2/4 bytes
|
||||
|
||||
# write(out, "Error: "+msg+"\n") then stop(ed, 1)
|
||||
error: # ed : (address exit-descriptor), out : fd or (address stream), msg : (address array byte)
|
||||
error: # ed : (address exit-descriptor), out : fd or (address stream byte), msg : (address array byte)
|
||||
# . prologue
|
||||
55/push-ebp
|
||||
89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp
|
||||
|
|
|
@ -7,8 +7,8 @@
|
|||
== data
|
||||
|
||||
# The buffered file for standard output.
|
||||
Stdout:
|
||||
# file descriptor or (address stream)
|
||||
Stdout: # (ref buffered-file)
|
||||
# file descriptor or (address stream byte)
|
||||
1/imm32 # standard output
|
||||
$Stdout->buffer:
|
||||
# inlined fields for a stream
|
||||
|
@ -205,7 +205,7 @@ test-write-byte-buffered-multiple-flushes:
|
|||
# - variant without buffering
|
||||
|
||||
# Write lower byte of 'n' to 'f'.
|
||||
append-byte: # f : (address stream), n : int
|
||||
append-byte: # f : (address stream byte), n : int
|
||||
# . prologue
|
||||
55/push-ebp
|
||||
89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp
|
||||
|
@ -283,7 +283,7 @@ test-append-byte-single:
|
|||
|
||||
== data
|
||||
|
||||
_test-output-stream:
|
||||
_test-output-stream: # (ref stream byte)
|
||||
# current write index
|
||||
0/imm32
|
||||
# current read index
|
||||
|
@ -325,8 +325,8 @@ _test-output-stream:
|
|||
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
|
||||
|
||||
# a test buffered file for _test-output-stream
|
||||
_test-output-buffered-file:
|
||||
# file descriptor or (address stream)
|
||||
_test-output-buffered-file: # (ref buffered-file)
|
||||
# file descriptor or (address stream byte)
|
||||
_test-output-stream/imm32
|
||||
$_test-output-buffered-file->buffer:
|
||||
# current write index
|
||||
|
@ -338,7 +338,7 @@ $_test-output-buffered-file->buffer:
|
|||
# data
|
||||
00 00 00 00 00 00 # 6 bytes
|
||||
|
||||
_test-error-stream:
|
||||
_test-error-stream: # (ref stream byte)
|
||||
# current write index
|
||||
0/imm32
|
||||
# current read index
|
||||
|
@ -356,8 +356,8 @@ _test-error-stream:
|
|||
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
|
||||
|
||||
# a test buffered file for _test-error-stream
|
||||
_test-error-buffered-file:
|
||||
# file descriptor or (address stream)
|
||||
_test-error-buffered-file: # (ref buffered-file)
|
||||
# file descriptor or (address stream byte)
|
||||
_test-error-stream/imm32
|
||||
$_test-error-buffered-file->buffer:
|
||||
# current write index
|
||||
|
|
|
@ -38,9 +38,9 @@ write-buffered: # f : (address buffered-file), msg : (address array byte)
|
|||
57/push-edi
|
||||
# eax = msg
|
||||
8b/copy 1/mod/*+disp8 5/rm32/ebp . . 0/r32/eax 0xc/disp8 . # copy *(ebp+12) to eax
|
||||
# in/esi = msg->data
|
||||
# var in/esi : (address byte) = msg->data
|
||||
8d/copy-address 1/mod/*+disp8 0/rm32/eax . . . 6/r32/esi 4/disp8 . # copy eax+4 to esi
|
||||
# inend/ecx = &msg->data[msg->length]
|
||||
# var inend/ecx : (address byte) = &msg->data[msg->length]
|
||||
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
|
||||
# edi = f
|
||||
|
@ -206,8 +206,8 @@ test-write-buffered-with-intermediate-flush:
|
|||
== data
|
||||
|
||||
# The buffered file for standard error.
|
||||
Stderr:
|
||||
# file descriptor or (address stream)
|
||||
Stderr: # (ref buffered-file)
|
||||
# file descriptor or (address stream byte)
|
||||
2/imm32 # standard error
|
||||
$Stderr->buffer:
|
||||
# inlined fields for a stream
|
||||
|
|
|
@ -5,7 +5,8 @@
|
|||
# . 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
|
||||
|
||||
to-hex-char: # in/eax : nibble -> out/eax : byte
|
||||
# convert the lowest nibble of eax to ascii and return it in the lowest byte of eax
|
||||
to-hex-char: # in/eax : int -> out/eax : int
|
||||
# no error checking; accepts argument in eax
|
||||
# if (eax <= 9) return eax + '0'
|
||||
3d/compare-eax-with 0x9/imm32/9
|
||||
|
@ -17,7 +18,7 @@ $to-hex-char:else:
|
|||
05/add-to-eax 0x57/imm32/a-10
|
||||
c3/return
|
||||
|
||||
append-byte-hex: # f : (address stream), n : int
|
||||
append-byte-hex: # f : (address stream byte), n : int
|
||||
# . prologue
|
||||
55/push-ebp
|
||||
89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp
|
||||
|
@ -174,7 +175,7 @@ test-print-byte-buffered:
|
|||
# . end
|
||||
c3/return
|
||||
|
||||
print-int32: # f : (address stream), n : int
|
||||
print-int32: # f : (address stream byte), n : int
|
||||
# pseudocode:
|
||||
# write(f, "0x")
|
||||
# ecx = 28
|
||||
|
|
|
@ -18,7 +18,7 @@ is-hex-int?: # in : (address slice) -> eax : boolean
|
|||
8b/copy 1/mod/*+disp8 5/rm32/ebp . . . 1/r32/ecx 8/disp8 . # copy *(ebp+8) to ecx
|
||||
# edx = s->end
|
||||
8b/copy 1/mod/*+disp8 1/rm32/ecx . . . 2/r32/edx 4/disp8 . # copy *(ecx+4) to edx
|
||||
# curr/ecx = s->start
|
||||
# var curr/ecx : (address byte) = s->start
|
||||
8b/copy 0/mod/indirect 1/rm32/ecx . . . 1/r32/ecx . . # copy *ecx to ecx
|
||||
# if s is empty return false
|
||||
b8/copy-to-eax 0/imm32/false
|
||||
|
@ -56,7 +56,7 @@ $is-hex-int?:loop:
|
|||
# if (curr >= in->end) return true
|
||||
39/compare 3/mod/direct 1/rm32/ecx . . . 2/r32/edx . . # compare ecx with edx
|
||||
73/jump-if-greater-or-equal-unsigned $is-hex-int?:true/disp8
|
||||
# eax = is-hex-digit?(*curr)
|
||||
# var eax : boolean = is-hex-digit?(*curr)
|
||||
# . . push args
|
||||
8a/copy-byte 0/mod/indirect 1/rm32/ecx . . . 0/r32/AL . . # copy byte at *ecx to AL
|
||||
50/push-eax
|
||||
|
@ -93,7 +93,7 @@ test-is-hex-int:
|
|||
8b/copy 0/mod/indirect 0/rm32/eax . . . 1/r32/ecx . . # copy *eax to ecx
|
||||
8d/copy-address 1/mod/*+disp8 4/rm32/sib 0/base/eax 1/index/ecx . 1/r32/ecx 4/disp8 . # copy eax+ecx+4 to ecx
|
||||
05/add-to-eax 4/imm32
|
||||
# var slice/ecx = {eax, ecx}
|
||||
# var slice/ecx : (ref slice) = {eax, ecx}
|
||||
51/push-ecx
|
||||
50/push-eax
|
||||
89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx
|
||||
|
@ -127,7 +127,7 @@ test-is-hex-int-handles-letters:
|
|||
8b/copy 0/mod/indirect 0/rm32/eax . . . 1/r32/ecx . . # copy *eax to ecx
|
||||
8d/copy-address 1/mod/*+disp8 4/rm32/sib 0/base/eax 1/index/ecx . 1/r32/ecx 4/disp8 . # copy eax+ecx+4 to ecx
|
||||
05/add-to-eax 4/imm32
|
||||
# var slice/ecx = {eax, ecx}
|
||||
# var slice/ecx : (ref slice) = {eax, ecx}
|
||||
51/push-ecx
|
||||
50/push-eax
|
||||
89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx
|
||||
|
@ -161,7 +161,7 @@ test-is-hex-int-with-trailing-char:
|
|||
8b/copy 0/mod/indirect 0/rm32/eax . . . 1/r32/ecx . . # copy *eax to ecx
|
||||
8d/copy-address 1/mod/*+disp8 4/rm32/sib 0/base/eax 1/index/ecx . 1/r32/ecx 4/disp8 . # copy eax+ecx+4 to ecx
|
||||
05/add-to-eax 4/imm32
|
||||
# var slice/ecx = {eax, ecx}
|
||||
# var slice/ecx : (ref slice) = {eax, ecx}
|
||||
51/push-ecx
|
||||
50/push-eax
|
||||
89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx
|
||||
|
@ -195,7 +195,7 @@ test-is-hex-int-with-leading-char:
|
|||
8b/copy 0/mod/indirect 0/rm32/eax . . . 1/r32/ecx . . # copy *eax to ecx
|
||||
8d/copy-address 1/mod/*+disp8 4/rm32/sib 0/base/eax 1/index/ecx . 1/r32/ecx 4/disp8 . # copy eax+ecx+4 to ecx
|
||||
05/add-to-eax 4/imm32
|
||||
# var slice/ecx = {eax, ecx}
|
||||
# var slice/ecx : (ref slice) = {eax, ecx}
|
||||
51/push-ecx
|
||||
50/push-eax
|
||||
89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx
|
||||
|
@ -224,7 +224,7 @@ test-is-hex-int-empty:
|
|||
# . prologue
|
||||
55/push-ebp
|
||||
89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp
|
||||
# var slice/ecx = ""
|
||||
# var slice/ecx : (ref slice) = ""
|
||||
68/push 0/imm32
|
||||
68/push 0/imm32
|
||||
89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx
|
||||
|
@ -258,7 +258,7 @@ test-is-hex-int-handles-0x-prefix:
|
|||
8b/copy 0/mod/indirect 0/rm32/eax . . . 1/r32/ecx . . # copy *eax to ecx
|
||||
8d/copy-address 1/mod/*+disp8 4/rm32/sib 0/base/eax 1/index/ecx . 1/r32/ecx 4/disp8 . # copy eax+ecx+4 to ecx
|
||||
05/add-to-eax 4/imm32
|
||||
# var slice/ecx = {eax, ecx}
|
||||
# var slice/ecx : (ref slice) = {eax, ecx}
|
||||
51/push-ecx
|
||||
50/push-eax
|
||||
89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx
|
||||
|
@ -292,7 +292,7 @@ test-is-hex-int-handles-negative:
|
|||
8b/copy 0/mod/indirect 0/rm32/eax . . . 1/r32/ecx . . # copy *eax to ecx
|
||||
8d/copy-address 1/mod/*+disp8 4/rm32/sib 0/base/eax 1/index/ecx . 1/r32/ecx 4/disp8 . # copy eax+ecx+4 to ecx
|
||||
05/add-to-eax 4/imm32
|
||||
# var slice/ecx = {eax, ecx}
|
||||
# var slice/ecx : (ref slice) = {eax, ecx}
|
||||
51/push-ecx
|
||||
50/push-eax
|
||||
89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx
|
||||
|
@ -326,7 +326,7 @@ test-is-hex-int-handles-negative-0x-prefix:
|
|||
8b/copy 0/mod/indirect 0/rm32/eax . . . 1/r32/ecx . . # copy *eax to ecx
|
||||
8d/copy-address 1/mod/*+disp8 4/rm32/sib 0/base/eax 1/index/ecx . 1/r32/ecx 4/disp8 . # copy eax+ecx+4 to ecx
|
||||
05/add-to-eax 4/imm32
|
||||
# var slice/ecx = {eax, ecx}
|
||||
# var slice/ecx : (ref slice) = {eax, ecx}
|
||||
51/push-ecx
|
||||
50/push-eax
|
||||
89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx
|
||||
|
@ -351,7 +351,7 @@ test-is-hex-int-handles-negative-0x-prefix:
|
|||
5d/pop-to-ebp
|
||||
c3/return
|
||||
|
||||
parse-hex-int: # in : (address slice) -> result/eax
|
||||
parse-hex-int: # in : (address slice) -> result/eax : int
|
||||
# . prologue
|
||||
55/push-ebp
|
||||
89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp
|
||||
|
@ -360,18 +360,18 @@ parse-hex-int: # in : (address slice) -> result/eax
|
|||
52/push-edx
|
||||
53/push-ebx
|
||||
56/push-esi
|
||||
# result/ebx = 0
|
||||
# var result/ebx : int = 0
|
||||
31/xor 3/mod/direct 3/rm32/ebx . . . 3/r32/ebx . . # clear ebx
|
||||
# ecx = s
|
||||
# ecx = in
|
||||
8b/copy 1/mod/*+disp8 5/rm32/ebp . . . 1/r32/ecx 8/disp8 . # copy *(ebp+8) to ecx
|
||||
# edx = s->end
|
||||
# edx = in->end
|
||||
8b/copy 1/mod/*+disp8 1/rm32/ecx . . . 2/r32/edx 4/disp8 . # copy *(ecx+4) to edx
|
||||
# curr/ecx = s->start
|
||||
# var curr/ecx : (address byte) = in->start
|
||||
8b/copy 0/mod/indirect 1/rm32/ecx . . . 1/r32/ecx . . # copy *ecx to ecx
|
||||
# negate?/esi = false
|
||||
# var negate?/esi : boolean = false
|
||||
31/xor 3/mod/direct 6/rm32/esi . . . 6/r32/esi . . # clear esi
|
||||
$parse-hex-int:negative:
|
||||
# . if (*curr == '-') negate = true
|
||||
# if (*curr == '-') ++curr, negate = true
|
||||
31/xor 3/mod/direct 0/rm32/eax . . . 0/r32/eax . . # clear eax
|
||||
8a/copy-byte 0/mod/indirect 1/rm32/ecx . . . 0/r32/AL . . # copy byte at *ecx to AL
|
||||
3d/compare-eax-and 0x2d/imm32/-
|
||||
|
@ -403,7 +403,7 @@ $parse-hex-int:loop:
|
|||
# if (curr >= in->end) break
|
||||
39/compare 3/mod/direct 1/rm32/ecx . . . 2/r32/edx . . # compare ecx with edx
|
||||
73/jump-if-greater-or-equal-unsigned $parse-hex-int:negate/disp8
|
||||
# eax = from-hex-char(*curr)
|
||||
# var eax : int = from-hex-char(*curr)
|
||||
# . . copy arg to eax
|
||||
8a/copy-byte 0/mod/indirect 1/rm32/ecx . . . 0/r32/AL . . # copy byte at *ecx to AL
|
||||
# . . call
|
||||
|
@ -416,10 +416,12 @@ $parse-hex-int:loop:
|
|||
# loop
|
||||
eb/jump $parse-hex-int:loop/disp8
|
||||
$parse-hex-int:negate:
|
||||
81 7/subop/compare 3/mod/direct 6/rm32/esi . . . . . 0/imm32 # compare esi
|
||||
# if (negate?) result = -result
|
||||
81 7/subop/compare 3/mod/direct 6/rm32/esi . . . . . 0/imm32/false # compare esi
|
||||
74/jump-if-equal $parse-hex-int:end/disp8
|
||||
f7 3/subop/negate 3/mod/direct 3/rm32/ebx . . . . . . # negate ebx
|
||||
$parse-hex-int:end:
|
||||
# return result
|
||||
89/copy 3/mod/direct 0/rm32/eax . . . 3/r32/ebx . . # copy ebx to eax
|
||||
# . restore registers
|
||||
5e/pop-to-esi
|
||||
|
@ -440,7 +442,7 @@ test-parse-hex-int-single-digit:
|
|||
8b/copy 0/mod/indirect 0/rm32/eax . . . 1/r32/ecx . . # copy *eax to ecx
|
||||
8d/copy-address 1/mod/*+disp8 4/rm32/sib 0/base/eax 1/index/ecx . 1/r32/ecx 4/disp8 . # copy eax+ecx+4 to ecx
|
||||
05/add-to-eax 4/imm32
|
||||
# var slice/ecx = {eax, ecx}
|
||||
# var slice/ecx : (ref slice) = {eax, ecx}
|
||||
51/push-ecx
|
||||
50/push-eax
|
||||
89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx
|
||||
|
@ -474,7 +476,7 @@ test-parse-hex-int-multi-digit:
|
|||
8b/copy 0/mod/indirect 0/rm32/eax . . . 1/r32/ecx . . # copy *eax to ecx
|
||||
8d/copy-address 1/mod/*+disp8 4/rm32/sib 0/base/eax 1/index/ecx . 1/r32/ecx 4/disp8 . # copy eax+ecx+4 to ecx
|
||||
05/add-to-eax 4/imm32
|
||||
# var slice/ecx = {eax, ecx}
|
||||
# var slice/ecx : (ref slice) = {eax, ecx}
|
||||
51/push-ecx
|
||||
50/push-eax
|
||||
89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx
|
||||
|
@ -508,7 +510,7 @@ test-parse-hex-int-0x-prefix:
|
|||
8b/copy 0/mod/indirect 0/rm32/eax . . . 1/r32/ecx . . # copy *eax to ecx
|
||||
8d/copy-address 1/mod/*+disp8 4/rm32/sib 0/base/eax 1/index/ecx . 1/r32/ecx 4/disp8 . # copy eax+ecx+4 to ecx
|
||||
05/add-to-eax 4/imm32
|
||||
# var slice/ecx = {eax, ecx}
|
||||
# var slice/ecx : (ref slice) = {eax, ecx}
|
||||
51/push-ecx
|
||||
50/push-eax
|
||||
89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx
|
||||
|
@ -542,7 +544,7 @@ test-parse-hex-int-zero:
|
|||
8b/copy 0/mod/indirect 0/rm32/eax . . . 1/r32/ecx . . # copy *eax to ecx
|
||||
8d/copy-address 1/mod/*+disp8 4/rm32/sib 0/base/eax 1/index/ecx . 1/r32/ecx 4/disp8 . # copy eax+ecx+4 to ecx
|
||||
05/add-to-eax 4/imm32
|
||||
# var slice/ecx = {eax, ecx}
|
||||
# var slice/ecx : (ref slice) = {eax, ecx}
|
||||
51/push-ecx
|
||||
50/push-eax
|
||||
89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx
|
||||
|
@ -576,7 +578,7 @@ test-parse-hex-int-0-prefix:
|
|||
8b/copy 0/mod/indirect 0/rm32/eax . . . 1/r32/ecx . . # copy *eax to ecx
|
||||
8d/copy-address 1/mod/*+disp8 4/rm32/sib 0/base/eax 1/index/ecx . 1/r32/ecx 4/disp8 . # copy eax+ecx+4 to ecx
|
||||
05/add-to-eax 4/imm32
|
||||
# var slice/ecx = {eax, ecx}
|
||||
# var slice/ecx : (ref slice) = {eax, ecx}
|
||||
51/push-ecx
|
||||
50/push-eax
|
||||
89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx
|
||||
|
@ -610,7 +612,7 @@ test-parse-hex-int-negative:
|
|||
8b/copy 0/mod/indirect 0/rm32/eax . . . 1/r32/ecx . . # copy *eax to ecx
|
||||
8d/copy-address 1/mod/*+disp8 4/rm32/sib 0/base/eax 1/index/ecx . 1/r32/ecx 4/disp8 . # copy eax+ecx+4 to ecx
|
||||
05/add-to-eax 4/imm32
|
||||
# var slice/ecx = {eax, ecx}
|
||||
# var slice/ecx : (ref slice) = {eax, ecx}
|
||||
51/push-ecx
|
||||
50/push-eax
|
||||
89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
# . 1-3 bytes 3 bits 2 bits 3 bits 3 bits 3 bits 2 bits 2 bits 0/1/2/4 bytes 0/1/2/4 bytes
|
||||
|
||||
#? Entry: # manual test
|
||||
#? # . var ed/eax : exit-descriptor
|
||||
#? # . var ed/eax : (ref exit-descriptor)
|
||||
#? 81 5/subop/subtract 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # subtract from esp
|
||||
#? 89/copy 3/mod/direct 0/rm32/eax . . . 4/r32/esp . . # copy esp to eax
|
||||
#? # . configure ed to really exit()
|
||||
|
@ -68,7 +68,7 @@ error-byte: # ed : (address exit-descriptor), out : (address buffered-file), ms
|
|||
e8/call write-buffered/disp32
|
||||
# . . discard args
|
||||
81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp
|
||||
# . flush(out)
|
||||
# flush(out)
|
||||
# . . push args
|
||||
ff 6/subop/push 1/mod/*+disp8 5/rm32/ebp . . . . 0xc/disp8 . # push *(ebp+12)
|
||||
# . . call
|
||||
|
|
|
@ -19,14 +19,14 @@
|
|||
== data
|
||||
|
||||
# A default allocation descriptor for programs to use.
|
||||
Heap:
|
||||
Heap: # (ref allocation-descriptor)
|
||||
# curr
|
||||
0/imm32
|
||||
# limit
|
||||
0/imm32
|
||||
|
||||
# a reasonable default
|
||||
Heap-size:
|
||||
Heap-size: # (ref int)
|
||||
0x200000/imm32/2MB
|
||||
|
||||
== code
|
||||
|
@ -56,7 +56,7 @@ $array-equal-main:end:
|
|||
|
||||
# Claim the next 'n' bytes of memory starting at ad->curr and update ad->curr.
|
||||
# Abort if there isn't enough memory in 'ad'.
|
||||
allocate: # ad : (address allocation-descriptor), n : int -> address-or-null/eax
|
||||
allocate: # ad : (address allocation-descriptor), n : int -> address-or-null/eax : (address _)
|
||||
# . prologue
|
||||
55/push-ebp
|
||||
89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp
|
||||
|
@ -104,11 +104,11 @@ test-allocate-success:
|
|||
# . prologue
|
||||
55/push-ebp
|
||||
89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp
|
||||
# var ad/ecx : (address allocation-descriptor) = {11, 15}
|
||||
# var ad/ecx : (ref allocation-descriptor) = {11, 15}
|
||||
68/push 0xf/imm32/limit
|
||||
68/push 0xb/imm32/curr
|
||||
89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx
|
||||
# eax = allocate(ad, 3)
|
||||
# var eax : (handle byte) = allocate(ad, 3)
|
||||
# . . push args
|
||||
68/push 3/imm32
|
||||
51/push-ecx
|
||||
|
@ -143,11 +143,11 @@ _pending-test-allocate-failure:
|
|||
# . prologue
|
||||
55/push-ebp
|
||||
89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp
|
||||
# var ad/ecx : (address allocation-descriptor) = {11, 15}
|
||||
# var ad/ecx : (ref allocation-descriptor) = {11, 15}
|
||||
68/push 0xf/imm32/limit
|
||||
68/push 0xb/imm32/curr
|
||||
89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx
|
||||
# eax = allocate(ad, 6)
|
||||
# var eax : (handle byte) = allocate(ad, 6)
|
||||
# . . push args
|
||||
68/push 6/imm32
|
||||
51/push-ecx
|
||||
|
@ -180,7 +180,7 @@ _pending-test-allocate-failure:
|
|||
c3/return
|
||||
|
||||
# helper: create a nested allocation descriptor (useful for tests)
|
||||
allocate-region: # ad : (address allocation-descriptor), n : int -> new-ad : (address allocation-descriptor)
|
||||
allocate-region: # ad : (address allocation-descriptor), n : int -> new-ad : (handle allocation-descriptor)
|
||||
# . prologue
|
||||
55/push-ebp
|
||||
89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp
|
||||
|
|
|
@ -5,13 +5,13 @@
|
|||
# . 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
|
||||
|
||||
new-stream: # ad : (address allocation-descriptor), length : int, elemsize : int -> address/eax
|
||||
new-stream: # ad : (address allocation-descriptor), length : int, elemsize : int -> address/eax : (handle stream _)
|
||||
# . prologue
|
||||
55/push-ebp
|
||||
89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp
|
||||
# . save registers
|
||||
52/push-edx
|
||||
# n = elemsize * length + 12 (for read, write and length)
|
||||
# var n/eax : int = elemsize * length + 12 (for read, write and length)
|
||||
# . eax = elemsize
|
||||
8b/copy 1/mod/*+disp8 5/rm32/ebp . . . 0/r32/eax 0x10/disp8 . # copy *(ebp+16) to eax
|
||||
# . eax *= length
|
||||
|
@ -24,7 +24,7 @@ new-stream: # ad : (address allocation-descriptor), length : int, elemsize : in
|
|||
89/copy 3/mod/direct 2/rm32/edx . . . 0/r32/eax . . # copy eax to edx
|
||||
# . eax += 12
|
||||
05/add-to-eax 0xc/imm32
|
||||
# allocate(ad, n)
|
||||
# var eax : (handle stream _) = allocate(ad, n)
|
||||
# . . push args
|
||||
50/push-eax
|
||||
ff 6/subop/push 1/mod/*+disp8 5/rm32/ebp . . . . 8/disp8 . # push *(ebp+8)
|
||||
|
@ -68,7 +68,7 @@ test-new-stream:
|
|||
# . prologue
|
||||
55/push-ebp
|
||||
89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp
|
||||
# var heap/ecx : (address allocation-descriptor) = {0, 0}
|
||||
# var heap/ecx : (ref allocation-descriptor)
|
||||
68/push 0/imm32/limit
|
||||
68/push 0/imm32/curr
|
||||
89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx
|
||||
|
@ -82,7 +82,7 @@ test-new-stream:
|
|||
81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp
|
||||
# var start/edx = ad->curr
|
||||
8b/copy 0/mod/indirect 1/rm32/ecx . . . 2/r32/edx . . # copy *ecx to edx
|
||||
# eax = new-stream(heap, 3, 2)
|
||||
# var eax : (handle stream byte) = new-stream(heap, 3, 2)
|
||||
# . . push args
|
||||
68/push 2/imm32
|
||||
68/push 3/imm32
|
||||
|
|
|
@ -216,7 +216,7 @@ test-read-line-buffered-reads-final-line-until-Eof:
|
|||
# read bytes from 'f' until (and including) a newline and store them into 's'
|
||||
# 's' fails to grow if and only if no data found
|
||||
# just abort if 's' is too small
|
||||
read-line: # f : (address stream), s : (address stream byte)
|
||||
read-line: # f : (address stream byte), s : (address stream byte)
|
||||
# pseudocode:
|
||||
# while true
|
||||
# if (s->write >= s->length) abort
|
||||
|
|
106
072slice.subx
106
072slice.subx
|
@ -34,7 +34,7 @@ test-slice-empty-true:
|
|||
# . prologue
|
||||
55/push-ebp
|
||||
89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp
|
||||
# var slice/ecx = {34, 34}
|
||||
# var slice/ecx : (ref slice) = {34, 34}
|
||||
68/push 34/imm32/end
|
||||
68/push 34/imm32/start
|
||||
89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx
|
||||
|
@ -63,7 +63,7 @@ test-slice-empty-false:
|
|||
# . prologue
|
||||
55/push-ebp
|
||||
89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp
|
||||
# var slice/ecx = {34, 23}
|
||||
# var slice/ecx : (ref slice) = {34, 23}
|
||||
68/push 23/imm32/end
|
||||
68/push 34/imm32/start
|
||||
89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx
|
||||
|
@ -88,7 +88,7 @@ test-slice-empty-false:
|
|||
5d/pop-to-ebp
|
||||
c3/return
|
||||
|
||||
slice-equal?: # s : (address slice), p : (address string) -> eax : boolean
|
||||
slice-equal?: # s : (address slice), p : (address array byte) -> eax : boolean
|
||||
# pseudocode:
|
||||
# if (p == 0) return (s == 0)
|
||||
# currs = s->start
|
||||
|
@ -118,11 +118,11 @@ slice-equal?: # s : (address slice), p : (address string) -> eax : boolean
|
|||
56/push-esi
|
||||
# esi = s
|
||||
8b/copy 1/mod/*+disp8 5/rm32/ebp . . . 6/r32/esi 8/disp8 . # copy *(ebp+8) to esi
|
||||
# currs/edx = s->start
|
||||
# var currs/edx : (address byte) = s->start
|
||||
8b/copy 0/mod/indirect 6/rm32/esi . . . 2/r32/edx . . # copy *esi to edx
|
||||
# maxs/esi = s->end
|
||||
# var maxs/esi : (address byte) = s->end
|
||||
8b/copy 1/mod/*+disp8 6/rm32/esi . . . 6/r32/esi 4/disp8 . # copy *(esi+4) to esi
|
||||
# eax = maxs - currs
|
||||
# var slen/eax : int = maxs - currs
|
||||
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
|
||||
# ebx = p
|
||||
|
@ -136,23 +136,24 @@ $slice-equal?:null-string:
|
|||
74/jump-if-equal $slice-equal?:true/disp8
|
||||
eb/jump $slice-equal?:false/disp8
|
||||
$slice-equal?:nonnull-string:
|
||||
# if (eax != p->length) return false
|
||||
# if (slen != p->length) return false
|
||||
39/compare 0/mod/indirect 3/rm32/ebx . . . 0/r32/eax . . # compare *ebx and eax
|
||||
75/jump-if-not-equal $slice-equal?:false/disp8
|
||||
# currp/ebx = p->data
|
||||
# var currp/ebx : (address byte) = p->data
|
||||
81 0/subop/add 3/mod/direct 3/rm32/ebx . . . . . 4/imm32 # add to ebx
|
||||
# eax = ecx = 0
|
||||
# var c1/eax : byte = 0
|
||||
31/xor 3/mod/direct 0/rm32/eax . . . 0/r32/eax . . # clear eax
|
||||
# var c2/ecx : byte = 0
|
||||
31/xor 3/mod/direct 1/rm32/ecx . . . 1/r32/ecx . . # clear ecx
|
||||
$slice-equal?:loop:
|
||||
# if (currs >= maxs) return true
|
||||
39/compare 3/mod/direct 2/rm32/edx . . . 6/r32/esi . . # compare edx with esi
|
||||
73/jump-if-greater-or-equal-unsigned $slice-equal?:true/disp8
|
||||
# AL = *currp
|
||||
# c1 = *currp
|
||||
8a/copy-byte 0/mod/indirect 3/rm32/ebx . . . 0/r32/AL . . # copy byte at *ebx to AL
|
||||
# CL = *currs
|
||||
# c2 = *currs
|
||||
8a/copy-byte 0/mod/indirect 2/rm32/edx . . . 1/r32/CL . . # copy byte at *edx to CL
|
||||
# if (eax != ecx) return false
|
||||
# if (c1 != c2) return false
|
||||
39/compare 3/mod/direct 0/rm32/eax . . . 1/r32/ecx . . # compare eax and ecx
|
||||
75/jump-if-not-equal $slice-equal?:false/disp8
|
||||
# ++currp
|
||||
|
@ -186,7 +187,7 @@ test-slice-equal:
|
|||
8b/copy 0/mod/indirect 0/rm32/eax . . . 1/r32/ecx . . # copy *eax to ecx
|
||||
8d/copy-address 1/mod/*+disp8 4/rm32/sib 0/base/eax 1/index/ecx . 1/r32/ecx 4/disp8 . # copy eax+ecx+4 to ecx
|
||||
05/add-to-eax 4/imm32
|
||||
# var slice/ecx = {eax, ecx}
|
||||
# var slice/ecx : (ref slice) = {eax, ecx}
|
||||
51/push-ecx
|
||||
50/push-eax
|
||||
89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx
|
||||
|
@ -222,7 +223,7 @@ test-slice-equal-false:
|
|||
8b/copy 0/mod/indirect 0/rm32/eax . . . 1/r32/ecx . . # copy *eax to ecx
|
||||
8d/copy-address 1/mod/*+disp8 4/rm32/sib 0/base/eax 1/index/ecx . 1/r32/ecx 4/disp8 . # copy eax+ecx+4 to ecx
|
||||
05/add-to-eax 4/imm32
|
||||
# var slice/ecx = {eax, ecx}
|
||||
# var slice/ecx : (ref slice) = {eax, ecx}
|
||||
51/push-ecx
|
||||
50/push-eax
|
||||
89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx
|
||||
|
@ -258,7 +259,7 @@ test-slice-equal-too-long:
|
|||
8b/copy 0/mod/indirect 0/rm32/eax . . . 1/r32/ecx . . # copy *eax to ecx
|
||||
8d/copy-address 1/mod/*+disp8 4/rm32/sib 0/base/eax 1/index/ecx . 1/r32/ecx 4/disp8 . # copy eax+ecx+4 to ecx
|
||||
05/add-to-eax 4/imm32
|
||||
# var slice/ecx = {eax, ecx}
|
||||
# var slice/ecx : (ref slice) = {eax, ecx}
|
||||
51/push-ecx
|
||||
50/push-eax
|
||||
89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx
|
||||
|
@ -294,7 +295,7 @@ test-slice-equal-too-short:
|
|||
8b/copy 0/mod/indirect 0/rm32/eax . . . 1/r32/ecx . . # copy *eax to ecx
|
||||
8d/copy-address 1/mod/*+disp8 4/rm32/sib 0/base/eax 1/index/ecx . 1/r32/ecx 4/disp8 . # copy eax+ecx+4 to ecx
|
||||
05/add-to-eax 4/imm32
|
||||
# var slice/ecx = {eax, ecx}
|
||||
# var slice/ecx : (ref slice) = {eax, ecx}
|
||||
51/push-ecx
|
||||
50/push-eax
|
||||
89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx
|
||||
|
@ -325,7 +326,7 @@ test-slice-equal-empty:
|
|||
# . prologue
|
||||
55/push-ebp
|
||||
89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp
|
||||
# var slice/ecx
|
||||
# var slice/ecx : (ref slice)
|
||||
68/push 0/imm32/end
|
||||
68/push 0/imm32/start
|
||||
89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx
|
||||
|
@ -361,7 +362,7 @@ test-slice-equal-with-empty:
|
|||
8b/copy 0/mod/indirect 0/rm32/eax . . . 1/r32/ecx . . # copy *eax to ecx
|
||||
8d/copy-address 1/mod/*+disp8 4/rm32/sib 0/base/eax 1/index/ecx . 1/r32/ecx 4/disp8 . # copy eax+ecx+4 to ecx
|
||||
05/add-to-eax 4/imm32
|
||||
# var slice/ecx = {eax, ecx}
|
||||
# var slice/ecx : (ref slice) = {eax, ecx}
|
||||
51/push-ecx
|
||||
50/push-eax
|
||||
89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx
|
||||
|
@ -392,7 +393,7 @@ test-slice-equal-empty-with-empty:
|
|||
# . prologue
|
||||
55/push-ebp
|
||||
89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp
|
||||
# var slice/ecx
|
||||
# var slice/ecx : (ref slice)
|
||||
68/push 0/imm32/end
|
||||
68/push 0/imm32/start
|
||||
89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx
|
||||
|
@ -428,7 +429,7 @@ test-slice-equal-with-null:
|
|||
8b/copy 0/mod/indirect 0/rm32/eax . . . 1/r32/ecx . . # copy *eax to ecx
|
||||
8d/copy-address 1/mod/*+disp8 4/rm32/sib 0/base/eax 1/index/ecx . 1/r32/ecx 4/disp8 . # copy eax+ecx+4 to ecx
|
||||
05/add-to-eax 4/imm32
|
||||
# var slice/ecx = {eax, ecx}
|
||||
# var slice/ecx : (ref slice) = {eax, ecx}
|
||||
51/push-ecx
|
||||
50/push-eax
|
||||
89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx
|
||||
|
@ -454,7 +455,7 @@ test-slice-equal-with-null:
|
|||
5d/pop-to-ebp
|
||||
c3/return
|
||||
|
||||
slice-starts-with?: # s : (address slice), head : (address string) -> eax : boolean
|
||||
slice-starts-with?: # s : (address slice), head : (address array byte) -> eax : boolean
|
||||
# pseudocode
|
||||
# lenh = head->length
|
||||
# if (lenh > s->end - s->start) return false
|
||||
|
@ -487,34 +488,35 @@ slice-starts-with?: # s : (address slice), head : (address string) -> eax : boo
|
|||
57/push-edi
|
||||
# esi = s
|
||||
8b/copy 1/mod/*+disp8 5/rm32/ebp . . . 6/r32/esi 8/disp8 . # copy *(ebp+8) to esi
|
||||
# ecx = s->end - s->start
|
||||
# var lens/ecx : int = s->end - s->start
|
||||
8b/copy 1/mod/*+disp8 6/rm32/esi . . . 1/r32/ecx 4/disp8 . # copy *(esi+4) to ecx
|
||||
2b/subtract 0/mod/indirect 6/rm32/esi . . . 1/r32/ecx . . # subtract *esi from ecx
|
||||
# edi = head
|
||||
8b/copy 1/mod/*+disp8 5/rm32/ebp . . . 7/r32/edi 0xc/disp8 . # copy *(ebp+12) to edi
|
||||
# lenh/edx = head->length
|
||||
# var lenh/edx : int = head->length
|
||||
8b/copy 0/mod/indirect 7/rm32/edi . . . 2/r32/edx . . # copy *edi to edx
|
||||
# if (lenh > s->end - s->start) return false
|
||||
# if (lenh > lens) return false
|
||||
39/compare 3/mod/direct 2/rm32/edx . . . 1/r32/ecx . . # compare edx with ecx
|
||||
7f/jump-if-greater $slice-starts-with?:false/disp8
|
||||
# currs/esi = s->start
|
||||
# var currs/esi : (address byte) = s->start
|
||||
8b/subtract 0/mod/indirect 6/rm32/esi . . . 6/r32/esi . . # copy *esi to esi
|
||||
# currh/edi = head->data
|
||||
# var currh/edi : (address byte) = head->data
|
||||
81 0/subop/add 3/mod/direct 7/rm32/edi . . . . . 4/imm32 # add to edi
|
||||
# i/ecx = 0
|
||||
# var i/ecx : int = 0
|
||||
31/xor 3/mod/direct 1/rm32/ecx . . . 1/r32/ecx . . # clear ecx
|
||||
# eax = ebx = 0
|
||||
# var c1/eax : byte = 0
|
||||
31/xor 3/mod/direct 0/rm32/eax . . . 0/r32/eax . . # clear eax
|
||||
# var c2/ebx : byte = 0
|
||||
31/xor 3/mod/direct 3/rm32/ebx . . . 3/r32/ebx . . # clear ebx
|
||||
$slice-starts-with?:loop:
|
||||
# if (i >= lenh) return true
|
||||
39/compare 3/mod/direct 1/rm32/ecx . . . 2/r32/edx . . # compare ecx with edx
|
||||
7d/jump-if-greater-or-equal $slice-starts-with?:true/disp8
|
||||
# AL = *currs
|
||||
# c1 = *currs
|
||||
8a/copy-byte 0/mod/indirect 6/rm32/esi . . . 0/r32/AL . . # copy byte at *esi to AL
|
||||
# BL = *currh
|
||||
# c2 = *currh
|
||||
8a/copy-byte 0/mod/indirect 7/rm32/edi . . . 3/r32/BL . . # copy byte at *edi to BL
|
||||
# if (*currs != *currh) return false
|
||||
# if (c1 != c2) return false
|
||||
39/compare 3/mod/direct 0/rm32/eax . . . 3/r32/ebx . . # compare eax and ebx
|
||||
75/jump-if-not-equal $slice-starts-with?:false/disp8
|
||||
# ++i
|
||||
|
@ -551,7 +553,7 @@ test-slice-starts-with-single-character:
|
|||
8b/copy 0/mod/indirect 0/rm32/eax . . . 1/r32/ecx . . # copy *eax to ecx
|
||||
8d/copy-address 1/mod/*+disp8 4/rm32/sib 0/base/eax 1/index/ecx . 1/r32/ecx 4/disp8 . # copy eax+ecx+4 to ecx
|
||||
05/add-to-eax 4/imm32
|
||||
# var slice/ecx = {eax, ecx}
|
||||
# var slice/ecx : (ref slice) = {eax, ecx}
|
||||
51/push-ecx
|
||||
50/push-eax
|
||||
89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx
|
||||
|
@ -587,7 +589,7 @@ test-slice-starts-with-empty-string:
|
|||
8b/copy 0/mod/indirect 0/rm32/eax . . . 1/r32/ecx . . # copy *eax to ecx
|
||||
8d/copy-address 1/mod/*+disp8 4/rm32/sib 0/base/eax 1/index/ecx . 1/r32/ecx 4/disp8 . # copy eax+ecx+4 to ecx
|
||||
05/add-to-eax 4/imm32
|
||||
# var slice/ecx = {eax, ecx}
|
||||
# var slice/ecx : (ref slice) = {eax, ecx}
|
||||
51/push-ecx
|
||||
50/push-eax
|
||||
89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx
|
||||
|
@ -623,7 +625,7 @@ test-slice-starts-with-multiple-characters:
|
|||
8b/copy 0/mod/indirect 0/rm32/eax . . . 1/r32/ecx . . # copy *eax to ecx
|
||||
8d/copy-address 1/mod/*+disp8 4/rm32/sib 0/base/eax 1/index/ecx . 1/r32/ecx 4/disp8 . # copy eax+ecx+4 to ecx
|
||||
05/add-to-eax 4/imm32
|
||||
# var slice/ecx = {eax, ecx}
|
||||
# var slice/ecx : (ref slice) = {eax, ecx}
|
||||
51/push-ecx
|
||||
50/push-eax
|
||||
89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx
|
||||
|
@ -659,7 +661,7 @@ test-slice-starts-with-entire-string:
|
|||
8b/copy 0/mod/indirect 0/rm32/eax . . . 1/r32/ecx . . # copy *eax to ecx
|
||||
8d/copy-address 1/mod/*+disp8 4/rm32/sib 0/base/eax 1/index/ecx . 1/r32/ecx 4/disp8 . # copy eax+ecx+4 to ecx
|
||||
05/add-to-eax 4/imm32
|
||||
# var slice/ecx = {eax, ecx}
|
||||
# var slice/ecx : (ref slice) = {eax, ecx}
|
||||
51/push-ecx
|
||||
50/push-eax
|
||||
89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx
|
||||
|
@ -695,7 +697,7 @@ test-slice-starts-with-fails:
|
|||
8b/copy 0/mod/indirect 0/rm32/eax . . . 1/r32/ecx . . # copy *eax to ecx
|
||||
8d/copy-address 1/mod/*+disp8 4/rm32/sib 0/base/eax 1/index/ecx . 1/r32/ecx 4/disp8 . # copy eax+ecx+4 to ecx
|
||||
05/add-to-eax 4/imm32
|
||||
# var slice/ecx = {eax, ecx}
|
||||
# var slice/ecx : (ref slice) = {eax, ecx}
|
||||
51/push-ecx
|
||||
50/push-eax
|
||||
89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx
|
||||
|
@ -731,7 +733,7 @@ test-slice-starts-with-fails-2:
|
|||
8b/copy 0/mod/indirect 0/rm32/eax . . . 1/r32/ecx . . # copy *eax to ecx
|
||||
8d/copy-address 1/mod/*+disp8 4/rm32/sib 0/base/eax 1/index/ecx . 1/r32/ecx 4/disp8 . # copy eax+ecx+4 to ecx
|
||||
05/add-to-eax 4/imm32
|
||||
# var slice/ecx = {eax, ecx}
|
||||
# var slice/ecx : (ref slice) = {eax, ecx}
|
||||
51/push-ecx
|
||||
50/push-eax
|
||||
89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx
|
||||
|
@ -759,7 +761,7 @@ test-slice-starts-with-fails-2:
|
|||
|
||||
# write a slice to a stream
|
||||
# abort if the stream doesn't have enough space
|
||||
write-slice: # out : (address stream), s : (address slice)
|
||||
write-slice: # out : (address stream byte), s : (address slice)
|
||||
# . prologue
|
||||
55/push-ebp
|
||||
89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp
|
||||
|
@ -772,9 +774,9 @@ write-slice: # out : (address stream), s : (address slice)
|
|||
57/push-edi
|
||||
# esi = s
|
||||
8b/copy 1/mod/*+disp8 5/rm32/ebp . . . 6/r32/esi 0xc/disp8 . # copy *(ebp+12) to esi
|
||||
# curr/ecx = s->start
|
||||
# var curr/ecx : (address byte) = s->start
|
||||
8b/copy 0/mod/indirect 6/rm32/esi . . . 1/r32/ecx . . # copy *esi to ecx
|
||||
# max/esi = s->end
|
||||
# var max/esi : (address byte) = s->end
|
||||
8b/copy 1/mod/*+disp8 6/rm32/esi . . . 6/r32/esi 4/disp8 . # copy *(esi+4) to esi
|
||||
# edi = out
|
||||
8b/copy 1/mod/*+disp8 5/rm32/ebp . . 7/r32/edi 8/disp8 . # copy *(ebp+8) to edi
|
||||
|
@ -848,7 +850,7 @@ test-write-slice:
|
|||
8b/copy 0/mod/indirect 0/rm32/eax . . . 1/r32/ecx . . # copy *eax to ecx
|
||||
8d/copy-address 1/mod/*+disp8 4/rm32/sib 0/base/eax 1/index/ecx . 1/r32/ecx 4/disp8 . # copy eax+ecx+4 to ecx
|
||||
05/add-to-eax 4/imm32
|
||||
# var slice/ecx = {eax, ecx}
|
||||
# var slice/ecx : (ref slice) = {eax, ecx}
|
||||
51/push-ecx
|
||||
50/push-eax
|
||||
89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx
|
||||
|
@ -888,9 +890,9 @@ write-slice-buffered: # out : (address buffered-file), s : (address slice)
|
|||
57/push-edi
|
||||
# esi = s
|
||||
8b/copy 1/mod/*+disp8 5/rm32/ebp . . . 6/r32/esi 0xc/disp8 . # copy *(ebp+12) to esi
|
||||
# curr/ecx = s->start
|
||||
# var curr/ecx : (address byte) = s->start
|
||||
8b/copy 0/mod/indirect 6/rm32/esi . . . 1/r32/ecx . . # copy *esi to ecx
|
||||
# max/esi = s->end
|
||||
# var max/esi : (address byte) = s->end
|
||||
8b/copy 1/mod/*+disp8 6/rm32/esi . . . 6/r32/esi 4/disp8 . # copy *(esi+4) to esi
|
||||
# edi = out
|
||||
8b/copy 1/mod/*+disp8 5/rm32/ebp . . 7/r32/edi 8/disp8 . # copy *(ebp+8) to edi
|
||||
|
@ -976,7 +978,7 @@ test-write-slice-buffered:
|
|||
8b/copy 0/mod/indirect 0/rm32/eax . . . 1/r32/ecx . . # copy *eax to ecx
|
||||
8d/copy-address 1/mod/*+disp8 4/rm32/sib 0/base/eax 1/index/ecx . 1/r32/ecx 4/disp8 . # copy eax+ecx+4 to ecx
|
||||
05/add-to-eax 4/imm32
|
||||
# var slice/ecx = {eax, ecx}
|
||||
# var slice/ecx : (ref slice) = {eax, ecx}
|
||||
51/push-ecx
|
||||
50/push-eax
|
||||
89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx
|
||||
|
@ -1010,7 +1012,7 @@ test-write-slice-buffered:
|
|||
c3/return
|
||||
|
||||
# copy a slice into a new (dynamically allocated) string
|
||||
slice-to-string: # ad : (address allocation-descriptor), in : (address slice) -> out/eax : (address array)
|
||||
slice-to-string: # ad : (address allocation-descriptor), in : (address slice) -> out/eax : (address array byte)
|
||||
# . prologue
|
||||
55/push-ebp
|
||||
89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp
|
||||
|
@ -1021,15 +1023,15 @@ slice-to-string: # ad : (address allocation-descriptor), in : (address slice) -
|
|||
56/push-esi
|
||||
# esi = in
|
||||
8b/copy 1/mod/*+disp8 5/rm32/ebp . . . 6/r32/esi 0xc/disp8 . # copy *(ebp+12) to esi
|
||||
# curr/edx = in->start
|
||||
# var curr/edx : (address byte) = in->start
|
||||
8b/copy 0/mod/indirect 6/rm32/esi . . . 2/r32/edx . . # copy *esi to edx
|
||||
# max/ebx = in->end
|
||||
# var max/ebx : (address byte) = in->end
|
||||
8b/copy 1/mod/*+disp8 6/rm32/esi . . . 3/r32/ebx 4/disp8 . # copy *(esi+4) to ebx
|
||||
# size/ecx = 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 length)
|
||||
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
|
||||
81 0/subop/add 3/mod/direct 1/rm32/ecx . . . . . 4/imm32 # add to ecx
|
||||
# out/eax = allocate(ad, size)
|
||||
# var out/eax : (handle array byte) = allocate(ad, size)
|
||||
# . . push args
|
||||
51/push-ecx
|
||||
ff 6/subop/push 1/mod/*+disp8 5/rm32/ebp . . . . 8/disp8 . # push *(ebp+8)
|
||||
|
@ -1040,7 +1042,7 @@ slice-to-string: # ad : (address allocation-descriptor), in : (address slice) -
|
|||
# if (eax == 0) abort
|
||||
3d/compare-eax-and 0/imm32
|
||||
74/jump-if-equal $slice-to-string:abort/disp8
|
||||
# *out = size-4
|
||||
# out->length = size-4
|
||||
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
|
||||
# save out
|
||||
|
@ -1092,7 +1094,7 @@ test-slice-to-string:
|
|||
# . prologue
|
||||
55/push-ebp
|
||||
89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp
|
||||
# var heap/edx : (address allocation-descriptor) = {0, 0}
|
||||
# var heap/edx : (ref allocation-descriptor)
|
||||
68/push 0/imm32/limit
|
||||
68/push 0/imm32/curr
|
||||
89/copy 3/mod/direct 2/rm32/edx . . . 4/r32/esp . . # copy esp to edx
|
||||
|
@ -1109,7 +1111,7 @@ test-slice-to-string:
|
|||
8b/copy 0/mod/indirect 0/rm32/eax . . . 1/r32/ecx . . # copy *eax to ecx
|
||||
8d/copy-address 1/mod/*+disp8 4/rm32/sib 0/base/eax 1/index/ecx . 1/r32/ecx 4/disp8 . # copy eax+ecx+4 to ecx
|
||||
05/add-to-eax 4/imm32
|
||||
# var slice/ecx = {eax, ecx}
|
||||
# var slice/ecx : (ref slice) = {eax, ecx}
|
||||
51/push-ecx
|
||||
50/push-eax
|
||||
89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
|
||||
# extract the next run of characters that are different from a given 'delimiter' (skipping multiple delimiters if necessary)
|
||||
# on reaching end of file, return an empty interval
|
||||
next-token: # in : (address stream), delimiter : byte, out : (address slice)
|
||||
next-token: # in : (address stream byte), delimiter : byte, out : (address slice)
|
||||
# . prologue
|
||||
55/push-ebp
|
||||
89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp
|
||||
|
@ -66,7 +66,7 @@ test-next-token:
|
|||
e8/call clear-stream/disp32
|
||||
# . . discard args
|
||||
81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp
|
||||
# var slice/ecx = {0, 0}
|
||||
# var slice/ecx : (ref slice)
|
||||
68/push 0/imm32/end
|
||||
68/push 0/imm32/start
|
||||
89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx
|
||||
|
@ -130,7 +130,7 @@ test-next-token-Eof:
|
|||
e8/call clear-stream/disp32
|
||||
# . . discard args
|
||||
81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp
|
||||
# var slice/ecx = {0, 0}
|
||||
# var slice/ecx : (ref slice)
|
||||
68/push 0/imm32/end
|
||||
68/push 0/imm32/start
|
||||
89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx
|
||||
|
@ -216,7 +216,7 @@ test-next-token-from-slice:
|
|||
8b/copy 0/mod/indirect 0/rm32/eax . . . 1/r32/ecx . . # copy *eax to ecx
|
||||
8d/copy-address 1/mod/*+disp8 4/rm32/sib 0/base/eax 1/index/ecx . 1/r32/ecx 4/disp8 . # copy eax+ecx+4 to ecx
|
||||
05/add-to-eax 4/imm32
|
||||
# var out/edi : (address slice) = {0, 0}
|
||||
# var out/edi : (ref slice)
|
||||
68/push 0/imm32/end
|
||||
68/push 0/imm32/start
|
||||
89/copy 3/mod/direct 7/rm32/edi . . . 4/r32/esp . . # copy esp to edi
|
||||
|
@ -265,7 +265,7 @@ test-next-token-from-slice-Eof:
|
|||
# . prologue
|
||||
55/push-ebp
|
||||
89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp
|
||||
# var out/edi : (address slice) = {0, 0}
|
||||
# var out/edi : (ref slice)
|
||||
68/push 0/imm32/end
|
||||
68/push 0/imm32/start
|
||||
89/copy 3/mod/direct 7/rm32/edi . . . 4/r32/esp . . # copy esp to edi
|
||||
|
@ -306,7 +306,7 @@ test-next-token-from-slice-nothing:
|
|||
8b/copy 0/mod/indirect 0/rm32/eax . . . 1/r32/ecx . . # copy *eax to ecx
|
||||
8d/copy-address 1/mod/*+disp8 4/rm32/sib 0/base/eax 1/index/ecx . 1/r32/ecx 4/disp8 . # copy eax+ecx+4 to ecx
|
||||
05/add-to-eax 4/imm32
|
||||
# var out/edi : (address slice) = {0, 0}
|
||||
# var out/edi : (ref slice)
|
||||
68/push 0/imm32/end
|
||||
68/push 0/imm32/start
|
||||
89/copy 3/mod/direct 7/rm32/edi . . . 4/r32/esp . . # copy esp to edi
|
||||
|
@ -338,7 +338,7 @@ test-next-token-from-slice-nothing:
|
|||
5d/pop-to-ebp
|
||||
c3/return
|
||||
|
||||
skip-chars-matching: # in : (address stream), delimiter : byte
|
||||
skip-chars-matching: # in : (address stream byte), delimiter : byte
|
||||
# . prologue
|
||||
55/push-ebp
|
||||
89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp
|
||||
|
@ -461,7 +461,7 @@ test-skip-chars-matching-none:
|
|||
# end
|
||||
c3/return
|
||||
|
||||
skip-chars-matching-whitespace: # in : (address stream)
|
||||
skip-chars-matching-whitespace: # in : (address stream byte)
|
||||
# . prologue
|
||||
55/push-ebp
|
||||
89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp
|
||||
|
@ -551,7 +551,7 @@ test-skip-chars-matching-whitespace:
|
|||
c3/return
|
||||
|
||||
# minor fork of 'skip-chars-matching'
|
||||
skip-chars-not-matching: # in : (address stream), delimiter : byte
|
||||
skip-chars-not-matching: # in : (address stream byte), delimiter : byte
|
||||
# . prologue
|
||||
55/push-ebp
|
||||
89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp
|
||||
|
@ -713,7 +713,7 @@ test-skip-chars-not-matching-all:
|
|||
# end
|
||||
c3/return
|
||||
|
||||
skip-chars-not-matching-whitespace: # in : (address stream)
|
||||
skip-chars-not-matching-whitespace: # in : (address stream byte)
|
||||
# . prologue
|
||||
55/push-ebp
|
||||
89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp
|
||||
|
@ -815,14 +815,15 @@ skip-chars-matching-in-slice: # curr : (address byte), end : (address byte), de
|
|||
8b/copy 1/mod/*+disp8 5/rm32/ebp . . . 1/r32/ecx 0xc/disp8 . # copy *(ebp+12) to ecx
|
||||
# edx = delimiter
|
||||
8b/copy 1/mod/*+disp8 5/rm32/ebp . . . 2/r32/edx 0x10/disp8 . # copy *(ebp+16) to edx
|
||||
# ebx = 0
|
||||
# var c/ebx : byte = 0
|
||||
31/xor 3/mod/direct 3/rm32/ebx . . . 3/r32/ebx . . # clear ebx
|
||||
$skip-chars-matching-in-slice:loop:
|
||||
# if (curr >= end) break
|
||||
39/compare 3/mod/direct 0/rm32/eax . . . 1/r32/ecx . . # compare eax with ecx
|
||||
73/jump-if-greater-or-equal-unsigned $skip-chars-matching-in-slice:end/disp8
|
||||
# if (*curr != delimiter) break
|
||||
# c = *curr
|
||||
8a/copy-byte 0/mod/indirect 0/rm32/eax . . . 3/r32/BL . . # copy byte at *eax to BL
|
||||
# if (c != delimiter) break
|
||||
39/compare 3/mod/direct 3/rm32/ebx . . . 2/r32/edx . . # compare ebx and edx
|
||||
75/jump-if-not-equal $skip-chars-matching-in-slice:end/disp8
|
||||
# ++curr
|
||||
|
@ -896,7 +897,7 @@ test-skip-chars-matching-in-slice-none:
|
|||
# end
|
||||
c3/return
|
||||
|
||||
skip-chars-matching-whitespace-in-slice: # in : (address stream)
|
||||
skip-chars-matching-whitespace-in-slice: # curr : (address byte), end : (address byte) -> curr/eax
|
||||
# . prologue
|
||||
55/push-ebp
|
||||
89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp
|
||||
|
@ -907,24 +908,24 @@ skip-chars-matching-whitespace-in-slice: # in : (address stream)
|
|||
8b/copy 1/mod/*+disp8 5/rm32/ebp . . . 0/r32/eax 8/disp8 . # copy *(ebp+8) to eax
|
||||
# ecx = end
|
||||
8b/copy 1/mod/*+disp8 5/rm32/ebp . . . 1/r32/ecx 0xc/disp8 . # copy *(ebp+12) to ecx
|
||||
# ebx = 0
|
||||
# var c/ebx : byte = 0
|
||||
31/xor 3/mod/direct 3/rm32/ebx . . . 3/r32/ebx . . # clear ebx
|
||||
$skip-chars-matching-whitespace-in-slice:loop:
|
||||
# if (curr >= end) break
|
||||
39/compare 3/mod/direct 0/rm32/eax . . . 1/r32/ecx . . # compare eax with ecx
|
||||
0f 83/jump-if-greater-or-equal-unsigned $skip-chars-matching-in-slice:end/disp32
|
||||
# ebx = *curr
|
||||
# c = *curr
|
||||
8a/copy-byte 0/mod/indirect 0/rm32/eax . . . 3/r32/BL . . # copy byte at *eax to BL
|
||||
# if (*curr == ' ') goto body
|
||||
# if (c == ' ') goto body
|
||||
81 7/subop/compare 3/mod/direct 3/rm32/ebx . . . . . 0x20/imm32/space # compare ebx
|
||||
74/jump-if-equal $skip-chars-matching-whitespace-in-slice:body/disp8
|
||||
# if (*curr == '\n') goto body
|
||||
# if (c == '\n') goto body
|
||||
81 7/subop/compare 3/mod/direct 3/rm32/ebx . . . . . 0x0a/imm32/newline # compare ebx
|
||||
74/jump-if-equal $skip-chars-matching-whitespace-in-slice:body/disp8
|
||||
# if (*curr == '\t') goto body
|
||||
# if (c == '\t') goto body
|
||||
81 7/subop/compare 3/mod/direct 3/rm32/ebx . . . . . 0x09/imm32/tab # compare ebx
|
||||
74/jump-if-equal $skip-chars-matching-whitespace-in-slice:body/disp8
|
||||
# if (*curr != '\r') break
|
||||
# if (c != '\r') break
|
||||
81 7/subop/compare 3/mod/direct 3/rm32/ebx . . . . . 0x0d/imm32/cr # compare ebx
|
||||
75/jump-if-not-equal $skip-chars-matching-whitespace-in-slice:end/disp8
|
||||
$skip-chars-matching-whitespace-in-slice:body:
|
||||
|
@ -983,14 +984,15 @@ skip-chars-not-matching-in-slice: # curr : (address byte), end : (address byte)
|
|||
8b/copy 1/mod/*+disp8 5/rm32/ebp . . . 1/r32/ecx 0xc/disp8 . # copy *(ebp+12) to ecx
|
||||
# edx = delimiter
|
||||
8b/copy 1/mod/*+disp8 5/rm32/ebp . . . 2/r32/edx 0x10/disp8 . # copy *(ebp+16) to edx
|
||||
# ebx = 0
|
||||
# var c/ebx : byte = 0
|
||||
31/xor 3/mod/direct 3/rm32/ebx . . . 3/r32/ebx . . # clear ebx
|
||||
$skip-chars-not-matching-in-slice:loop:
|
||||
# if (curr >= end) break
|
||||
39/compare 3/mod/direct 0/rm32/eax . . . 1/r32/ecx . . # compare eax with ecx
|
||||
73/jump-if-greater-or-equal-unsigned $skip-chars-not-matching-in-slice:end/disp8
|
||||
# if (*curr == delimiter) break
|
||||
# c = *curr
|
||||
8a/copy-byte 0/mod/indirect 0/rm32/eax . . . 3/r32/BL . . # copy byte at *eax to BL
|
||||
# if (c == delimiter) break
|
||||
39/compare 3/mod/direct 3/rm32/ebx . . . 2/r32/edx . . # compare ebx and edx
|
||||
74/jump-if-equal $skip-chars-not-matching-in-slice:end/disp8
|
||||
# ++curr
|
||||
|
@ -1093,7 +1095,7 @@ test-skip-chars-not-matching-in-slice-all:
|
|||
# end
|
||||
c3/return
|
||||
|
||||
skip-chars-not-matching-whitespace-in-slice: # in : (address stream)
|
||||
skip-chars-not-matching-whitespace-in-slice: # curr : (address byte), end : (address byte) -> curr/eax
|
||||
# . prologue
|
||||
55/push-ebp
|
||||
89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp
|
||||
|
@ -1104,24 +1106,24 @@ skip-chars-not-matching-whitespace-in-slice: # in : (address stream)
|
|||
8b/copy 1/mod/*+disp8 5/rm32/ebp . . . 0/r32/eax 8/disp8 . # copy *(ebp+8) to eax
|
||||
# ecx = end
|
||||
8b/copy 1/mod/*+disp8 5/rm32/ebp . . . 1/r32/ecx 0xc/disp8 . # copy *(ebp+12) to ecx
|
||||
# ebx = 0
|
||||
# var c/ebx : byte = 0
|
||||
31/xor 3/mod/direct 3/rm32/ebx . . . 3/r32/ebx . . # clear ebx
|
||||
$skip-chars-not-matching-whitespace-in-slice:loop:
|
||||
# if (curr >= end) break
|
||||
39/compare 3/mod/direct 0/rm32/eax . . . 1/r32/ecx . . # compare eax with ecx
|
||||
0f 83/jump-if-greater-or-equal-unsigned $skip-chars-not-matching-in-slice:end/disp32
|
||||
# ebx = *curr
|
||||
# c = *curr
|
||||
8a/copy-byte 0/mod/indirect 0/rm32/eax . . . 3/r32/BL . . # copy byte at *eax to BL
|
||||
# if (*curr == ' ') break
|
||||
# if (c == ' ') break
|
||||
81 7/subop/compare 3/mod/direct 3/rm32/ebx . . . . . 0x20/imm32/space # compare ebx
|
||||
74/jump-if-equal $skip-chars-not-matching-whitespace-in-slice:end/disp8
|
||||
# if (*curr == '\n') break
|
||||
# if (c == '\n') break
|
||||
81 7/subop/compare 3/mod/direct 3/rm32/ebx . . . . . 0x0a/imm32/newline # compare ebx
|
||||
74/jump-if-equal $skip-chars-not-matching-whitespace-in-slice:end/disp8
|
||||
# if (*curr == '\t') break
|
||||
# if (c == '\t') break
|
||||
81 7/subop/compare 3/mod/direct 3/rm32/ebx . . . . . 0x09/imm32/tab # compare ebx
|
||||
74/jump-if-equal $skip-chars-not-matching-whitespace-in-slice:end/disp8
|
||||
# if (*curr == '\r') break
|
||||
# if (c == '\r') break
|
||||
81 7/subop/compare 3/mod/direct 3/rm32/ebx . . . . . 0x0d/imm32/cr # compare ebx
|
||||
74/jump-if-equal $skip-chars-not-matching-whitespace-in-slice:end/disp8
|
||||
# ++curr
|
||||
|
@ -1166,7 +1168,7 @@ test-skip-chars-not-matching-whitespace-in-slice:
|
|||
|
||||
# update line->read to end of string literal surrounded by double quotes
|
||||
# line->read must start out at a double-quote
|
||||
skip-string: # line : (address stream)
|
||||
skip-string: # line : (address stream byte)
|
||||
# . prologue
|
||||
55/push-ebp
|
||||
89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp
|
||||
|
@ -1420,7 +1422,7 @@ skip-string-in-slice: # curr : (address byte), end : (address byte) -> new_curr
|
|||
8b/copy 1/mod/*+disp8 5/rm32/ebp . . 1/r32/ecx 8/disp8 . # copy *(ebp+8) to ecx
|
||||
# edx = end
|
||||
8b/copy 1/mod/*+disp8 5/rm32/ebp . . 2/r32/edx 0xc/disp8 . # copy *(ebp+12) to edx
|
||||
# eax = 0
|
||||
# var c/eax : byte = 0
|
||||
31/xor 3/mod/direct 0/rm32/eax . . . 0/r32/eax . . # clear eax
|
||||
# skip initial dquote
|
||||
41/increment-ecx
|
||||
|
@ -1428,14 +1430,14 @@ $skip-string-in-slice:loop:
|
|||
# if (curr >= end) return curr
|
||||
39/compare 3/mod/direct 1/rm32/ecx . . . 2/r32/edx . . # compare ecx with edx
|
||||
73/jump-if-greater-unsigned-or-equal $skip-string-in-slice:return-curr/disp8
|
||||
# AL = *curr
|
||||
# c = *curr
|
||||
8a/copy-byte 0/mod/indirect 1/rm32/ecx . . . 0/r32/AL . . # copy byte at *ecx to AL
|
||||
$skip-string-in-slice:dquote:
|
||||
# if (eax == '"') break
|
||||
# if (c == '"') break
|
||||
3d/compare-eax-and 0x22/imm32/double-quote
|
||||
74/jump-if-equal $skip-string-in-slice:break/disp8
|
||||
$skip-string-in-slice:check-for-escape:
|
||||
# if (eax == '\') escape next char
|
||||
# if (c == '\') escape next char
|
||||
3d/compare-eax-and 0x5c/imm32/backslash
|
||||
75/jump-if-not-equal $skip-string-in-slice:continue/disp8
|
||||
$skip-string-in-slice:escape:
|
||||
|
@ -1594,7 +1596,7 @@ test-skip-string-in-slice-stops-at-end:
|
|||
|
||||
# update line->read to ')'
|
||||
# line->read ends at ')'
|
||||
skip-until-close-paren: # line : (address stream)
|
||||
skip-until-close-paren: # line : (address stream byte)
|
||||
# . prologue
|
||||
55/push-ebp
|
||||
89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp
|
||||
|
@ -1781,7 +1783,7 @@ test-skip-until-close-paren-works-from-mid-stream:
|
|||
5d/pop-to-ebp
|
||||
c3/return
|
||||
|
||||
skip-until-close-paren-in-slice: # curr : (address byte), end : (address byte) -> new_curr/eax
|
||||
skip-until-close-paren-in-slice: # curr : (address byte), end : (address byte) -> new_curr/eax : (address byte)
|
||||
# . prologue
|
||||
55/push-ebp
|
||||
89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp
|
||||
|
@ -1792,7 +1794,7 @@ skip-until-close-paren-in-slice: # curr : (address byte), end : (address byte)
|
|||
8b/copy 1/mod/*+disp8 5/rm32/ebp . . 1/r32/ecx 8/disp8 . # copy *(ebp+8) to ecx
|
||||
# edx = end
|
||||
8b/copy 1/mod/*+disp8 5/rm32/ebp . . 2/r32/edx 0xc/disp8 . # copy *(ebp+12) to edx
|
||||
# eax = 0
|
||||
# var c/eax : byte = 0
|
||||
31/xor 3/mod/direct 0/rm32/eax . . . 0/r32/eax . . # clear eax
|
||||
# skip initial dquote
|
||||
41/increment-ecx
|
||||
|
@ -1800,10 +1802,10 @@ $skip-until-close-paren-in-slice:loop:
|
|||
# if (curr >= end) break
|
||||
39/compare 3/mod/direct 1/rm32/ecx . . . 2/r32/edx . . # compare ecx with edx
|
||||
73/jump-if-greater-unsigned-or-equal $skip-until-close-paren-in-slice:break/disp8
|
||||
# AL = *curr
|
||||
# c = *curr
|
||||
8a/copy-byte 0/mod/indirect 1/rm32/ecx . . . 0/r32/AL . . # copy byte at *ecx to AL
|
||||
$skip-until-close-paren-in-slice:check-close:
|
||||
# if (eax == ')') break
|
||||
# if (c == ')') break
|
||||
3d/compare-eax-and 0x29/imm32/close-paren
|
||||
74/jump-if-equal $skip-until-close-paren-in-slice:break/disp8
|
||||
# ++curr
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
# - construct a 'maximal slice' and pass it to write-slice-buffered
|
||||
# - flush the buffered-file and pass the stream directly to its fd (disabling buffering)
|
||||
# we'll go with the first way for now
|
||||
write-stream-data: # f : (address buffered-file), s : (address stream)
|
||||
write-stream-data: # f : (address buffered-file), s : (address stream byte)
|
||||
# . prologue
|
||||
55/push-ebp
|
||||
89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp
|
||||
|
@ -18,8 +18,8 @@ write-stream-data: # f : (address buffered-file), s : (address stream)
|
|||
56/push-esi
|
||||
# esi = s
|
||||
8b/copy 1/mod/*+disp8 5/rm32/ebp . . . 6/r32/esi 0xc/disp8 . # copy *(ebp+12) to esi
|
||||
# var slice/ecx = {s->data, s->data + s->write}
|
||||
# . push s->data + s->write
|
||||
# var slice/ecx : (ref slice) = {s->data, &s->data[s->write]}
|
||||
# . push &s->data[s->write]
|
||||
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
|
||||
50/push-eax
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
# . 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
|
||||
|
||||
print-int32-decimal: # out : (address stream), n : int32
|
||||
print-int32-decimal: # out : (address stream byte), n : int32
|
||||
# works by generating characters from lowest to highest and pushing them
|
||||
# to the stack, before popping them one by one into the stream
|
||||
#
|
||||
|
@ -44,11 +44,11 @@ print-int32-decimal: # out : (address stream), n : int32
|
|||
52/push-edx
|
||||
53/push-ebx
|
||||
57/push-edi
|
||||
# ten/ecx = 10
|
||||
# const ten/ecx = 10
|
||||
b9/copy-to-ecx 0xa/imm32
|
||||
# push sentinel
|
||||
68/push 0/imm32/sentinel
|
||||
# eax = abs(n)
|
||||
# var eax : int = abs(n)
|
||||
8b/copy 1/mod/*+disp8 5/rm32/ebp . . . 0/r32/eax 0xc/disp8 . # copy *(ebp+12) to eax
|
||||
3d/compare-eax-with 0/imm32
|
||||
7d/jump-if-greater-or-equal $print-int32-decimal:read-loop/disp8
|
||||
|
@ -74,11 +74,11 @@ $print-int32-decimal:push-negative:
|
|||
$print-int32-decimal:write:
|
||||
# edi = out
|
||||
8b/copy 1/mod/*+disp8 5/rm32/ebp . . . 7/r32/edi 8/disp8 . # copy *(ebp+8) to edi
|
||||
# w/edx = out->write
|
||||
# var w/edx : int = out->write
|
||||
8b/copy 0/mod/indirect 7/rm32/edi . . . 2/r32/edx . . # copy *edi to edx
|
||||
# curr/ecx = &out->data[out->write]
|
||||
# var curr/ecx : (address 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
|
||||
# max/ebx = &out->data[out->length]
|
||||
# var max/ebx : (address byte) = &out->data[out->length]
|
||||
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
|
||||
$print-int32-decimal:write-loop:
|
||||
|
|
|
@ -35,7 +35,7 @@ $next-word:check0:
|
|||
# . if (eax < line->write) goto next check
|
||||
3b/compare 0/mod/indirect 6/rm32/esi . . . 0/r32/eax . . # compare eax with *esi
|
||||
7c/jump-if-lesser $next-word:check-for-comment/disp8
|
||||
# . return out = {0, 0}
|
||||
# . return out
|
||||
c7 0/subop/copy 0/mod/direct 7/rm32/edi . . . . . 0/imm32 # copy to *edi
|
||||
c7 0/subop/copy 1/mod/*+disp8 7/rm32/edi . . . . 4/disp8 0/imm32 # copy to *(edi+4)
|
||||
eb/jump $next-word:end/disp8
|
||||
|
@ -95,7 +95,7 @@ test-next-word:
|
|||
e8/call clear-stream/disp32
|
||||
# . . discard args
|
||||
81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp
|
||||
# var slice/ecx = {0, 0}
|
||||
# var slice/ecx : (ref slice)
|
||||
68/push 0/imm32/end
|
||||
68/push 0/imm32/start
|
||||
89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx
|
||||
|
@ -158,7 +158,7 @@ test-next-word-returns-whole-comment:
|
|||
e8/call clear-stream/disp32
|
||||
# . . discard args
|
||||
81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp
|
||||
# var slice/ecx = {0, 0}
|
||||
# var slice/ecx : (ref slice)
|
||||
68/push 0/imm32/end
|
||||
68/push 0/imm32/start
|
||||
89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx
|
||||
|
@ -221,7 +221,7 @@ test-next-word-returns-empty-string-on-eof:
|
|||
e8/call clear-stream/disp32
|
||||
# . . discard args
|
||||
81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp
|
||||
# var slice/ecx = {0, 0}
|
||||
# var slice/ecx : (ref slice)
|
||||
68/push 0/imm32/end
|
||||
68/push 0/imm32/start
|
||||
89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx
|
||||
|
|
|
@ -25,9 +25,9 @@ has-metadata?: # word : (address slice), s : (address string) -> eax : boolean
|
|||
57/push-edi
|
||||
# esi = word
|
||||
8b/copy 1/mod/*+disp8 5/rm32/ebp . . . 6/r32/esi 8/disp8 . # copy *(ebp+8) to esi
|
||||
# edx = word->end
|
||||
# var edx : (address byte) = word->end
|
||||
8b/copy 1/mod/*+disp8 6/rm32/esi . . . 2/r32/edx 4/disp8 . # copy *(esi+4) to edx
|
||||
# var twig/edi : (address slice) = {0, 0}
|
||||
# var twig/edi : (ref slice)
|
||||
68/push 0/imm32/end
|
||||
68/push 0/imm32/start
|
||||
89/copy 3/mod/direct 7/rm32/edi . . . 4/r32/esp . . # copy esp to edi
|
||||
|
@ -41,15 +41,13 @@ has-metadata?: # word : (address slice), s : (address string) -> eax : boolean
|
|||
e8/call next-token-from-slice/disp32
|
||||
# . . discard args
|
||||
81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0x10/imm32 # add to esp
|
||||
# curr/ecx = twig->end
|
||||
8b/copy 1/mod/*+disp8 7/rm32/edi . . . 1/r32/ecx 4/disp8 . # copy *(edi+4) to ecx
|
||||
$has-metadata?:loop:
|
||||
# next-token-from-slice(curr, word->end, '/', twig)
|
||||
# . . push args
|
||||
57/push-edi
|
||||
68/push 0x2f/imm32/slash
|
||||
52/push-edx
|
||||
51/push-ecx
|
||||
ff 6/subop/push 1/mod/*+disp8 7/rm32/edi . . . . 4/disp8 . # push *(edi+4)
|
||||
# . . call
|
||||
e8/call next-token-from-slice/disp32
|
||||
# . . discard args
|
||||
|
@ -62,8 +60,8 @@ $has-metadata?:loop:
|
|||
e8/call slice-empty?/disp32
|
||||
# . . discard args
|
||||
81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp
|
||||
# . if (eax != 0) return false
|
||||
3d/compare-eax-and 0/imm32
|
||||
# . if (eax != false) return false
|
||||
3d/compare-eax-and 0/imm32/false
|
||||
75/jump-if-not-equal $has-metadata?:false/disp8
|
||||
# if (slice-equal?(twig, s)) return true
|
||||
# . eax = slice-equal?(twig, s)
|
||||
|
@ -74,15 +72,11 @@ $has-metadata?:loop:
|
|||
e8/call slice-equal?/disp32
|
||||
# . . discard args
|
||||
81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp
|
||||
# . if (eax != 0) return true
|
||||
3d/compare-eax-and 0/imm32
|
||||
75/jump-if-not-equal $has-metadata?:true/disp8
|
||||
# curr = twig->end
|
||||
8b/copy 1/mod/*+disp8 7/rm32/edi . . . 1/r32/ecx 4/disp8 . # copy *(edi+4) to ecx
|
||||
# . if (eax != false) return true
|
||||
3d/compare-eax-and 0/imm32/false
|
||||
# eax already contains true
|
||||
75/jump-if-not-equal $has-metadata?:end/disp8
|
||||
eb/jump $has-metadata?:loop/disp8
|
||||
$has-metadata?:true:
|
||||
b8/copy-to-eax 1/imm32/true
|
||||
eb/jump $has-metadata?:end/disp8
|
||||
$has-metadata?:false:
|
||||
b8/copy-to-eax 0/imm32/false
|
||||
$has-metadata?:end:
|
||||
|
@ -107,7 +101,7 @@ test-has-metadata-true:
|
|||
8b/copy 0/mod/indirect 0/rm32/eax . . . 1/r32/ecx . . # copy *eax to ecx
|
||||
8d/copy-address 1/mod/*+disp8 4/rm32/sib 0/base/eax 1/index/ecx . 1/r32/ecx 4/disp8 . # copy eax+ecx+4 to ecx
|
||||
05/add-to-eax 4/imm32
|
||||
# var in/esi : (address slice) = {eax, ecx}
|
||||
# var in/esi : (ref slice) = {eax, ecx}
|
||||
51/push-ecx
|
||||
50/push-eax
|
||||
89/copy 3/mod/direct 6/rm32/esi . . . 4/r32/esp . . # copy esp to esi
|
||||
|
@ -142,7 +136,7 @@ test-has-metadata-false:
|
|||
8b/copy 0/mod/indirect 0/rm32/eax . . . 1/r32/ecx . . # copy *eax to ecx
|
||||
8d/copy-address 1/mod/*+disp8 4/rm32/sib 0/base/eax 1/index/ecx . 1/r32/ecx 4/disp8 . # copy eax+ecx+4 to ecx
|
||||
05/add-to-eax 4/imm32
|
||||
# var in/esi : (address slice) = {eax, ecx}
|
||||
# var in/esi : (ref slice) = {eax, ecx}
|
||||
51/push-ecx
|
||||
50/push-eax
|
||||
89/copy 3/mod/direct 6/rm32/esi . . . 4/r32/esp . . # copy esp to esi
|
||||
|
@ -177,7 +171,7 @@ test-has-metadata-ignore-name:
|
|||
8b/copy 0/mod/indirect 0/rm32/eax . . . 1/r32/ecx . . # copy *eax to ecx
|
||||
8d/copy-address 1/mod/*+disp8 4/rm32/sib 0/base/eax 1/index/ecx . 1/r32/ecx 4/disp8 . # copy eax+ecx+4 to ecx
|
||||
05/add-to-eax 4/imm32
|
||||
# var in/esi : (address slice) = {eax, ecx}
|
||||
# var in/esi : (ref slice) = {eax, ecx}
|
||||
51/push-ecx
|
||||
50/push-eax
|
||||
89/copy 3/mod/direct 6/rm32/esi . . . 4/r32/esp . . # copy esp to esi
|
||||
|
@ -212,7 +206,7 @@ test-has-metadata-multiple-true:
|
|||
8b/copy 0/mod/indirect 0/rm32/eax . . . 1/r32/ecx . . # copy *eax to ecx
|
||||
8d/copy-address 1/mod/*+disp8 4/rm32/sib 0/base/eax 1/index/ecx . 1/r32/ecx 4/disp8 . # copy eax+ecx+4 to ecx
|
||||
05/add-to-eax 4/imm32
|
||||
# var in/esi : (address slice) = {eax, ecx}
|
||||
# var in/esi : (ref slice) = {eax, ecx}
|
||||
51/push-ecx
|
||||
50/push-eax
|
||||
89/copy 3/mod/direct 6/rm32/esi . . . 4/r32/esp . . # copy esp to esi
|
||||
|
@ -247,7 +241,7 @@ test-has-metadata-multiple-false:
|
|||
8b/copy 0/mod/indirect 0/rm32/eax . . . 1/r32/ecx . . # copy *eax to ecx
|
||||
8d/copy-address 1/mod/*+disp8 4/rm32/sib 0/base/eax 1/index/ecx . 1/r32/ecx 4/disp8 . # copy eax+ecx+4 to ecx
|
||||
05/add-to-eax 4/imm32
|
||||
# var in/esi : (address slice) = {eax, ecx}
|
||||
# var in/esi : (ref slice) = {eax, ecx}
|
||||
51/push-ecx
|
||||
50/push-eax
|
||||
89/copy 3/mod/direct 6/rm32/esi . . . 4/r32/esp . . # copy esp to esi
|
||||
|
@ -290,22 +284,21 @@ is-valid-name?: # in : (address slice) -> eax : boolean
|
|||
56/push-esi
|
||||
# esi = in
|
||||
8b/copy 1/mod/*+disp8 5/rm32/ebp . . . 6/r32/esi 8/disp8 . # copy *(ebp+8) to esi
|
||||
# start/ecx = in->start
|
||||
# var start/ecx : (address byte) = in->start
|
||||
8b/copy 0/mod/indirect 6/rm32/esi . . . 1/r32/ecx . . # copy *esi to ecx
|
||||
# end/eax = in->end
|
||||
8b/copy 1/mod/*+disp8 6/rm32/esi . . . 0/r32/eax 4/disp8 . # copy *(esi+4) to eax
|
||||
$is-valid-name?:check0:
|
||||
# if (start >= end) return false
|
||||
39/compare 3/mod/direct 1/rm32/ecx . . . 0/r32/eax . . # compare ecx with eax
|
||||
# if (start >= in->end) return false
|
||||
3b/compare 1/mod/*+disp8 6/rm32/esi . . . 1/r32/ecx 4/disp8 . # compare ecx with *(esi+4)
|
||||
73/jump-if-greater-or-equal-unsigned $is-valid-name?:false/disp8
|
||||
$is-valid-name?:check1:
|
||||
# eax -= ecx
|
||||
# var len/eax : int = in->end - start
|
||||
8b/copy 1/mod/*+disp8 6/rm32/esi . . . 0/r32/eax 4/disp8 . # copy *(esi+4) to eax
|
||||
29/subtract 3/mod/direct 0/rm32/eax . . . 1/r32/ecx . . # subtract ecx from eax
|
||||
# if (eax == 2) return false
|
||||
3d/compare-eax-and 2/imm32
|
||||
74/jump-if-equal $is-valid-name?:false/disp8
|
||||
$is-valid-name?:check2:
|
||||
# c/eax = *ecx
|
||||
# var c/eax : (address byte) = *start
|
||||
31/xor 3/mod/direct 0/rm32/eax . . . 0/r32/eax . . # clear eax
|
||||
8a/copy-byte 0/mod/indirect 1/rm32/ecx . . . 0/r32/AL . . # copy byte at *ecx to AL
|
||||
# if (c == "-") return false
|
||||
|
@ -344,7 +337,7 @@ test-is-valid-name-digit-prefix:
|
|||
8b/copy 0/mod/indirect 0/rm32/eax . . . 1/r32/ecx . . # copy *eax to ecx
|
||||
8d/copy-address 1/mod/*+disp8 4/rm32/sib 0/base/eax 1/index/ecx . 1/r32/ecx 4/disp8 . # copy eax+ecx+4 to ecx
|
||||
05/add-to-eax 4/imm32
|
||||
# var slice/ecx = {eax, ecx}
|
||||
# var slice/ecx : (ref slice) = {eax, ecx}
|
||||
51/push-ecx
|
||||
50/push-eax
|
||||
89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx
|
||||
|
@ -378,7 +371,7 @@ test-is-valid-name-negative-prefix:
|
|||
8b/copy 0/mod/indirect 0/rm32/eax . . . 1/r32/ecx . . # copy *eax to ecx
|
||||
8d/copy-address 1/mod/*+disp8 4/rm32/sib 0/base/eax 1/index/ecx . 1/r32/ecx 4/disp8 . # copy eax+ecx+4 to ecx
|
||||
05/add-to-eax 4/imm32
|
||||
# var slice/ecx = {eax, ecx}
|
||||
# var slice/ecx : (ref slice) = {eax, ecx}
|
||||
51/push-ecx
|
||||
50/push-eax
|
||||
89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx
|
||||
|
@ -412,7 +405,7 @@ test-is-valid-name-0x-prefix:
|
|||
8b/copy 0/mod/indirect 0/rm32/eax . . . 1/r32/ecx . . # copy *eax to ecx
|
||||
8d/copy-address 1/mod/*+disp8 4/rm32/sib 0/base/eax 1/index/ecx . 1/r32/ecx 4/disp8 . # copy eax+ecx+4 to ecx
|
||||
05/add-to-eax 4/imm32
|
||||
# var slice/ecx = {eax, ecx}
|
||||
# var slice/ecx : (ref slice) = {eax, ecx}
|
||||
51/push-ecx
|
||||
50/push-eax
|
||||
89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx
|
||||
|
@ -446,7 +439,7 @@ test-is-valid-name-starts-with-pre-digit:
|
|||
8b/copy 0/mod/indirect 0/rm32/eax . . . 1/r32/ecx . . # copy *eax to ecx
|
||||
8d/copy-address 1/mod/*+disp8 4/rm32/sib 0/base/eax 1/index/ecx . 1/r32/ecx 4/disp8 . # copy eax+ecx+4 to ecx
|
||||
05/add-to-eax 4/imm32
|
||||
# var slice/ecx = {eax, ecx}
|
||||
# var slice/ecx : (ref slice) = {eax, ecx}
|
||||
51/push-ecx
|
||||
50/push-eax
|
||||
89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx
|
||||
|
@ -480,7 +473,7 @@ test-is-valid-name-starts-with-post-digit:
|
|||
8b/copy 0/mod/indirect 0/rm32/eax . . . 1/r32/ecx . . # copy *eax to ecx
|
||||
8d/copy-address 1/mod/*+disp8 4/rm32/sib 0/base/eax 1/index/ecx . 1/r32/ecx 4/disp8 . # copy eax+ecx+4 to ecx
|
||||
05/add-to-eax 4/imm32
|
||||
# var slice/ecx = {eax, ecx}
|
||||
# var slice/ecx : (ref slice) = {eax, ecx}
|
||||
51/push-ecx
|
||||
50/push-eax
|
||||
89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx
|
||||
|
@ -514,7 +507,7 @@ test-is-valid-name-starts-with-digit:
|
|||
8b/copy 0/mod/indirect 0/rm32/eax . . . 1/r32/ecx . . # copy *eax to ecx
|
||||
8d/copy-address 1/mod/*+disp8 4/rm32/sib 0/base/eax 1/index/ecx . 1/r32/ecx 4/disp8 . # copy eax+ecx+4 to ecx
|
||||
05/add-to-eax 4/imm32
|
||||
# var slice/ecx = {eax, ecx}
|
||||
# var slice/ecx : (ref slice) = {eax, ecx}
|
||||
51/push-ecx
|
||||
50/push-eax
|
||||
89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx
|
||||
|
@ -547,12 +540,11 @@ is-label?: # word : (address slice) -> eax : boolean
|
|||
51/push-ecx
|
||||
# ecx = word
|
||||
8b/copy 1/mod/*+disp8 5/rm32/ebp . . . 1/r32/ecx 8/disp8 . # copy *(ebp+8) to ecx
|
||||
# ecx = word->end
|
||||
# var end/ecx : (address byte) = word->end
|
||||
8b/copy 1/mod/*+disp8 1/rm32/ecx . . . 1/r32/ecx 4/disp8 . # copy *(ecx+4) to ecx
|
||||
# return *(word->end - 1) == ':'
|
||||
# . eax = 0
|
||||
# return *(end - 1) == ':'
|
||||
# . eax = *(end-1)
|
||||
31/xor 3/mod/direct 0/rm32/eax . . . 0/r32/eax . . # clear eax
|
||||
# . eax = *((char *) word->end - 1)
|
||||
8a/copy-byte 1/mod/*+disp8 1/rm32/ecx . . . 0/r32/AL -1/disp8 . # copy byte at *(ecx-1) to AL
|
||||
# . return (eax == ':')
|
||||
3d/compare-eax-and 0x3a/imm32/colon
|
||||
|
@ -577,7 +569,7 @@ $test-is-label?:true:
|
|||
8b/copy 0/mod/indirect 0/rm32/eax . . . 1/r32/ecx . . # copy *eax to ecx
|
||||
8d/copy-address 1/mod/*+disp8 4/rm32/sib 0/base/eax 1/index/ecx . 1/r32/ecx 4/disp8 . # copy eax+ecx+4 to ecx
|
||||
05/add-to-eax 4/imm32
|
||||
# var slice/ecx = {eax, ecx}
|
||||
# var slice/ecx : (ref slice) = {eax, ecx}
|
||||
51/push-ecx
|
||||
50/push-eax
|
||||
89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx
|
||||
|
@ -603,7 +595,7 @@ $test-is-label?:false:
|
|||
8b/copy 0/mod/indirect 0/rm32/eax . . . 1/r32/ecx . . # copy *eax to ecx
|
||||
8d/copy-address 1/mod/*+disp8 4/rm32/sib 0/base/eax 1/index/ecx . 1/r32/ecx 4/disp8 . # copy eax+ecx+4 to ecx
|
||||
05/add-to-eax 4/imm32
|
||||
# var slice/ecx = {eax, ecx}
|
||||
# var slice/ecx : (ref slice) = {eax, ecx}
|
||||
51/push-ecx
|
||||
50/push-eax
|
||||
89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx
|
||||
|
|
|
@ -20,13 +20,13 @@ emit-hex: # out : (address buffered-file), n : int, width : int
|
|||
8b/copy 1/mod/*+disp8 5/rm32/ebp . . . 3/r32/ebx 0xc/disp8 . # copy *(ebp+12) to ebx
|
||||
# edx = width
|
||||
8b/copy 1/mod/*+disp8 5/rm32/ebp . . . 2/r32/edx 0x10/disp8 . # copy *(ebp+16) to edx
|
||||
# var curr/ecx = 0
|
||||
# var curr/ecx : int = 0
|
||||
31/xor 3/mod/direct 1/rm32/ecx . . . 1/r32/ecx . . # clear ecx
|
||||
$emit-hex:loop:
|
||||
# if (curr >= width) break
|
||||
39/compare 3/mod/direct 1/rm32/ecx . . . 2/r32/edx . . # compare ecx with edx
|
||||
7d/jump-if-greater-or-equal $emit-hex:end/disp8
|
||||
# print-byte-buffered(out, ebx)
|
||||
# print-byte-buffered(out, ebx) # only BL used
|
||||
# . . push args
|
||||
53/push-ebx
|
||||
57/push-edi
|
||||
|
|
26
079emit.subx
26
079emit.subx
|
@ -17,7 +17,7 @@ emit: # out : (address buffered-file), word : (address slice), width : int
|
|||
57/push-edi
|
||||
# esi = word
|
||||
8b/copy 1/mod/*+disp8 5/rm32/ebp . . . 6/r32/esi 0xc/disp8 . # copy *(ebp+12) to esi
|
||||
# var name/edi : (address slice) = {0, 0}
|
||||
# var datum/edi : (ref slice)
|
||||
68/push 0/imm32/end
|
||||
68/push 0/imm32/start
|
||||
89/copy 3/mod/direct 7/rm32/edi . . . 4/r32/esp . . # copy esp to edi
|
||||
|
@ -39,8 +39,8 @@ emit: # out : (address buffered-file), word : (address slice), width : int
|
|||
e8/call is-valid-name?/disp32
|
||||
# . . discard args
|
||||
81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp
|
||||
# . if (eax != 0)
|
||||
3d/compare-eax-and 0/imm32
|
||||
# . if (eax != false)
|
||||
3d/compare-eax-and 0/imm32/false
|
||||
74/jump-if-equal $emit:hex-int/disp8
|
||||
$emit:name:
|
||||
# . write-slice-buffered(out, word)
|
||||
|
@ -63,11 +63,11 @@ $emit:name:
|
|||
eb/jump $emit:end/disp8
|
||||
# otherwise emit-hex(out, parse-hex-int(datum), width)
|
||||
# (Weird shit can happen here if the datum of 'word' isn't either a valid
|
||||
# name or a hex number, but we're only going to be passing in real legal
|
||||
# programs. We just want to make sure that valid names aren't treated as
|
||||
# (valid) hex numbers.)
|
||||
# name or a hex number. `emit` is mostly used by ntranslate, which is
|
||||
# currently designed to only receive legal SubX programs. We just want to
|
||||
# make sure that valid names aren't treated as (valid) hex numbers.)
|
||||
$emit:hex-int:
|
||||
# . value/eax = parse-hex-int(datum)
|
||||
# . var value/eax : int = parse-hex-int(datum)
|
||||
# . . push args
|
||||
57/push-edi
|
||||
# . . call
|
||||
|
@ -119,7 +119,7 @@ test-emit-number:
|
|||
8b/copy 0/mod/indirect 0/rm32/eax . . . 1/r32/ecx . . # copy *eax to ecx
|
||||
8d/copy-address 1/mod/*+disp8 4/rm32/sib 0/base/eax 1/index/ecx . 1/r32/ecx 4/disp8 . # copy eax+ecx+4 to ecx
|
||||
05/add-to-eax 4/imm32
|
||||
# var slice/ecx = {eax, ecx}
|
||||
# var slice/ecx : (ref slice) = {eax, ecx}
|
||||
51/push-ecx
|
||||
50/push-eax
|
||||
89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx
|
||||
|
@ -178,7 +178,7 @@ test-emit-negative-number:
|
|||
8b/copy 0/mod/indirect 0/rm32/eax . . . 1/r32/ecx . . # copy *eax to ecx
|
||||
8d/copy-address 1/mod/*+disp8 4/rm32/sib 0/base/eax 1/index/ecx . 1/r32/ecx 4/disp8 . # copy eax+ecx+4 to ecx
|
||||
05/add-to-eax 4/imm32
|
||||
# var slice/ecx = {eax, ecx}
|
||||
# var slice/ecx : (ref slice) = {eax, ecx}
|
||||
51/push-ecx
|
||||
50/push-eax
|
||||
89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx
|
||||
|
@ -236,7 +236,7 @@ test-emit-number-with-metadata:
|
|||
8b/copy 0/mod/indirect 0/rm32/eax . . . 1/r32/ecx . . # copy *eax to ecx
|
||||
8d/copy-address 1/mod/*+disp8 4/rm32/sib 0/base/eax 1/index/ecx . 1/r32/ecx 4/disp8 . # copy eax+ecx+4 to ecx
|
||||
05/add-to-eax 4/imm32
|
||||
# var slice/ecx = {eax, ecx}
|
||||
# var slice/ecx : (ref slice) = {eax, ecx}
|
||||
51/push-ecx
|
||||
50/push-eax
|
||||
89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx
|
||||
|
@ -295,7 +295,7 @@ test-emit-non-number:
|
|||
8b/copy 0/mod/indirect 0/rm32/eax . . . 1/r32/ecx . . # copy *eax to ecx
|
||||
8d/copy-address 1/mod/*+disp8 4/rm32/sib 0/base/eax 1/index/ecx . 1/r32/ecx 4/disp8 . # copy eax+ecx+4 to ecx
|
||||
05/add-to-eax 4/imm32
|
||||
# var slice/ecx = {eax, ecx}
|
||||
# var slice/ecx : (ref slice) = {eax, ecx}
|
||||
51/push-ecx
|
||||
50/push-eax
|
||||
89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx
|
||||
|
@ -353,7 +353,7 @@ test-emit-non-number-with-metadata:
|
|||
8b/copy 0/mod/indirect 0/rm32/eax . . . 1/r32/ecx . . # copy *eax to ecx
|
||||
8d/copy-address 1/mod/*+disp8 4/rm32/sib 0/base/eax 1/index/ecx . 1/r32/ecx 4/disp8 . # copy eax+ecx+4 to ecx
|
||||
05/add-to-eax 4/imm32
|
||||
# var slice/ecx = {eax, ecx}
|
||||
# var slice/ecx : (ref slice) = {eax, ecx}
|
||||
51/push-ecx
|
||||
50/push-eax
|
||||
89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx
|
||||
|
@ -411,7 +411,7 @@ test-emit-non-number-with-all-hex-digits-and-metadata:
|
|||
8b/copy 0/mod/indirect 0/rm32/eax . . . 1/r32/ecx . . # copy *eax to ecx
|
||||
8d/copy-address 1/mod/*+disp8 4/rm32/sib 0/base/eax 1/index/ecx . 1/r32/ecx 4/disp8 . # copy eax+ecx+4 to ecx
|
||||
05/add-to-eax 4/imm32
|
||||
# var slice/ecx = {eax, ecx}
|
||||
# var slice/ecx : (ref slice) = {eax, ecx}
|
||||
51/push-ecx
|
||||
50/push-eax
|
||||
89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
# . 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
|
||||
|
||||
zero-out: # start : address, len : int
|
||||
zero-out: # start : (address byte), len : int
|
||||
# pseudocode:
|
||||
# curr/esi = start
|
||||
# i/ecx = 0
|
||||
|
@ -25,7 +25,7 @@ zero-out: # start : address, len : int
|
|||
56/push-esi
|
||||
# curr/esi = start
|
||||
8b/copy 1/mod/*+disp8 5/rm32/ebp . . . 6/r32/esi 8/disp8 . # copy *(ebp+8) to esi
|
||||
# i/ecx = 0
|
||||
# var i/ecx : int = 0
|
||||
31/xor 3/mod/direct 1/rm32/ecx . . . 1/r32/ecx . . # clear ecx
|
||||
# edx = len
|
||||
8b/copy 1/mod/*+disp8 5/rm32/ebp . . . 2/r32/edx 0xc/disp8 . # copy *(ebp+12) to edx
|
||||
|
|
123
081table.subx
123
081table.subx
|
@ -1,7 +1,7 @@
|
|||
# A table is a stream of (key, value) rows.
|
||||
#
|
||||
# Each row consists of a 4-byte key (address to a string) and a variable-size
|
||||
# value.
|
||||
# Each row consists of a 4-byte key -- a 'string_key' which is (address array
|
||||
# byte) -- and a variable-size value.
|
||||
#
|
||||
# Accessing the table performs a linear scan for a key string, and always
|
||||
# requires passing in the row size.
|
||||
|
@ -23,7 +23,8 @@
|
|||
# . 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
|
||||
|
||||
# if no row is found, abort
|
||||
get: # table : (address stream {string, _}), key : (address string), row-size : int, abort-message-prefix : (address string) -> eax : (address _)
|
||||
# type string_key = (address array byte)
|
||||
get: # table : (address stream {string_key, T}), key : string_key, row-size : int, abort-message-prefix : (address array byte) -> eax : (address T)
|
||||
# pseudocode:
|
||||
# curr = table->data
|
||||
# max = &table->data[table->write]
|
||||
|
@ -42,9 +43,9 @@ get: # table : (address stream {string, _}), key : (address string), row-size :
|
|||
56/push-esi
|
||||
# esi = table
|
||||
8b/copy 1/mod/*+disp8 5/rm32/ebp . . . 6/r32/esi 8/disp8 . # copy *(ebp+8) to esi
|
||||
# curr/ecx = table->data
|
||||
# var curr/ecx : (address string_key) = table->data
|
||||
8d/copy-address 1/mod/*+disp8 6/rm32/esi . . . 1/r32/ecx 0xc/disp8 . # copy esi+12 to ecx
|
||||
# max/edx = table->data + table->write
|
||||
# var max/edx : (address byte) = &table->data[table->write]
|
||||
8b/copy 0/mod/indirect 6/rm32/esi . . . 2/r32/edx . . # copy *esi to edx
|
||||
8d/copy-address 0/mod/indirect 4/rm32/sib 1/base/ecx 2/index/edx . 2/r32/edx . . # copy ecx+edx to edx
|
||||
$get:search-loop:
|
||||
|
@ -60,8 +61,8 @@ $get:search-loop:
|
|||
e8/call string-equal?/disp32
|
||||
# . . discard args
|
||||
81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp
|
||||
# . if (eax != 0) return eax = curr+4
|
||||
3d/compare-eax-and 0/imm32
|
||||
# . if (eax != false) return eax = curr+4
|
||||
3d/compare-eax-and 0/imm32/false
|
||||
74/jump-if-equal $get:mismatch/disp8
|
||||
8d/copy-address 1/mod/*+disp8 1/rm32/ecx . . . 0/r32/eax 4/disp8 . # copy ecx+4 to eax
|
||||
eb/jump $get:end/disp8
|
||||
|
@ -124,7 +125,7 @@ test-get:
|
|||
55/push-ebp
|
||||
89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp
|
||||
# - setup: create a table with a couple of keys
|
||||
# var table/ecx : (address stream {string, number}) = stream(2 rows * 8 bytes)
|
||||
# var table/ecx : (ref stream {string, number} 16) # 2 rows * 8 bytes/row
|
||||
81 5/subop/subtract 3/mod/direct 4/rm32/esp . . . . . 0x10/imm32 # subtract from esp
|
||||
68/push 0x10/imm32/length
|
||||
68/push 0/imm32/read
|
||||
|
@ -197,7 +198,7 @@ $test-get:end:
|
|||
c3/return
|
||||
|
||||
# if no row is found, abort
|
||||
get-slice: # table : (address stream {string, _}), key : (address slice), row-size : int, abort-message-prefix : (address string) -> eax : (address _)
|
||||
get-slice: # table : (address stream {string_key, T}), key : (address slice), row-size : int, abort-message-prefix : (address array byte) -> eax : (address T)
|
||||
# pseudocode:
|
||||
# curr = table->data
|
||||
# max = &table->data[table->write]
|
||||
|
@ -216,9 +217,9 @@ get-slice: # table : (address stream {string, _}), key : (address slice), row-s
|
|||
56/push-esi
|
||||
# esi = table
|
||||
8b/copy 1/mod/*+disp8 5/rm32/ebp . . . 6/r32/esi 8/disp8 . # copy *(ebp+8) to esi
|
||||
# curr/ecx = table->data
|
||||
# var curr/ecx : (address string_key) = table->data
|
||||
8d/copy-address 1/mod/*+disp8 6/rm32/esi . . . 1/r32/ecx 0xc/disp8 . # copy esi+12 to ecx
|
||||
# max/edx = table->data + table->write
|
||||
# var max/edx : (address byte) = &table->data[table->write]
|
||||
8b/copy 0/mod/indirect 6/rm32/esi . . . 2/r32/edx . . # copy *esi to edx
|
||||
8d/copy-address 0/mod/indirect 4/rm32/sib 1/base/ecx 2/index/edx . 2/r32/edx . . # copy ecx+edx to edx
|
||||
$get-slice:search-loop:
|
||||
|
@ -234,8 +235,8 @@ $get-slice:search-loop:
|
|||
e8/call slice-equal?/disp32
|
||||
# . . discard args
|
||||
81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp
|
||||
# . if (eax != 0) return eax = curr+4
|
||||
3d/compare-eax-and 0/imm32
|
||||
# . if (eax != false) return eax = curr+4
|
||||
3d/compare-eax-and 0/imm32/false
|
||||
74/jump-if-equal $get-slice:mismatch/disp8
|
||||
8d/copy-address 1/mod/*+disp8 1/rm32/ecx . . . 0/r32/eax 4/disp8 . # copy ecx+4 to eax
|
||||
eb/jump $get-slice:end/disp8
|
||||
|
@ -305,7 +306,7 @@ test-get-slice:
|
|||
55/push-ebp
|
||||
89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp
|
||||
# - setup: create a table with a couple of keys
|
||||
# var table/ecx : (address stream {string, number}) = stream(2 rows * 8 bytes)
|
||||
# var table/ecx : (ref stream {string, number} 16) # 2 rows * 8 bytes/row
|
||||
81 5/subop/subtract 3/mod/direct 4/rm32/esp . . . . . 0x10/imm32 # subtract from esp
|
||||
68/push 0x10/imm32/length
|
||||
68/push 0/imm32/read
|
||||
|
@ -335,7 +336,7 @@ $test-get-slice:check1:
|
|||
8b/copy 0/mod/indirect 0/rm32/eax . . . 2/r32/edx . . # copy *eax 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
|
||||
05/add-to-eax 4/imm32
|
||||
# var slice/edx = {eax, edx}
|
||||
# var slice/edx : (ref slice) = {eax, edx}
|
||||
52/push-edx
|
||||
50/push-eax
|
||||
89/copy 3/mod/direct 2/rm32/edx . . . 4/r32/esp . . # copy esp to edx
|
||||
|
@ -365,7 +366,7 @@ $test-get-slice:check2:
|
|||
8b/copy 0/mod/indirect 0/rm32/eax . . . 2/r32/edx . . # copy *eax 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
|
||||
05/add-to-eax 4/imm32
|
||||
# var slice/edx = {eax, edx}
|
||||
# var slice/edx : (ref slice) = {eax, edx}
|
||||
52/push-edx
|
||||
50/push-eax
|
||||
89/copy 3/mod/direct 2/rm32/edx . . . 4/r32/esp . . # copy esp to edx
|
||||
|
@ -400,7 +401,7 @@ $test-get-slice:end:
|
|||
# return the address of the value
|
||||
# Beware: assume keys are immutable; they're inserted by reference
|
||||
# TODO: pass in an allocation descriptor
|
||||
get-or-insert: # table : (address stream {string, _}), key : (address string), row-size : int -> eax : (address _)
|
||||
get-or-insert: # table : (address stream {string_key, T}), key : string_key, row-size : int -> eax : (address T)
|
||||
# pseudocode:
|
||||
# curr = table->data
|
||||
# max = &table->data[table->write]
|
||||
|
@ -424,9 +425,9 @@ get-or-insert: # table : (address stream {string, _}), key : (address string),
|
|||
56/push-esi
|
||||
# esi = table
|
||||
8b/copy 1/mod/*+disp8 5/rm32/ebp . . . 6/r32/esi 8/disp8 . # copy *(ebp+8) to esi
|
||||
# curr/ecx = table->data
|
||||
# var curr/ecx : (address string_key) = table->data
|
||||
8d/copy-address 1/mod/*+disp8 6/rm32/esi . . . 1/r32/ecx 0xc/disp8 . # copy esi+12 to ecx
|
||||
# max/edx = table->data + table->write
|
||||
# var max/edx : (address string_key) = &table->data[table->write]
|
||||
8b/copy 0/mod/indirect 6/rm32/esi . . . 2/r32/edx . . # copy *esi to edx
|
||||
8d/copy-address 0/mod/indirect 4/rm32/sib 1/base/ecx 2/index/edx . 2/r32/edx . . # copy ecx+edx to edx
|
||||
$get-or-insert:search-loop:
|
||||
|
@ -442,8 +443,8 @@ $get-or-insert:search-loop:
|
|||
e8/call string-equal?/disp32
|
||||
# . . discard args
|
||||
81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp
|
||||
# . if (eax != 0) return eax = curr+4
|
||||
3d/compare-eax-and 0/imm32
|
||||
# . if (eax != false) return eax = curr+4
|
||||
3d/compare-eax-and 0/imm32/false
|
||||
74/jump-if-equal $get-or-insert:mismatch/disp8
|
||||
8d/copy-address 1/mod/*+disp8 1/rm32/ecx . . . 0/r32/eax 4/disp8 . # copy ecx+4 to eax
|
||||
eb/jump $get-or-insert:end/disp8
|
||||
|
@ -511,7 +512,7 @@ test-get-or-insert:
|
|||
# . prologue
|
||||
55/push-ebp
|
||||
89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp
|
||||
# var table/ecx : (address stream {string, number}) = stream(2 rows * 8 bytes)
|
||||
# var table/ecx : (ref stream {string, number} 16) # 2 rows * 8 bytes/row
|
||||
81 5/subop/subtract 3/mod/direct 4/rm32/esp . . . . . 0x10/imm32 # subtract from esp
|
||||
68/push 0x10/imm32/length
|
||||
68/push 0/imm32/read
|
||||
|
@ -651,7 +652,7 @@ $test-get-or-insert:end:
|
|||
# if there are no rows free, abort
|
||||
# WARNING: leaks memory
|
||||
# TODO: pass in an allocation descriptor
|
||||
leaky-get-or-insert-slice: # table : (address stream {string, _}), key : (address slice), row-size : int -> eax : (address _)
|
||||
leaky-get-or-insert-slice: # table : (address stream {string_key, T}), key : (address slice), row-size : int -> eax : (address T)
|
||||
# pseudocode:
|
||||
# curr = table->data
|
||||
# max = &table->data[table->write]
|
||||
|
@ -675,9 +676,9 @@ leaky-get-or-insert-slice: # table : (address stream {string, _}), key : (addre
|
|||
56/push-esi
|
||||
# esi = table
|
||||
8b/copy 1/mod/*+disp8 5/rm32/ebp . . . 6/r32/esi 8/disp8 . # copy *(ebp+8) to esi
|
||||
# curr/ecx = table->data
|
||||
# var curr/ecx : (address string_key) = table->data
|
||||
8d/copy-address 1/mod/*+disp8 6/rm32/esi . . . 1/r32/ecx 0xc/disp8 . # copy esi+12 to ecx
|
||||
# max/edx = table->data + table->write
|
||||
# var max/edx : (address string_key) = &table->data[table->write]
|
||||
8b/copy 0/mod/indirect 6/rm32/esi . . . 2/r32/edx . . # copy *esi to edx
|
||||
8d/copy-address 0/mod/indirect 4/rm32/sib 1/base/ecx 2/index/edx . 2/r32/edx . . # copy ecx+edx to edx
|
||||
$leaky-get-or-insert-slice:search-loop:
|
||||
|
@ -693,8 +694,8 @@ $leaky-get-or-insert-slice:search-loop:
|
|||
e8/call slice-equal?/disp32
|
||||
# . . discard args
|
||||
81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp
|
||||
# . if (eax != 0) return eax = curr+4
|
||||
3d/compare-eax-and 0/imm32
|
||||
# . if (eax != false) return eax = curr+4
|
||||
3d/compare-eax-and 0/imm32/false
|
||||
74/jump-if-equal $leaky-get-or-insert-slice:mismatch/disp8
|
||||
8d/copy-address 1/mod/*+disp8 1/rm32/ecx . . . 0/r32/eax 4/disp8 . # copy ecx+4 to eax
|
||||
eb/jump $leaky-get-or-insert-slice:end/disp8
|
||||
|
@ -768,7 +769,7 @@ test-leaky-get-or-insert-slice:
|
|||
# . prologue
|
||||
55/push-ebp
|
||||
89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp
|
||||
# var table/ecx : (address stream {string, number}) = stream(2 rows * 8 bytes)
|
||||
# var table/ecx : (ref stream {string, number} 16) # 2 rows * 8 bytes/row
|
||||
81 5/subop/subtract 3/mod/direct 4/rm32/esp . . . . . 0x10/imm32 # subtract from esp
|
||||
68/push 0x10/imm32/length
|
||||
68/push 0/imm32/read
|
||||
|
@ -779,7 +780,7 @@ test-leaky-get-or-insert-slice:
|
|||
8b/copy 0/mod/indirect 0/rm32/eax . . . 2/r32/edx . . # copy *eax 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
|
||||
05/add-to-eax 4/imm32
|
||||
# var slice/edx = {eax, edx}
|
||||
# var slice/edx : (ref slice) = {eax, edx}
|
||||
52/push-edx
|
||||
50/push-eax
|
||||
89/copy 3/mod/direct 2/rm32/edx . . . 4/r32/esp . . # copy esp to edx
|
||||
|
@ -872,7 +873,7 @@ $test-leaky-get-or-insert-slice:third-call:
|
|||
8b/copy 0/mod/indirect 0/rm32/eax . . . 2/r32/edx . . # copy *eax 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
|
||||
05/add-to-eax 4/imm32
|
||||
# var slice/edx = {eax, edx}
|
||||
# var slice/edx : (ref slice) = {eax, edx}
|
||||
52/push-edx
|
||||
50/push-eax
|
||||
89/copy 3/mod/direct 2/rm32/edx . . . 4/r32/esp . . # copy esp to edx
|
||||
|
@ -923,9 +924,9 @@ $test-leaky-get-or-insert-slice:end:
|
|||
c3/return
|
||||
|
||||
# if no row is found, stop(ed)
|
||||
get-or-stop: # table : (address stream {string, _}), key : (address string), row-size : int,
|
||||
# abort-message-prefix : (address string), err : (address buffered-file), ed : (address exit-descriptor)
|
||||
# -> eax : (address _)
|
||||
get-or-stop: # table : (address stream {string_key, T}), key : string_key, row-size : int,
|
||||
# abort-message-prefix : (address array byte), err : (address buffered-file), ed : (address exit-descriptor)
|
||||
# -> eax : (address T)
|
||||
# pseudocode:
|
||||
# curr = table->data
|
||||
# max = &table->data[table->write]
|
||||
|
@ -945,9 +946,9 @@ get-or-stop: # table : (address stream {string, _}), key : (address string), ro
|
|||
56/push-esi
|
||||
# esi = table
|
||||
8b/copy 1/mod/*+disp8 5/rm32/ebp . . . 6/r32/esi 8/disp8 . # copy *(ebp+8) to esi
|
||||
# curr/ecx = table->data
|
||||
# var curr/ecx : (address string_key) = table->data
|
||||
8d/copy-address 1/mod/*+disp8 6/rm32/esi . . . 1/r32/ecx 0xc/disp8 . # copy esi+12 to ecx
|
||||
# max/edx = table->data + table->write
|
||||
# var max/edx : (address byte) = &table->data[table->write]
|
||||
8b/copy 0/mod/indirect 6/rm32/esi . . . 2/r32/edx . . # copy *esi to edx
|
||||
8d/copy-address 0/mod/indirect 4/rm32/sib 1/base/ecx 2/index/edx . 2/r32/edx . . # copy ecx+edx to edx
|
||||
$get-or-stop:search-loop:
|
||||
|
@ -963,8 +964,8 @@ $get-or-stop:search-loop:
|
|||
e8/call string-equal?/disp32
|
||||
# . . discard args
|
||||
81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp
|
||||
# . if (eax != 0) return eax = curr+4
|
||||
3d/compare-eax-and 0/imm32
|
||||
# . if (eax != false) return eax = curr+4
|
||||
3d/compare-eax-and 0/imm32/false
|
||||
74/jump-if-equal $get-or-stop:mismatch/disp8
|
||||
8d/copy-address 1/mod/*+disp8 1/rm32/ecx . . . 0/r32/eax 4/disp8 . # copy ecx+4 to eax
|
||||
eb/jump $get-or-stop:end/disp8
|
||||
|
@ -1050,13 +1051,13 @@ test-get-or-stop:
|
|||
e8/call clear-stream/disp32
|
||||
# . . discard args
|
||||
81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp
|
||||
# var table/ecx : (address stream {string, number}) = stream(2 rows * 8 bytes)
|
||||
# var table/ecx : (ref stream {string, number} 16) # 2 rows * 8 bytes/row
|
||||
81 5/subop/subtract 3/mod/direct 4/rm32/esp . . . . . 0x10/imm32 # subtract from esp
|
||||
68/push 0x10/imm32/length
|
||||
68/push 0/imm32/read
|
||||
68/push 0/imm32/write
|
||||
89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx
|
||||
# var ed/edx : (address exit-descriptor)
|
||||
# var ed/edx : (ref exit-descriptor)
|
||||
68/push 0/imm32
|
||||
68/push 0/imm32
|
||||
89/copy 3/mod/direct 2/rm32/edx . . . 4/r32/esp . . # copy esp to edx
|
||||
|
@ -1139,7 +1140,7 @@ $test-get-or-stop:end:
|
|||
c3/return
|
||||
|
||||
# if no row is found, stop(ed)
|
||||
get-slice-or-stop: # table : (address stream {string, _}), key : (address slice), row-size : int,
|
||||
get-slice-or-stop: # table : (address stream {string_key, _}), key : (address slice), row-size : int,
|
||||
# abort-message-prefix : (address string), err : (address buffered-file), ed : (address exit-descriptor)
|
||||
# -> eax : (address _)
|
||||
# pseudocode:
|
||||
|
@ -1161,9 +1162,9 @@ get-slice-or-stop: # table : (address stream {string, _}), key : (address slice
|
|||
56/push-esi
|
||||
# esi = table
|
||||
8b/copy 1/mod/*+disp8 5/rm32/ebp . . . 6/r32/esi 8/disp8 . # copy *(ebp+8) to esi
|
||||
# curr/ecx = table->data
|
||||
# var curr/ecx : (address string_key) = table->data
|
||||
8d/copy-address 1/mod/*+disp8 6/rm32/esi . . . 1/r32/ecx 0xc/disp8 . # copy esi+12 to ecx
|
||||
# max/edx = table->data + table->write
|
||||
# var max/edx : (address byte) = &table->data[table->write]
|
||||
8b/copy 0/mod/indirect 6/rm32/esi . . . 2/r32/edx . . # copy *esi to edx
|
||||
8d/copy-address 0/mod/indirect 4/rm32/sib 1/base/ecx 2/index/edx . 2/r32/edx . . # copy ecx+edx to edx
|
||||
$get-slice-or-stop:search-loop:
|
||||
|
@ -1179,8 +1180,8 @@ $get-slice-or-stop:search-loop:
|
|||
e8/call slice-equal?/disp32
|
||||
# . . discard args
|
||||
81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp
|
||||
# . if (eax != 0) return eax = curr+4
|
||||
3d/compare-eax-and 0/imm32
|
||||
# . if (eax != false) return eax = curr+4
|
||||
3d/compare-eax-and 0/imm32/false
|
||||
74/jump-if-equal $get-slice-or-stop:mismatch/disp8
|
||||
8d/copy-address 1/mod/*+disp8 1/rm32/ecx . . . 0/r32/eax 4/disp8 . # copy ecx+4 to eax
|
||||
eb/jump $get-slice-or-stop:end/disp8
|
||||
|
@ -1266,17 +1267,17 @@ test-get-slice-or-stop:
|
|||
e8/call clear-stream/disp32
|
||||
# . . discard args
|
||||
81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp
|
||||
# var table/ecx : (address stream {string, number}) = stream(2 rows * 8 bytes)
|
||||
# var table/ecx : (ref stream {string, number} 16) # 2 rows * 8 bytes/row
|
||||
81 5/subop/subtract 3/mod/direct 4/rm32/esp . . . . . 0x10/imm32 # subtract from esp
|
||||
68/push 0x10/imm32/length
|
||||
68/push 0/imm32/read
|
||||
68/push 0/imm32/write
|
||||
89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx
|
||||
# var ed/edx : (address exit-descriptor)
|
||||
# var ed/edx : (ref exit-descriptor)
|
||||
68/push 0/imm32
|
||||
68/push 0/imm32
|
||||
89/copy 3/mod/direct 2/rm32/edx . . . 4/r32/esp . . # copy esp to edx
|
||||
# var slice/ebx = "code"
|
||||
# var slice/ebx : (ref slice) = "code"
|
||||
# . (eax..ebx) = "code"
|
||||
b8/copy-to-eax "code"/imm32
|
||||
8b/copy 0/mod/indirect 0/rm32/eax . . . 3/r32/ebx . . # copy *eax to ebx
|
||||
|
@ -1378,7 +1379,7 @@ $test-get-slice-or-stop:end:
|
|||
c3/return
|
||||
|
||||
# if no row is found, return null (0)
|
||||
maybe-get: # table : (address stream {string, _}), key : (address string), row-size : int -> eax : (address _)
|
||||
maybe-get: # table : (address stream {string_key, T}), key : string_key, row-size : int -> eax : (address T)
|
||||
# pseudocode:
|
||||
# curr = table->data
|
||||
# max = &table->data[table->write]
|
||||
|
@ -1397,9 +1398,9 @@ maybe-get: # table : (address stream {string, _}), key : (address string), row-
|
|||
56/push-esi
|
||||
# esi = table
|
||||
8b/copy 1/mod/*+disp8 5/rm32/ebp . . . 6/r32/esi 8/disp8 . # copy *(ebp+8) to esi
|
||||
# curr/ecx = table->data
|
||||
# var curr/ecx : (address string_key) = table->data
|
||||
8d/copy-address 1/mod/*+disp8 6/rm32/esi . . . 1/r32/ecx 0xc/disp8 . # copy esi+12 to ecx
|
||||
# max/edx = table->data + table->write
|
||||
# var max/edx : (address byte) = &table->data[table->write]
|
||||
8b/copy 0/mod/indirect 6/rm32/esi . . . 2/r32/edx . . # copy *esi to edx
|
||||
8d/copy-address 0/mod/indirect 4/rm32/sib 1/base/ecx 2/index/edx . 2/r32/edx . . # copy ecx+edx to edx
|
||||
$maybe-get:search-loop:
|
||||
|
@ -1415,8 +1416,8 @@ $maybe-get:search-loop:
|
|||
e8/call string-equal?/disp32
|
||||
# . . discard args
|
||||
81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp
|
||||
# . if (eax != 0) return eax = curr+4
|
||||
3d/compare-eax-and 0/imm32
|
||||
# . if (eax != false) return eax = curr+4
|
||||
3d/compare-eax-and 0/imm32/false
|
||||
74/jump-if-equal $maybe-get:mismatch/disp8
|
||||
8d/copy-address 1/mod/*+disp8 1/rm32/ecx . . . 0/r32/eax 4/disp8 . # copy ecx+4 to eax
|
||||
eb/jump $maybe-get:end/disp8
|
||||
|
@ -1442,7 +1443,7 @@ test-maybe-get:
|
|||
55/push-ebp
|
||||
89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp
|
||||
# - setup: create a table with one row
|
||||
# var table/ecx : (address stream {string, number}) = stream(2 rows * 8 bytes)
|
||||
# var table/ecx : (ref stream {string, number} 16) # 2 rows * 8 bytes/row
|
||||
81 5/subop/subtract 3/mod/direct 4/rm32/esp . . . . . 0x10/imm32 # subtract from esp
|
||||
68/push 0x10/imm32/length
|
||||
68/push 0/imm32/read
|
||||
|
@ -1525,7 +1526,7 @@ $test-maybe-get:end:
|
|||
c3/return
|
||||
|
||||
# if no row is found, return null (0)
|
||||
maybe-get-slice: # table : (address stream {string, _}), key : (address slice), row-size : int -> eax : (address _)
|
||||
maybe-get-slice: # table : (address stream {string_key, T}), key : (address slice), row-size : int -> eax : (address T)
|
||||
# pseudocode:
|
||||
# curr = table->data
|
||||
# max = &table->data[table->write]
|
||||
|
@ -1544,9 +1545,9 @@ maybe-get-slice: # table : (address stream {string, _}), key : (address slice),
|
|||
56/push-esi
|
||||
# esi = table
|
||||
8b/copy 1/mod/*+disp8 5/rm32/ebp . . . 6/r32/esi 8/disp8 . # copy *(ebp+8) to esi
|
||||
# curr/ecx = table->data
|
||||
# var curr/ecx : (address string_key) = table->data
|
||||
8d/copy-address 1/mod/*+disp8 6/rm32/esi . . . 1/r32/ecx 0xc/disp8 . # copy esi+12 to ecx
|
||||
# max/edx = table->data + table->write
|
||||
# var max/edx : (address byte) = &table->data[table->write]
|
||||
8b/copy 0/mod/indirect 6/rm32/esi . . . 2/r32/edx . . # copy *esi to edx
|
||||
8d/copy-address 0/mod/indirect 4/rm32/sib 1/base/ecx 2/index/edx . 2/r32/edx . . # copy ecx+edx to edx
|
||||
$maybe-get-slice:search-loop:
|
||||
|
@ -1562,8 +1563,8 @@ $maybe-get-slice:search-loop:
|
|||
e8/call slice-equal?/disp32
|
||||
# . . discard args
|
||||
81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp
|
||||
# . if (eax != 0) return eax = curr+4
|
||||
3d/compare-eax-and 0/imm32
|
||||
# . if (eax != false) return eax = curr+4
|
||||
3d/compare-eax-and 0/imm32/false
|
||||
74/jump-if-equal $maybe-get-slice:mismatch/disp8
|
||||
8d/copy-address 1/mod/*+disp8 1/rm32/ecx . . . 0/r32/eax 4/disp8 . # copy ecx+4 to eax
|
||||
eb/jump $maybe-get-slice:end/disp8
|
||||
|
@ -1589,7 +1590,7 @@ test-maybe-get-slice:
|
|||
55/push-ebp
|
||||
89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp
|
||||
# - setup: create a table with one row
|
||||
# var table/ecx : (address stream {string, number}) = stream(2 rows * 8 bytes)
|
||||
# var table/ecx : (ref stream {string, number} 16) # 2 rows * 8 bytes/row
|
||||
81 5/subop/subtract 3/mod/direct 4/rm32/esp . . . . . 0x10/imm32 # subtract from esp
|
||||
68/push 0x10/imm32/length
|
||||
68/push 0/imm32/read
|
||||
|
@ -1611,7 +1612,7 @@ $test-maybe-get-slice:success:
|
|||
8b/copy 0/mod/indirect 0/rm32/eax . . . 2/r32/edx . . # copy *eax 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
|
||||
05/add-to-eax 4/imm32
|
||||
# var slice/edx = {eax, edx}
|
||||
# var slice/edx : (ref slice) = {eax, edx}
|
||||
52/push-edx
|
||||
50/push-eax
|
||||
89/copy 3/mod/direct 2/rm32/edx . . . 4/r32/esp . . # copy esp to edx
|
||||
|
@ -1661,7 +1662,7 @@ $test-maybe-get-slice:failure:
|
|||
8b/copy 0/mod/indirect 0/rm32/eax . . . 2/r32/edx . . # copy *eax 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
|
||||
05/add-to-eax 4/imm32
|
||||
# var slice/edx = {eax, edx}
|
||||
# var slice/edx : (ref slice) = {eax, edx}
|
||||
52/push-edx
|
||||
50/push-eax
|
||||
89/copy 3/mod/direct 2/rm32/edx . . . 4/r32/esp . . # copy esp to edx
|
||||
|
|
|
@ -63,10 +63,10 @@ $slurp:loop:
|
|||
3d/compare-eax-and 0/imm32
|
||||
74/jump-if-equal $slurp:end/disp8
|
||||
$slurp:from-stream:
|
||||
# AL = f->data[f->read]
|
||||
# var c/eax : byte = f->data[f->read]
|
||||
31/xor 3/mod/direct 0/rm32/eax . . . 0/r32/eax . . # clear eax
|
||||
8a/copy-byte 1/mod/*+disp8 4/rm32/sib 6/base/esi 1/index/ecx . 0/r32/AL 0x10/disp8 . # copy byte at *(esi+ecx+16) to AL
|
||||
# s->data[s->write] = AL
|
||||
# s->data[s->write] = c
|
||||
88/copy-byte 1/mod/*+disp8 4/rm32/sib 7/base/edi 2/index/edx . 0/r32/AL 0xc/disp8 . # copy AL to *(edi+edx+12)
|
||||
# ++f->read
|
||||
41/increment-ecx
|
||||
|
|
|
@ -1,3 +1,8 @@
|
|||
# Helpers to compute widths of SubX arguments based on their metadata.
|
||||
# /imm8 => 1 byte,
|
||||
# /disp32 => 4 bytes,
|
||||
# and so on.
|
||||
|
||||
== code
|
||||
# instruction effective address register displacement immediate
|
||||
# . op subop mod rm32 base index scale r32
|
||||
|
@ -11,12 +16,12 @@ compute-width: # word : (address array byte) -> eax : int
|
|||
51/push-ecx
|
||||
# eax = word
|
||||
8b/copy 1/mod/*+disp8 5/rm32/ebp . . . 0/r32/eax 8/disp8 . # copy *(ebp+8) to ecx
|
||||
# ecx = word + word->length
|
||||
# var ecx : (address byte) = &word[word->length]
|
||||
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
|
||||
# eax = word->data
|
||||
05/add-to-eax 4/imm32
|
||||
# var in/ecx : (address slice) = {eax, ecx}
|
||||
# var in/ecx : (ref slice) = {eax, ecx}
|
||||
51/push-ecx
|
||||
50/push-eax
|
||||
89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx
|
||||
|
@ -54,8 +59,8 @@ compute-width-of-slice: # s : (address slice) -> eax : int
|
|||
e8/call has-metadata?/disp32
|
||||
# . . discard args
|
||||
81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp
|
||||
# . if (eax != 0) return 4
|
||||
3d/compare-eax-and 0/imm32
|
||||
# . if (eax != false) return 4
|
||||
3d/compare-eax-and 0/imm32/false
|
||||
b8/copy-to-eax 4/imm32 # ZF is set, so we can overwrite eax now
|
||||
75/jump-if-not-equal $compute-width-of-slice:end/disp8
|
||||
# if (has-metadata?(word, "disp32")) return 4
|
||||
|
@ -67,8 +72,8 @@ compute-width-of-slice: # s : (address slice) -> eax : int
|
|||
e8/call has-metadata?/disp32
|
||||
# . . discard args
|
||||
81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp
|
||||
# . if (eax != 0) return 4
|
||||
3d/compare-eax-and 0/imm32
|
||||
# . if (eax != false) return 4
|
||||
3d/compare-eax-and 0/imm32/false
|
||||
b8/copy-to-eax 4/imm32 # ZF is set, so we can overwrite eax now
|
||||
75/jump-if-not-equal $compute-width-of-slice:end/disp8
|
||||
# if (has-metadata?(word, "imm16")) return 2
|
||||
|
@ -80,8 +85,8 @@ compute-width-of-slice: # s : (address slice) -> eax : int
|
|||
e8/call has-metadata?/disp32
|
||||
# . . discard args
|
||||
81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp
|
||||
# . if (eax != 0) return 2
|
||||
3d/compare-eax-and 0/imm32
|
||||
# . if (eax != false) return 2
|
||||
3d/compare-eax-and 0/imm32/false
|
||||
b8/copy-to-eax 2/imm32 # ZF is set, so we can overwrite eax now
|
||||
75/jump-if-not-equal $compute-width-of-slice:end/disp8
|
||||
# if (has-metadata?(word, "disp16")) return 2
|
||||
|
@ -93,8 +98,8 @@ compute-width-of-slice: # s : (address slice) -> eax : int
|
|||
e8/call has-metadata?/disp32
|
||||
# . . discard args
|
||||
81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp
|
||||
# . if (eax != 0) return 2
|
||||
3d/compare-eax-and 0/imm32
|
||||
# . if (eax != false) return 2
|
||||
3d/compare-eax-and 0/imm32/false
|
||||
b8/copy-to-eax 2/imm32 # ZF is set, so we can overwrite eax now
|
||||
75/jump-if-not-equal $compute-width-of-slice:end/disp8
|
||||
# otherwise return 1
|
||||
|
|
|
@ -15,20 +15,20 @@ emit-hex-array: # out : (address buffered-file), arr : (address array byte)
|
|||
57/push-edi
|
||||
# edi = out
|
||||
8b/copy 1/mod/*+disp8 5/rm32/ebp . . . 7/r32/edi 8/disp8 . # copy *(ebp+8) to edi
|
||||
# edx = arr # <== 0xbdffffe4
|
||||
# edx = arr
|
||||
8b/copy 1/mod/*+disp8 5/rm32/ebp . . . 2/r32/edx 0xc/disp8 . # copy *(ebp+12) to edx
|
||||
# curr/ecx = arr->data
|
||||
# var curr/ecx : (address byte) = arr->data
|
||||
8d/copy-address 1/mod/*+disp8 2/rm32/edx . . . 1/r32/ecx 4/disp8 . # copy edx+4 to ecx
|
||||
# max/edx = arr->data + arr->length
|
||||
# var max/edx : (address byte) = &arr->data[arr->length]
|
||||
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
|
||||
# eax = 0
|
||||
# var c/eax : byte = 0
|
||||
31/xor 3/mod/direct 0/rm32/eax . . . 0/r32/eax . . # clear eax
|
||||
$emit-hex-array:loop:
|
||||
# if (curr >= width) break
|
||||
39/compare 3/mod/direct 1/rm32/ecx . . . 2/r32/edx . . # compare ecx with edx
|
||||
73/jump-if-greater-or-equal-unsigned $emit-hex-array:end/disp8
|
||||
# emit-hex(out, *curr, width=1)
|
||||
# emit-hex(out, c = *curr, width=1)
|
||||
# . . push args
|
||||
68/push 1/imm32/width
|
||||
8a/copy-byte 0/mod/indirect 1/rm32/ecx . . . 0/r32/AL . . # copy byte at *ecx to AL
|
||||
|
@ -71,7 +71,7 @@ test-emit-hex-array:
|
|||
e8/call clear-stream/disp32
|
||||
# . . discard args
|
||||
81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp
|
||||
# var arr/ecx (address array byte) = [01, 02, 03]
|
||||
# var arr/ecx (ref array byte) = [01, 02, 03]
|
||||
68/push 0x00030201/imm32 # bytes 01 02 03
|
||||
68/push 3/imm32/length
|
||||
89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
# . 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
|
||||
|
||||
write-int: # out : (address stream), n : int
|
||||
write-int: # out : (address stream byte), n : int
|
||||
# . prologue
|
||||
55/push-ebp
|
||||
89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp
|
||||
|
|
|
@ -40,27 +40,29 @@ array-equal?: # a : (address array int), b : (address array int) -> eax : boole
|
|||
8b/copy 1/mod/*+disp8 5/rm32/ebp . . . 6/r32/esi 8/disp8 . # copy *(ebp+8) to esi
|
||||
# edi = b
|
||||
8b/copy 1/mod/*+disp8 5/rm32/ebp . . . 7/r32/edi 0xc/disp8 . # copy *(ebp+12) to edi
|
||||
# lena/edx = a->length
|
||||
# var lena/edx : int = a->length
|
||||
8b/copy 0/mod/indirect 6/rm32/esi . . . 2/r32/edx . . # copy *esi to edx
|
||||
$array-equal?:lengths:
|
||||
# if (lena != b->length) return false
|
||||
39/compare 0/mod/indirect 7/rm32/edi . . . 2/r32/edx . . # compare *edi and edx
|
||||
75/jump-if-not-equal $array-equal?:false/disp8
|
||||
# curra/esi = a->data
|
||||
# var curra/esi : (address byte) = a->data
|
||||
81 0/subop/add 3/mod/direct 6/rm32/esi . . . . . 4/imm32 # add to esi
|
||||
# currb/edi = b->data
|
||||
# var currb/edi : (address byte) = b->data
|
||||
81 0/subop/add 3/mod/direct 7/rm32/edi . . . . . 4/imm32 # add to edi
|
||||
# i/ecx = i1/eax = i2/ebx = 0
|
||||
# var i/ecx : int = 0
|
||||
31/xor 3/mod/direct 1/rm32/ecx . . . 1/r32/ecx . . # clear ecx
|
||||
# var vala/eax : int
|
||||
# var valb/ebx : int
|
||||
$array-equal?:loop:
|
||||
# if (i >= lena) return true
|
||||
39/compare 3/mod/direct 1/rm32/ecx . . . 2/r32/edx . . # compare ecx with edx
|
||||
7d/jump-if-greater-or-equal $array-equal?:true/disp8
|
||||
# i1 = *curra
|
||||
# vala = *curra
|
||||
8b/copy 0/mod/indirect 6/rm32/esi . . . 0/r32/eax . . # copy *esi to eax
|
||||
# i2 = *currb
|
||||
# valb = *currb
|
||||
8b/copy 0/mod/indirect 7/rm32/edi . . . 3/r32/ebx . . # copy *edi to ebx
|
||||
# if (i1 != i2) return false
|
||||
# if (vala != valb) return false
|
||||
39/compare 3/mod/direct 0/rm32/eax . . . 3/r32/ebx . . # compare eax and ebx
|
||||
75/jump-if-not-equal $array-equal?:false/disp8
|
||||
# i += 4
|
||||
|
@ -91,10 +93,10 @@ test-compare-empty-with-empty-array:
|
|||
# . prologue
|
||||
55/push-ebp
|
||||
89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp
|
||||
# var ecx = []
|
||||
# var ecx : (ref array _) = []
|
||||
68/push 0/imm32/size
|
||||
89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx
|
||||
# var edx = []
|
||||
# var edx : (ref array _) = []
|
||||
68/push 0/imm32/size
|
||||
89/copy 3/mod/direct 2/rm32/edx . . . 4/r32/esp . . # copy esp to edx
|
||||
# eax = array-equal?(ecx, edx)
|
||||
|
@ -123,11 +125,11 @@ test-compare-empty-with-non-empty-array: # also checks length-mismatch code pat
|
|||
# . prologue
|
||||
55/push-ebp
|
||||
89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp
|
||||
# var ecx = [1]
|
||||
# var ecx : (ref array int) = [1]
|
||||
68/push 1/imm32
|
||||
68/push 4/imm32/size
|
||||
89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx
|
||||
# var edx = []
|
||||
# var edx : (ref array int) = []
|
||||
68/push 0/imm32/size
|
||||
89/copy 3/mod/direct 2/rm32/edx . . . 4/r32/esp . . # copy esp to edx
|
||||
# eax = array-equal?(ecx, edx)
|
||||
|
@ -156,13 +158,13 @@ test-compare-equal-arrays:
|
|||
# . prologue
|
||||
55/push-ebp
|
||||
89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp
|
||||
# var ecx = [1, 2, 3]
|
||||
# var ecx : (ref array int) = [1, 2, 3]
|
||||
68/push 3/imm32
|
||||
68/push 2/imm32
|
||||
68/push 1/imm32
|
||||
68/push 0xc/imm32/size
|
||||
89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx
|
||||
# var edx = [1, 2, 3]
|
||||
# var edx : (ref array int) = [1, 2, 3]
|
||||
68/push 3/imm32
|
||||
68/push 2/imm32
|
||||
68/push 1/imm32
|
||||
|
@ -194,13 +196,13 @@ test-compare-inequal-arrays-equal-lengths:
|
|||
# . prologue
|
||||
55/push-ebp
|
||||
89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp
|
||||
# var ecx = [1, 4, 3]
|
||||
# var ecx : (ref array int) = [1, 4, 3]
|
||||
68/push 3/imm32
|
||||
68/push 4/imm32
|
||||
68/push 1/imm32
|
||||
68/push 0xc/imm32/size
|
||||
89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx
|
||||
# var edx = [1, 2, 3]
|
||||
# var edx : (ref array int) = [1, 2, 3]
|
||||
68/push 3/imm32
|
||||
68/push 2/imm32
|
||||
68/push 1/imm32
|
||||
|
@ -228,9 +230,9 @@ test-compare-inequal-arrays-equal-lengths:
|
|||
5d/pop-to-ebp
|
||||
c3/return
|
||||
|
||||
parse-array-of-ints: # ad : (address allocation-descriptor), s : (address string) -> result/eax : (address array int)
|
||||
parse-array-of-ints: # ad : (address allocation-descriptor), s : (address string) -> result/eax : (handle array int)
|
||||
# pseudocode
|
||||
# end = s->data + s->length
|
||||
# end = &s->data[s->length]
|
||||
# curr = s->data
|
||||
# size = 0
|
||||
# while true
|
||||
|
@ -241,7 +243,7 @@ parse-array-of-ints: # ad : (address allocation-descriptor), s : (address strin
|
|||
# ++size
|
||||
# result = allocate(ad, (size+1)*4)
|
||||
# result->size = (size+1)*4
|
||||
# var slice = {s->data, 0}
|
||||
# var slice : (ref slice) = {s->data, 0}
|
||||
# out = result->data
|
||||
# while true
|
||||
# if (slice->start >= end) break
|
||||
|
@ -264,14 +266,14 @@ parse-array-of-ints: # ad : (address allocation-descriptor), s : (address strin
|
|||
57/push-edi
|
||||
# esi = s
|
||||
8b/copy 1/mod/*+disp8 5/rm32/ebp . . . 6/r32/esi 0xc/disp8 . # copy *(ebp+12) to esi
|
||||
# curr/ecx = s->data
|
||||
# var curr/ecx : (address byte) = s->data
|
||||
8d/copy-address 1/mod/*+disp8 6/rm32/esi . . . 1/r32/ecx 4/disp8 . # copy esi+4 to ecx
|
||||
# end/edx = s->data + s->length
|
||||
# var end/edx : (address byte) = &s->data[s->length]
|
||||
# . edx = s->length
|
||||
8b/copy 0/mod/indirect 6/rm32/esi . . . 2/r32/edx . . # copy *esi to edx
|
||||
# . edx += curr
|
||||
01/add 3/mod/direct 2/rm32/edx . . . 1/r32/ecx . . # add ecx to edx
|
||||
# size/ebx = 0
|
||||
# var size/ebx : int = 0
|
||||
31/xor 3/mod/direct 3/rm32/ebx . . . 3/r32/ebx . . # clear ebx
|
||||
$parse-array-of-ints:loop1:
|
||||
# if (curr >= end) break
|
||||
|
@ -308,7 +310,7 @@ $parse-array-of-ints:loop1:
|
|||
81 0/subop/add 3/mod/direct 3/rm32/ebx . . . . . 4/imm32 # add to ebx
|
||||
eb/jump $parse-array-of-ints:loop1/disp8
|
||||
$parse-array-of-ints:break1:
|
||||
# result/edi = allocate(ad, size+4)
|
||||
# var result/edi : (handle array int) = allocate(ad, size+4)
|
||||
# . eax = allocate(ad, size+4)
|
||||
# . . push args
|
||||
89/copy 3/mod/direct 0/rm32/eax . . . 3/r32/ebx . . # copy ebx to eax
|
||||
|
@ -324,7 +326,7 @@ $parse-array-of-ints:break1:
|
|||
# result->size = size
|
||||
89/copy 0/mod/indirect 0/rm32/eax . . . 3/r32/ebx . . # copy ebx to *eax
|
||||
$parse-array-of-ints:pass2:
|
||||
# var slice/ecx = {s->data, 0}
|
||||
# var slice/ecx : (ref slice) = {s->data, 0}
|
||||
# . push 0
|
||||
68/push 0/imm32/end
|
||||
# . push s->data
|
||||
|
@ -332,7 +334,7 @@ $parse-array-of-ints:pass2:
|
|||
51/push-ecx
|
||||
# . bookmark
|
||||
89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx
|
||||
# out/ebx = result->data
|
||||
# var out/ebx : (address byte) = result->data
|
||||
8d/copy-address 1/mod/*+disp8 0/rm32/eax . . . 3/r32/ebx 4/disp8 . # copy eax+4 to ebx
|
||||
$parse-array-of-ints:loop2:
|
||||
# if (slice->start >= end) break
|
||||
|
@ -373,7 +375,7 @@ $parse-array-of-ints:loop2:
|
|||
e8/call parse-hex-int/disp32
|
||||
# . . discard args
|
||||
81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp
|
||||
# *out = eax
|
||||
# . *out = eax
|
||||
89/copy 0/mod/indirect 3/rm32/ebx . . . 0/r32/eax . . # copy eax to *ebx
|
||||
# out += 4
|
||||
81 0/subop/add 3/mod/direct 3/rm32/ebx . . . . . 4/imm32 # add to ebx
|
||||
|
@ -402,7 +404,7 @@ test-parse-array-of-ints:
|
|||
# . prologue
|
||||
55/push-ebp
|
||||
89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp
|
||||
# var ecx = [1, 2, 3]
|
||||
# var ecx : (ref array int) = [1, 2, 3]
|
||||
68/push 3/imm32
|
||||
68/push 2/imm32
|
||||
68/push 1/imm32
|
||||
|
@ -496,7 +498,7 @@ test-parse-array-of-ints-extra-whitespace:
|
|||
# . prologue
|
||||
55/push-ebp
|
||||
89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp
|
||||
# var ecx = [1, 2, 3]
|
||||
# var ecx : (ref array int) = [1, 2, 3]
|
||||
68/push 3/imm32
|
||||
68/push 2/imm32
|
||||
68/push 1/imm32
|
||||
|
@ -540,7 +542,7 @@ check-array-equal: # a : (address array int), expected : (address string), msg
|
|||
89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp
|
||||
# . save registers
|
||||
50/push-eax
|
||||
# var b/ecx = parse-array-of-ints(Heap, expected)
|
||||
# var b/ecx : (handle array int) = parse-array-of-ints(Heap, expected)
|
||||
# . eax = parse-array-of-ints(Heap, expected)
|
||||
# . . push args
|
||||
ff 6/subop/push 1/mod/*+disp8 5/rm32/ebp . . . . 0xc/disp8 . # push *(ebp+12)
|
||||
|
@ -580,7 +582,7 @@ test-check-array-equal:
|
|||
# . prologue
|
||||
55/push-ebp
|
||||
89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp
|
||||
# var ecx = [1, 2, 3]
|
||||
# var ecx : (ref array int) = [1, 2, 3]
|
||||
68/push 3/imm32
|
||||
68/push 2/imm32
|
||||
68/push 1/imm32
|
||||
|
|
|
@ -33,7 +33,7 @@ $next-word-or-string:check0:
|
|||
# . if (eax < line->write) goto next check
|
||||
3b/compare 0/mod/indirect 6/rm32/esi . . . 0/r32/eax . . # compare eax with *esi
|
||||
7c/jump-if-lesser $next-word-or-string:check-for-comment/disp8
|
||||
# . return out = {0, 0}
|
||||
# . return out
|
||||
c7 0/subop/copy 0/mod/direct 7/rm32/edi . . . . . 0/imm32 # copy to *edi
|
||||
c7 0/subop/copy 1/mod/*+disp8 7/rm32/edi . . . . 4/disp8 0/imm32 # copy to *(edi+4)
|
||||
eb/jump $next-word-or-string:end/disp8
|
||||
|
@ -111,7 +111,7 @@ test-next-word-or-string:
|
|||
e8/call clear-stream/disp32
|
||||
# . . discard args
|
||||
81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp
|
||||
# var slice/ecx = {0, 0}
|
||||
# var slice/ecx : (ref slice)
|
||||
68/push 0/imm32/end
|
||||
68/push 0/imm32/start
|
||||
89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx
|
||||
|
@ -184,7 +184,7 @@ test-next-word-or-string-returns-whole-comment:
|
|||
e8/call clear-stream/disp32
|
||||
# . . discard args
|
||||
81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp
|
||||
# var slice/ecx = {0, 0}
|
||||
# var slice/ecx : (ref slice)
|
||||
68/push 0/imm32/end
|
||||
68/push 0/imm32/start
|
||||
89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx
|
||||
|
@ -257,7 +257,7 @@ test-next-word-or-string-returns-empty-slice-on-eof:
|
|||
e8/call clear-stream/disp32
|
||||
# . . discard args
|
||||
81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp
|
||||
# var slice/ecx = {0, 0}
|
||||
# var slice/ecx : (ref slice)
|
||||
68/push 0/imm32/end
|
||||
68/push 0/imm32/start
|
||||
89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx
|
||||
|
@ -299,7 +299,7 @@ test-next-word-or-string-returns-string-literal:
|
|||
e8/call clear-stream/disp32
|
||||
# . . discard args
|
||||
81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp
|
||||
# var slice/ecx = {0, 0}
|
||||
# var slice/ecx : (ref slice)
|
||||
68/push 0/imm32/end
|
||||
68/push 0/imm32/start
|
||||
89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx
|
||||
|
@ -362,7 +362,7 @@ test-next-word-or-string-returns-string-with-escapes:
|
|||
e8/call clear-stream/disp32
|
||||
# . . discard args
|
||||
81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp
|
||||
# var slice/ecx = {0, 0}
|
||||
# var slice/ecx : (ref slice)
|
||||
68/push 0/imm32/end
|
||||
68/push 0/imm32/start
|
||||
89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx
|
||||
|
|
|
@ -16,20 +16,20 @@ clear-stack: # s : (address stack)
|
|||
51/push-ecx
|
||||
# eax = s
|
||||
8b/copy 1/mod/*+disp8 5/rm32/ebp . . . 0/r32/eax 8/disp8 . # copy *(ebp+8) to eax
|
||||
# ecx = &s->data[s->length]
|
||||
# var max/ecx : (address byte) = &s->data[s->length]
|
||||
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
|
||||
# s->top = 0
|
||||
c7 0/subop/copy 0/mod/direct 0/rm32/eax . . . . . 0/imm32 # copy to *eax
|
||||
# eax = s->data
|
||||
# var curr/eax : (address byte) = s->data
|
||||
81 0/subop/add 3/mod/direct 0/rm32/eax . . . . . 8/imm32 # add to eax
|
||||
$clear-stack:loop:
|
||||
# if (eax >= ecx) break
|
||||
# if (curr >= max) break
|
||||
39/compare 3/mod/direct 0/rm32/eax . . . 1/r32/ecx . . # compare eax with ecx
|
||||
73/jump-if-greater-or-equal-unsigned $clear-stack:end/disp8
|
||||
# *eax = 0
|
||||
# *curr = 0
|
||||
c6 0/subop/copy 0/mod/direct 0/rm32/eax . . . . . 0/imm8 # copy byte to *eax
|
||||
# ++eax
|
||||
# ++curr
|
||||
40/increment-eax
|
||||
eb/jump $clear-stack:loop/disp8
|
||||
$clear-stack:end:
|
||||
|
@ -343,7 +343,7 @@ top: # s : (address stack) -> n/eax : int
|
|||
# if (s->top <= 0) abort
|
||||
81 7/subop/compare 0/mod/indirect 6/rm32/esi . . . . . 0/imm32 # compare *esi
|
||||
7e/jump-if-lesser-or-equal $top:abort/disp8
|
||||
# eax = s->data[s->top - 4]
|
||||
# n = s->data[s->top - 4]
|
||||
8b/copy 0/mod/indirect 6/rm32/esi . . . 1/r32/ecx . . # copy *esi to ecx
|
||||
81 5/subop/subtract 3/mod/direct 1/rm32/ecx . . . . . 4/imm32 # subtract from ecx
|
||||
8b/copy 1/mod/*+disp8 4/rm32/sib 6/base/esi 1/index/ecx . 0/r32/eax 8/disp8 . # copy *(esi+ecx+8) to eax
|
||||
|
|
BIN
apps/assort
BIN
apps/assort
Binary file not shown.
|
@ -50,8 +50,8 @@ Entry: # run tests if necessary, convert stdin if not
|
|||
e8/call kernel-string-equal?/disp32
|
||||
# . . discard args
|
||||
81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp
|
||||
# . if (eax == 0) goto interactive
|
||||
3d/compare-eax-and 0/imm32
|
||||
# . if (eax == false) goto interactive
|
||||
3d/compare-eax-and 0/imm32/false
|
||||
74/jump-if-equal $subx-assort-main:interactive/disp8
|
||||
# run-tests()
|
||||
e8/call run-tests/disp32
|
||||
|
@ -60,7 +60,7 @@ Entry: # run tests if necessary, convert stdin if not
|
|||
eb/jump $subx-assort-main:end/disp8
|
||||
$subx-assort-main:interactive:
|
||||
# - otherwise convert stdin
|
||||
# var ed/eax : exit-descriptor
|
||||
# var ed/eax : (ref exit-descriptor)
|
||||
81 5/subop/subtract 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # subtract from esp
|
||||
89/copy 3/mod/direct 0/rm32/eax . . . 4/r32/esp . . # copy esp to eax
|
||||
# configure ed to really exit()
|
||||
|
@ -97,7 +97,7 @@ subx-assort: # in : (address buffered-file), out : (address buffered-file)
|
|||
89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp
|
||||
# . save registers
|
||||
51/push-ecx
|
||||
# var table/ecx : (address stream byte 10*8)
|
||||
# var table/ecx : (ref stream {string, (address stream byte)} 80) # 10 rows * 8 bytes/row
|
||||
81 5/subop/subtract 3/mod/direct 4/rm32/esp . . . . . 0x50/imm32 # subtract from esp
|
||||
68/push 0x50/imm32/length
|
||||
68/push 0/imm32/read
|
||||
|
@ -450,8 +450,10 @@ test-subx-assort:
|
|||
5d/pop-to-ebp
|
||||
c3/return
|
||||
|
||||
# type string_key = (address array byte)
|
||||
|
||||
# beware: leaks memory (one name per segment read)
|
||||
read-segments: # in : (address buffered-file), table : (address stream {string, (address stream byte)})
|
||||
read-segments: # in : (address buffered-file), table : (address stream {string_key, (handle stream byte)})
|
||||
# pseudocode:
|
||||
# var curr-segment : (handle stream byte) = 0
|
||||
# var line : (stream byte 512)
|
||||
|
@ -494,13 +496,13 @@ read-segments: # in : (address buffered-file), table : (address stream {string,
|
|||
52/push-edx
|
||||
53/push-ebx
|
||||
56/push-esi
|
||||
# var line/ecx : (stream byte 512)
|
||||
# var line/ecx : (ref stream byte 512)
|
||||
81 5/subop/subtract 3/mod/direct 4/rm32/esp . . . . . 0x200/imm32 # subtract from esp
|
||||
68/push 0x200/imm32/length
|
||||
68/push 0/imm32/read
|
||||
68/push 0/imm32/write
|
||||
89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx
|
||||
# var word-slice/edx = {0, 0}
|
||||
# var word-slice/edx : (ref slice)
|
||||
68/push 0/imm32/end
|
||||
68/push 0/imm32/start
|
||||
89/copy 3/mod/direct 2/rm32/edx . . . 4/r32/esp . . # copy esp to edx
|
||||
|
@ -583,8 +585,8 @@ $read-segments:check1:
|
|||
e8/call slice-empty?/disp32
|
||||
# . . discard args
|
||||
81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp
|
||||
# . if (eax != 0) continue
|
||||
3d/compare-eax-and 0/imm32
|
||||
# . if (eax != false) continue
|
||||
3d/compare-eax-and 0/imm32/false
|
||||
0f 85/jump-if-not-equal $read-segments:loop/disp32
|
||||
$read-segments:check-for-comment:
|
||||
#? # print("check for comment\n") {{{
|
||||
|
@ -597,12 +599,12 @@ $read-segments:check-for-comment:
|
|||
#? 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp
|
||||
#? # }}}
|
||||
# if (slice-starts-with?(word-slice, "#")) continue
|
||||
# . start/esi = word-slice->start
|
||||
# . var start/esi : (address byte) = word-slice->start
|
||||
8b/copy 0/mod/indirect 2/rm32/edx . . . 6/r32/esi . . # copy *ecx to esi
|
||||
# . c/eax = *start
|
||||
# . var c/eax : byte = *start
|
||||
31/xor 3/mod/direct 0/rm32/eax . . . 0/r32/eax . . # clear eax
|
||||
8a/copy-byte 0/mod/indirect 6/rm32/esi . . . 0/r32/AL . . # copy byte at *esi to AL
|
||||
# . if (eax == '#') continue
|
||||
# . if (c == '#') continue
|
||||
3d/compare-eax-and 0x23/imm32/hash
|
||||
0f 84/jump-if-equal $read-segments:loop/disp32
|
||||
$read-segments:check-for-segment-header:
|
||||
|
@ -664,8 +666,8 @@ $read-segments:check-for-segment-header:
|
|||
e8/call slice-equal?/disp32
|
||||
# . . discard args
|
||||
81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp
|
||||
# . if (eax == 0) goto check3
|
||||
3d/compare-eax-and 0/imm32
|
||||
# . if (eax == false) goto check3
|
||||
3d/compare-eax-and 0/imm32/false
|
||||
0f 84/jump-if-equal $read-segments:regular-line/disp32
|
||||
# segment-name = next-word-or-string(line)
|
||||
# . . push args
|
||||
|
@ -715,7 +717,7 @@ $read-segments:check-for-segment-header:
|
|||
#? # . . discard args
|
||||
#? 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp
|
||||
#? # }}}
|
||||
# segment-slot/eax = leaky-get-or-insert-slice(table, segment-name, row-size=8)
|
||||
# var segment-slot/eax : (address handle stream byte) = leaky-get-or-insert-slice(table, segment-name, row-size=8)
|
||||
# . . push args
|
||||
68/push 8/imm32/row-size
|
||||
52/push-edx
|
||||
|
@ -841,10 +843,10 @@ $read-segments:end:
|
|||
5d/pop-to-ebp
|
||||
c3/return
|
||||
|
||||
write-segments: # out : (address buffered-file), table : (address stream {string, (address stream byte)})
|
||||
write-segments: # out : (address buffered-file), table : (address stream {string_key, (handle stream byte)})
|
||||
# pseudocode:
|
||||
# var curr = table->data
|
||||
# var max = table->data + table->write
|
||||
# var max = &table->data[table->write]
|
||||
# while curr < max
|
||||
# stream = table[i].stream
|
||||
# write-stream-data(out, stream)
|
||||
|
@ -860,17 +862,17 @@ write-segments: # out : (address buffered-file), table : (address stream {strin
|
|||
56/push-esi
|
||||
# esi = table
|
||||
8b/copy 1/mod/*+disp8 5/rm32/ebp . . . 6/r32/esi 0xc/disp8 . # copy *(ebp+12) to esi
|
||||
# write/edx = table->write
|
||||
# var write/edx : int = table->write
|
||||
8b/copy 0/mod/indirect 6/rm32/esi . . . 2/r32/edx . . # copy *esi to edx
|
||||
# curr/esi = table->data
|
||||
# var curr/esi : (address byte) = table->data
|
||||
81 0/subop/add 3/mod/direct 6/rm32/esi . . . . . 0xc/imm32 # add to eax
|
||||
# max/edx = curr + write
|
||||
# var max/edx : (address byte) = curr + write
|
||||
01/add 3/mod/direct 2/rm32/edx . . . 6/r32/esi . . # add esi to edx
|
||||
$write-segments:loop:
|
||||
# if (curr >= max) break
|
||||
39/compare 3/mod/direct 6/rm32/esi . . . 2/r32/edx . . # compare esi with edx
|
||||
73/jump-if-greater-or-equal-unsigned $write-segments:break/disp8
|
||||
# stream/eax = table[i].stream
|
||||
# var stream/eax : (address stream byte) = table[i].stream
|
||||
8b/copy 1/mod/*+disp8 6/rm32/esi . . . 0/r32/eax 4/disp8 . # copy *(esi+4) to eax
|
||||
# write-stream-data(out, stream)
|
||||
# . . push args
|
||||
|
|
BIN
apps/braces
BIN
apps/braces
Binary file not shown.
|
@ -77,8 +77,8 @@ $subx-braces-main:end:
|
|||
|
||||
subx-braces: # in : (address buffered-file), out : (address buffered-file)
|
||||
# pseudocode:
|
||||
# var line : (stream byte 512)
|
||||
# var label-stack : (stack address 32) # at most 32 levels of nesting
|
||||
# var line : (ref stream byte 512)
|
||||
# var label-stack : (stack int 32) # at most 32 levels of nesting
|
||||
# var next-label-id : int = 1
|
||||
# while true
|
||||
# clear-stream(line)
|
||||
|
@ -123,20 +123,20 @@ subx-braces: # in : (address buffered-file), out : (address buffered-file)
|
|||
57/push-edi
|
||||
# esi = in
|
||||
8b/-> *(ebp+8) 6/r32/esi
|
||||
# var line/ecx : (stream byte 512)
|
||||
# var line/ecx : (ref stream byte 512)
|
||||
81 5/subop/subtract %esp 0x200/imm32
|
||||
68/push 0x200/imm32/length
|
||||
68/push 0/imm32/read
|
||||
68/push 0/imm32/write
|
||||
89/<- %ecx 4/r32/esp
|
||||
# var label-stack/edx : (stack int 32)
|
||||
# var label-stack/edx : (ref stack int 32)
|
||||
81 5/subop/subtract %esp 0x80/imm32
|
||||
68/push 0x80/imm32/length
|
||||
68/push 0/imm32/top
|
||||
89/<- %edx 4/r32/esp
|
||||
# next-label-id/ebx = 1
|
||||
# var next-label-id/ebx : int = 1
|
||||
c7 0/subop/copy %ebx 1/imm32
|
||||
# var word-slice/edi = {0, 0}
|
||||
# var word-slice/edi : (ref slice)
|
||||
68/push 0/imm32/end
|
||||
68/push 0/imm32/start
|
||||
89/<- %edi 4/r32/esp
|
||||
|
@ -201,8 +201,8 @@ $subx-braces:check-for-break:
|
|||
# if (!slice-starts-with?(word-slice, "break/")) goto next check
|
||||
# . eax = slice-starts-with?(word-slice, "break/")
|
||||
(slice-starts-with? %edi "break/")
|
||||
# . if (eax == 0) goto next check
|
||||
3d/compare-eax-and 0/imm32
|
||||
# . if (eax == false) goto next check
|
||||
3d/compare-eax-and 0/imm32/false
|
||||
74/jump-if-equal $subx-braces:check-for-loop/disp8
|
||||
$subx-braces:emit-break:
|
||||
(top %edx)
|
||||
|
@ -217,8 +217,8 @@ $subx-braces:check-for-loop:
|
|||
# if (!slice-starts-with?(word-slice, "loop/")) emit word
|
||||
# . eax = slice-starts-with?(word-slice, "loop/")
|
||||
(slice-starts-with? %edi "loop/")
|
||||
# . if (eax == 0) goto next check
|
||||
3d/compare-eax-and 0/imm32
|
||||
# . if (eax == false) goto next check
|
||||
3d/compare-eax-and 0/imm32/false
|
||||
74/jump-if-equal $subx-braces:emit-word-slice/disp8
|
||||
$subx-braces:emit-loop:
|
||||
(top %edx)
|
||||
|
|
BIN
apps/calls
BIN
apps/calls
Binary file not shown.
|
@ -51,8 +51,8 @@ Entry: # run tests if necessary, convert stdin if not
|
|||
e8/call kernel-string-equal?/disp32
|
||||
# . . discard args
|
||||
81 0/subop/add %esp 8/imm32
|
||||
# . if (eax == 0) goto run-main
|
||||
3d/compare-eax-and 0/imm32
|
||||
# . if (eax == false) goto run-main
|
||||
3d/compare-eax-and 0/imm32/false
|
||||
74/jump-if-equal $subx-calls-main:interactive/disp8
|
||||
# run-tests()
|
||||
e8/call run-tests/disp32
|
||||
|
@ -77,8 +77,8 @@ $subx-calls-main:end:
|
|||
|
||||
subx-calls: # in : (address buffered-file), out : (address buffered-file)
|
||||
# pseudocode:
|
||||
# var line : (stream byte 512)
|
||||
# var words : (stream slice 16) # at most function name and 15 args
|
||||
# var line : (ref stream byte 512)
|
||||
# var words : (ref stream slice 16) # at most function name and 15 args
|
||||
# while true
|
||||
# clear-stream(line)
|
||||
# read-line-buffered(in, line)
|
||||
|
@ -105,13 +105,13 @@ subx-calls: # in : (address buffered-file), out : (address buffered-file)
|
|||
51/push-ecx
|
||||
52/push-edx
|
||||
56/push-esi
|
||||
# var line/esi : (address stream byte) = stream(512)
|
||||
# var line/esi : (ref stream byte 512)
|
||||
81 5/subop/subtract %esp 0x200/imm32
|
||||
68/push 0x200/imm32/length
|
||||
68/push 0/imm32/read
|
||||
68/push 0/imm32/write
|
||||
89/<- %esi 4/r32/esp
|
||||
# var words/edx : (address stream slice) = stream(16, 8)
|
||||
# var words/edx : (ref stream slice 128) # 16 rows * 8 bytes/row
|
||||
81 5/subop/subtract %esp 0x80/imm32
|
||||
68/push 0x80/imm32/length
|
||||
68/push 0/imm32/read
|
||||
|
@ -233,7 +233,7 @@ $subx-calls:end:
|
|||
|
||||
parse-line: # line : (address stream byte), words : (address stream slice)
|
||||
# pseudocode:
|
||||
# var word-slice : (address slice)
|
||||
# var word-slice : (ref slice)
|
||||
# while true
|
||||
# word-slice = next-word-string-or-expression-without-metadata(line)
|
||||
# if slice-empty?(word-slice)
|
||||
|
@ -246,7 +246,7 @@ parse-line: # line : (address stream byte), words : (address stream slice)
|
|||
89/<- %ebp 4/r32/esp
|
||||
# . save registers
|
||||
51/push-ecx
|
||||
# var word-slice/ecx : (address slice) = {0, 0}
|
||||
# var word-slice/ecx : (ref slice)
|
||||
68/push 0/imm32/end
|
||||
68/push 0/imm32/start
|
||||
89/<- %ecx 4/r32/esp
|
||||
|
@ -268,8 +268,8 @@ $parse-line:check1:
|
|||
e8/call slice-empty?/disp32
|
||||
# . . discard args
|
||||
81 0/subop/add %esp 4/imm32
|
||||
# . if (eax != 0) break
|
||||
3d/compare-eax-and 0/imm32
|
||||
# . if (eax != false) break
|
||||
3d/compare-eax-and 0/imm32/false
|
||||
0f 85/jump-if-not-equal $parse-line:end/disp32
|
||||
#? # dump word-slice {{{
|
||||
#? # . write(2/stderr, "w: ")
|
||||
|
@ -381,9 +381,9 @@ emit-call: # out : (address buffered-file), words : (address stream slice)
|
|||
8b/-> *esi 1/r32/ecx
|
||||
81 5/subop/subtract %ecx 8/imm32
|
||||
0f 8c/jump-if-lesser $emit-call:error1/disp32
|
||||
# curr/ecx = &words->data[words->write-8]
|
||||
# var curr/ecx : (address slice) = &words->data[words->write-8]
|
||||
8d/copy-address *(esi+ecx+0xc) 1/r32/ecx
|
||||
# min/edx = words->data
|
||||
# var min/edx : (address byte) = words->data
|
||||
8d/copy-address *(esi+0xc) 2/r32/edx
|
||||
# - emit pushes
|
||||
$emit-call:push-loop:
|
||||
|
@ -391,15 +391,15 @@ $emit-call:push-loop:
|
|||
39/compare %ecx 2/r32/edx
|
||||
0f 8e/jump-if-lesser-or-equal $emit-call:call-instruction/disp32
|
||||
# if (*curr->start in '%' '*') goto push-rm32
|
||||
# . eax = curr->start
|
||||
# . var start/eax : (address byte) = curr->start
|
||||
8b/-> *ecx 0/r32/eax
|
||||
# . eax = (byte)*eax
|
||||
# . var c/eax : byte = *eax
|
||||
8b/-> *eax 0/r32/eax
|
||||
81 4/subop/and %eax 0xff/imm32
|
||||
# . if (eax == '%') goto push-rm32
|
||||
# . if (c == '%') goto push-rm32
|
||||
3d/compare-eax-and 0x25/imm32/percent
|
||||
74/jump-if-equal $emit-call:push-rm32/disp8
|
||||
# . if (eax == '*') goto push-rm32
|
||||
# . if (c == '*') goto push-rm32
|
||||
3d/compare-eax-and 0x2a/imm32/asterisk
|
||||
74/jump-if-equal $emit-call:push-rm32/disp8
|
||||
$emit-call:push-imm32:
|
||||
|
@ -741,7 +741,7 @@ test-subx-calls-processes-calls:
|
|||
5d/pop-to-ebp
|
||||
c3/return
|
||||
|
||||
next-word-string-or-expression-without-metadata: # line : (address stream), out : (address slice)
|
||||
next-word-string-or-expression-without-metadata: # line : (address stream byte), out : (address slice)
|
||||
# pseudocode:
|
||||
# skip-chars-matching(line, ' ')
|
||||
# if line->read >= line->write # end of line
|
||||
|
@ -830,7 +830,7 @@ $next-word-string-or-expression-without-metadata:check-for-comment:
|
|||
8d/copy-address *(esi+ecx+0xc) 0/r32/eax
|
||||
89/<- *edi 0/r32/eax
|
||||
# if (line->data[line->read] != '#') goto next check
|
||||
# . eax = line->data[line->read]
|
||||
# . var eax : byte = line->data[line->read]
|
||||
31/xor %eax 0/r32/eax
|
||||
8a/copy-byte *(esi+ecx+0xc) 0/r32/AL
|
||||
# . if (eax != '#') goto next check
|
||||
|
@ -1191,7 +1191,7 @@ test-next-word-string-or-expression-without-metadata:
|
|||
e8/call clear-stream/disp32
|
||||
# . . discard args
|
||||
81 0/subop/add %esp 4/imm32
|
||||
# var slice/ecx = {0, 0}
|
||||
# var slice/ecx : (ref slice)
|
||||
68/push 0/imm32/end
|
||||
68/push 0/imm32/start
|
||||
89/<- %ecx 4/r32/esp
|
||||
|
@ -1264,7 +1264,7 @@ test-next-word-string-or-expression-without-metadata-returns-whole-comment:
|
|||
e8/call clear-stream/disp32
|
||||
# . . discard args
|
||||
81 0/subop/add %esp 4/imm32
|
||||
# var slice/ecx = {0, 0}
|
||||
# var slice/ecx : (ref slice)
|
||||
68/push 0/imm32/end
|
||||
68/push 0/imm32/start
|
||||
89/<- %ecx 4/r32/esp
|
||||
|
@ -1337,7 +1337,7 @@ test-next-word-string-or-expression-without-metadata-returns-empty-slice-on-eof:
|
|||
e8/call clear-stream/disp32
|
||||
# . . discard args
|
||||
81 0/subop/add %esp 4/imm32
|
||||
# var slice/ecx = {0, 0}
|
||||
# var slice/ecx : (ref slice)
|
||||
68/push 0/imm32/end
|
||||
68/push 0/imm32/start
|
||||
89/<- %ecx 4/r32/esp
|
||||
|
@ -1379,7 +1379,7 @@ test-next-word-string-or-expression-without-metadata-returns-string-literal:
|
|||
e8/call clear-stream/disp32
|
||||
# . . discard args
|
||||
81 0/subop/add %esp 4/imm32
|
||||
# var slice/ecx = {0, 0}
|
||||
# var slice/ecx : (ref slice)
|
||||
68/push 0/imm32/end
|
||||
68/push 0/imm32/start
|
||||
89/<- %ecx 4/r32/esp
|
||||
|
@ -1442,7 +1442,7 @@ test-next-word-string-or-expression-without-metadata-returns-string-with-escapes
|
|||
e8/call clear-stream/disp32
|
||||
# . . discard args
|
||||
81 0/subop/add %esp 4/imm32
|
||||
# var slice/ecx = {0, 0}
|
||||
# var slice/ecx : (ref slice)
|
||||
68/push 0/imm32/end
|
||||
68/push 0/imm32/start
|
||||
89/<- %ecx 4/r32/esp
|
||||
|
@ -1505,7 +1505,7 @@ test-next-word-string-or-expression-without-metadata-returns-whole-expression:
|
|||
e8/call clear-stream/disp32
|
||||
# . . discard args
|
||||
81 0/subop/add %esp 4/imm32
|
||||
# var slice/ecx = {0, 0}
|
||||
# var slice/ecx : (ref slice)
|
||||
68/push 0/imm32/end
|
||||
68/push 0/imm32/start
|
||||
89/<- %ecx 4/r32/esp
|
||||
|
@ -1568,7 +1568,7 @@ test-next-word-string-or-expression-without-metadata-returns-eol-on-trailing-clo
|
|||
e8/call clear-stream/disp32
|
||||
# . . discard args
|
||||
81 0/subop/add %esp 4/imm32
|
||||
# var slice/ecx = {0, 0}
|
||||
# var slice/ecx : (ref slice)
|
||||
68/push 0/imm32/end
|
||||
68/push 0/imm32/start
|
||||
89/<- %ecx 4/r32/esp
|
||||
|
@ -1623,7 +1623,7 @@ test-next-word-string-or-expression-without-metadata-handles-comment-after-trail
|
|||
e8/call clear-stream/disp32
|
||||
# . . discard args
|
||||
81 0/subop/add %esp 4/imm32
|
||||
# var slice/ecx = {0, 0}
|
||||
# var slice/ecx : (ref slice)
|
||||
68/push 0/imm32/end
|
||||
68/push 0/imm32/start
|
||||
89/<- %ecx 4/r32/esp
|
||||
|
@ -1678,7 +1678,7 @@ test-next-word-string-or-expression-without-metadata-handles-newline-after-trail
|
|||
e8/call clear-stream/disp32
|
||||
# . . discard args
|
||||
81 0/subop/add %esp 4/imm32
|
||||
# var slice/ecx = {0, 0}
|
||||
# var slice/ecx : (ref slice)
|
||||
68/push 0/imm32/end
|
||||
68/push 0/imm32/start
|
||||
89/<- %ecx 4/r32/esp
|
||||
|
@ -1733,7 +1733,7 @@ test-next-word-string-or-expression-without-metadata-stops-at-close-paren:
|
|||
e8/call clear-stream/disp32
|
||||
# . . discard args
|
||||
81 0/subop/add %esp 4/imm32
|
||||
# var slice/ecx = {0, 0}
|
||||
# var slice/ecx : (ref slice)
|
||||
68/push 0/imm32/end
|
||||
68/push 0/imm32/start
|
||||
89/<- %ecx 4/r32/esp
|
||||
|
|
BIN
apps/crenshaw2-1
BIN
apps/crenshaw2-1
Binary file not shown.
|
@ -57,8 +57,8 @@ Entry: # run tests if necessary, call 'compile' if not
|
|||
e8/call kernel-string-equal?/disp32
|
||||
# . . discard args
|
||||
81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp
|
||||
# . if (eax == 0) goto run-main
|
||||
3d/compare-eax-and 0/imm32
|
||||
# . if (eax == false) goto run-main
|
||||
3d/compare-eax-and 0/imm32/false
|
||||
74/jump-if-equal $run-main/disp8
|
||||
# run-tests()
|
||||
e8/call run-tests/disp32
|
||||
|
@ -67,7 +67,7 @@ Entry: # run tests if necessary, call 'compile' if not
|
|||
eb/jump $main:end/disp8
|
||||
$run-main:
|
||||
# - otherwise read a program from stdin and emit its translation to stdout
|
||||
# var ed/eax : exit-descriptor
|
||||
# var ed/eax : (ref exit-descriptor)
|
||||
81 5/subop/subtract 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # subtract from esp
|
||||
89/copy 3/mod/direct 0/rm32/eax . . . 4/r32/esp . . # copy esp to eax
|
||||
# configure ed to really exit()
|
||||
|
@ -90,7 +90,7 @@ $main:end:
|
|||
cd/syscall 0x80/imm8
|
||||
|
||||
# the main entry point
|
||||
compile: # in : (address buffered-file), out : fd or (address stream), err : fd or (address stream), ed : (address exit-descriptor)
|
||||
compile: # in : (address buffered-file), out : fd or (address stream byte), err : fd or (address stream byte), ed : (address exit-descriptor)
|
||||
# . prologue
|
||||
55/push-ebp
|
||||
89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp
|
||||
|
@ -105,7 +105,7 @@ compile: # in : (address buffered-file), out : fd or (address stream), err : fd
|
|||
e8/call get-char/disp32
|
||||
# . . discard args
|
||||
81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp
|
||||
# var num/ecx : (address stream) on the stack
|
||||
# var num/ecx : (ref 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.
|
||||
# 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.
|
||||
|
@ -187,10 +187,11 @@ $compile:end:
|
|||
5d/pop-to-ebp
|
||||
c3/return
|
||||
|
||||
# Read a single digit into 'out'. Abort if there are none, or if there is no space in 'out'.
|
||||
# Input comes from the global variable 'Look', and we leave the next byte from
|
||||
# 'in' into it on exit.
|
||||
get-num: # in : (address buffered-file), out : (address stream), err : fd or (address stream), ed : (address exit-descriptor)
|
||||
# Read a single digit into 'out'. Abort if there are none, or if there is no
|
||||
# space in 'out'.
|
||||
# Input comes from the global variable 'Look' (first byte) and the argument
|
||||
# 'in' (rest). We leave the next byte from 'in' into 'Look' on exit.
|
||||
get-num: # in : (address buffered-file), out : (address stream byte), err : fd or (address stream byte), ed : (address exit-descriptor)
|
||||
# pseudocode:
|
||||
# if (!is-digit?(Look)) expected(ed, err, "integer")
|
||||
# if out->write >= out->length
|
||||
|
@ -221,8 +222,8 @@ get-num: # in : (address buffered-file), out : (address stream), err : fd or (a
|
|||
e8/call is-digit?/disp32
|
||||
# . . discard args
|
||||
81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp
|
||||
# . if (eax == 0)
|
||||
3d/compare-eax-and 0/imm32
|
||||
# . if (eax == false)
|
||||
3d/compare-eax-and 0/imm32/false
|
||||
75/jump-if-not-equal $get-num:main/disp8
|
||||
# . expected(ed, err, "integer")
|
||||
# . . push args
|
||||
|
@ -251,6 +252,7 @@ $get-num:main:
|
|||
8b/copy 0/mod/indirect 7/rm32/edi . . . 1/r32/ecx . . # copy *edi to ecx
|
||||
# edx = out->length
|
||||
8b/copy 1/mod/*+disp8 7/rm32/edi . . . 2/r32/edx 8/disp8 . # copy *(edi+8) to edx
|
||||
$get-num:loop:
|
||||
# if (out->write >= out->length) error
|
||||
39/compare 3/mod/direct 2/rm32/edx . . . 1/r32/ecx . . # compare edx with ecx
|
||||
7d/jump-if-lesser $get-num:stage2/disp8
|
||||
|
@ -337,7 +339,7 @@ test-get-num-reads-single-digit:
|
|||
# . . discard args
|
||||
81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp
|
||||
# initialize exit-descriptor 'ed' for the call to 'get-num' below
|
||||
# . var ed/eax : exit-descriptor
|
||||
# . var ed/eax : (ref exit-descriptor)
|
||||
81 5/subop/subtract 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # subtract from esp
|
||||
89/copy 3/mod/direct 0/rm32/eax . . . 4/r32/esp . . # copy esp to eax
|
||||
# . tailor-exit-descriptor(ed, 16)
|
||||
|
@ -426,7 +428,7 @@ test-get-num-aborts-on-non-digit-in-Look:
|
|||
# . . discard args
|
||||
81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp
|
||||
# initialize exit-descriptor 'ed' for the call to 'get-num' below
|
||||
# . var ed/eax : (address exit-descriptor)
|
||||
# . var ed/eax : (ref exit-descriptor)
|
||||
81 5/subop/subtract 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # subtract from esp
|
||||
89/copy 3/mod/direct 0/rm32/eax . . . 4/r32/esp . . # copy esp to eax
|
||||
# . tailor-exit-descriptor(ed, 16)
|
||||
|
@ -468,7 +470,7 @@ test-get-num-aborts-on-non-digit-in-Look:
|
|||
## helpers
|
||||
|
||||
# write(f, "Error: "+s+" expected\n") then stop(ed, 1)
|
||||
expected: # ed : (address exit-descriptor), f : fd or (address stream), s : (address array byte)
|
||||
expected: # ed : (address exit-descriptor), f : fd or (address stream byte), s : (address array byte)
|
||||
# . prologue
|
||||
55/push-ebp
|
||||
89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp
|
||||
|
@ -488,7 +490,7 @@ expected: # ed : (address exit-descriptor), f : fd or (address stream), s : (ad
|
|||
e8/call write/disp32
|
||||
# . . discard args
|
||||
81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp
|
||||
# write(f, " expected")
|
||||
# write(f, " expected\n")
|
||||
# . . push args
|
||||
68/push " expected\n"/imm32
|
||||
ff 6/subop/push 1/mod/*+disp8 5/rm32/ebp . . . . 0xc/disp8 . # push *(ebp+12)
|
||||
|
|
Binary file not shown.
|
@ -57,8 +57,8 @@ Entry: # run tests if necessary, call 'compile' if not
|
|||
e8/call kernel-string-equal?/disp32
|
||||
# . . discard args
|
||||
81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp
|
||||
# . if (eax == 0) goto run-main
|
||||
3d/compare-eax-and 0/imm32
|
||||
# . if (eax == false) goto run-main
|
||||
3d/compare-eax-and 0/imm32/false
|
||||
74/jump-if-equal $run-main/disp8
|
||||
# run-tests()
|
||||
e8/call run-tests/disp32
|
||||
|
@ -67,7 +67,7 @@ Entry: # run tests if necessary, call 'compile' if not
|
|||
eb/jump $main:end/disp8
|
||||
$run-main:
|
||||
# - otherwise read a program from stdin and emit its translation to stdout
|
||||
# var ed/eax : exit-descriptor
|
||||
# var ed/eax : (ref exit-descriptor)
|
||||
81 5/subop/subtract 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # subtract from esp
|
||||
89/copy 3/mod/direct 0/rm32/eax . . . 4/r32/esp . . # copy esp to eax
|
||||
# configure ed to really exit()
|
||||
|
@ -90,7 +90,7 @@ $main:end:
|
|||
cd/syscall 0x80/imm8
|
||||
|
||||
# the main entry point
|
||||
compile: # in : (address buffered-file), out : fd or (address stream), err : fd or (address stream), ed : (address exit-descriptor)
|
||||
compile: # in : (address buffered-file), out : fd or (address stream byte), err : fd or (address stream byte), ed : (address exit-descriptor)
|
||||
# . prologue
|
||||
55/push-ebp
|
||||
89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp
|
||||
|
@ -105,7 +105,7 @@ compile: # in : (address buffered-file), out : fd or (address stream), err : fd
|
|||
e8/call get-char/disp32
|
||||
# . . discard args
|
||||
81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp
|
||||
# var num/ecx : (address stream) on the stack
|
||||
# var num/ecx : (ref 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.
|
||||
# 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.
|
||||
|
@ -191,7 +191,7 @@ $compile:end:
|
|||
# no space in 'out'.
|
||||
# Input comes from the global variable 'Look' (first byte) and the argument
|
||||
# 'in' (rest). We leave the next byte from 'in' into 'Look' on exit.
|
||||
get-num: # in : (address buffered-file), out : (address stream), err : fd or (address stream), ed : (address exit-descriptor)
|
||||
get-num: # in : (address buffered-file), out : (address stream byte), err : fd or (address stream byte), ed : (address exit-descriptor)
|
||||
# pseudocode:
|
||||
# if (!is-digit?(Look)) expected(ed, err, "integer")
|
||||
# do
|
||||
|
@ -227,8 +227,8 @@ get-num: # in : (address buffered-file), out : (address stream), err : fd or (a
|
|||
e8/call is-digit?/disp32
|
||||
# . . discard args
|
||||
81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp
|
||||
# . if (eax == 0)
|
||||
3d/compare-eax-and 0/imm32
|
||||
# . if (eax == false)
|
||||
3d/compare-eax-and 0/imm32/false
|
||||
75/jump-if-not-equal $get-num:main/disp8
|
||||
# . expected(ed, err, "integer")
|
||||
# . . push args
|
||||
|
@ -292,8 +292,8 @@ $get-num:loop-stage2:
|
|||
e8/call is-digit?/disp32
|
||||
# . . discard args
|
||||
81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp
|
||||
# . if (eax != 0) loop
|
||||
3d/compare-eax-and 0/imm32
|
||||
# . if (eax != false) loop
|
||||
3d/compare-eax-and 0/imm32/false
|
||||
0f 85/jump-if-not-equal $get-num:loop/disp32
|
||||
$get-num:loop-end:
|
||||
# persist necessary variables from registers
|
||||
|
@ -355,7 +355,7 @@ test-get-num-reads-single-digit:
|
|||
# . . discard args
|
||||
81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp
|
||||
# initialize exit-descriptor 'ed' for the call to 'get-num' below
|
||||
# . var ed/eax : exit-descriptor
|
||||
# . var ed/eax : (ref exit-descriptor)
|
||||
81 5/subop/subtract 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # subtract from esp
|
||||
89/copy 3/mod/direct 0/rm32/eax . . . 4/r32/esp . . # copy esp to eax
|
||||
# . tailor-exit-descriptor(ed, 16)
|
||||
|
@ -444,7 +444,7 @@ test-get-num-aborts-on-non-digit-in-Look:
|
|||
# . . discard args
|
||||
81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp
|
||||
# initialize exit-descriptor 'ed' for the call to 'get-num' below
|
||||
# . var ed/eax : (address exit-descriptor)
|
||||
# . var ed/eax : (ref exit-descriptor)
|
||||
81 5/subop/subtract 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # subtract from esp
|
||||
89/copy 3/mod/direct 0/rm32/eax . . . 4/r32/esp . . # copy esp to eax
|
||||
# . tailor-exit-descriptor(ed, 16)
|
||||
|
@ -527,7 +527,7 @@ test-get-num-reads-multiple-digits:
|
|||
# . . discard args
|
||||
81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp
|
||||
# initialize exit-descriptor 'ed' for the call to 'get-num' below
|
||||
# . var ed/eax : (address exit-descriptor)
|
||||
# . var ed/eax : (ref exit-descriptor)
|
||||
81 5/subop/subtract 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # subtract from esp
|
||||
89/copy 3/mod/direct 0/rm32/eax . . . 4/r32/esp . . # copy esp to eax
|
||||
# . tailor-exit-descriptor(ed, 16)
|
||||
|
@ -616,7 +616,7 @@ test-get-num-reads-multiple-digits-followed-by-nondigit:
|
|||
# . . discard args
|
||||
81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp
|
||||
# initialize exit-descriptor 'ed' for the call to 'get-num' below
|
||||
# . var ed/eax : (address exit-descriptor)
|
||||
# . var ed/eax : (ref exit-descriptor)
|
||||
81 5/subop/subtract 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # subtract from esp
|
||||
89/copy 3/mod/direct 0/rm32/eax . . . 4/r32/esp . . # copy esp to eax
|
||||
# . tailor-exit-descriptor(ed, 16)
|
||||
|
@ -664,7 +664,7 @@ test-get-num-reads-multiple-digits-followed-by-nondigit:
|
|||
## helpers
|
||||
|
||||
# write(f, "Error: "+s+" expected\n") then stop(ed, 1)
|
||||
expected: # ed : (address exit-descriptor), f : fd or (address stream), s : (address array byte)
|
||||
expected: # ed : (address exit-descriptor), f : fd or (address stream byte), s : (address array byte)
|
||||
# . prologue
|
||||
55/push-ebp
|
||||
89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp
|
||||
|
|
BIN
apps/dquotes
BIN
apps/dquotes
Binary file not shown.
|
@ -46,8 +46,8 @@ Entry: # run tests if necessary, convert stdin if not
|
|||
e8/call kernel-string-equal?/disp32
|
||||
# . . discard args
|
||||
81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp
|
||||
# . if (eax == 0) goto interactive
|
||||
3d/compare-eax-and 0/imm32
|
||||
# . if (eax == false) goto interactive
|
||||
3d/compare-eax-and 0/imm32/false
|
||||
74/jump-if-equal $subx-dquotes-main:interactive/disp8
|
||||
# run-tests()
|
||||
e8/call run-tests/disp32
|
||||
|
@ -56,7 +56,7 @@ Entry: # run tests if necessary, convert stdin if not
|
|||
eb/jump $subx-dquotes-main:end/disp8
|
||||
$subx-dquotes-main:interactive:
|
||||
# - otherwise convert stdin
|
||||
# var ed/eax : exit-descriptor
|
||||
# var ed/eax : (ref exit-descriptor)
|
||||
81 5/subop/subtract 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # subtract from esp
|
||||
89/copy 3/mod/direct 0/rm32/eax . . . 4/r32/esp . . # copy esp to eax
|
||||
# configure ed to really exit()
|
||||
|
@ -84,7 +84,7 @@ $subx-dquotes-main:end:
|
|||
|
||||
subx-dquotes: # in : (address buffered-file), out : (address buffered-file)
|
||||
# pseudocode:
|
||||
# var line : (stream byte 512)
|
||||
# var line : (ref stream byte 512)
|
||||
# var new-data-segment : (handle stream byte) = new-stream(Heap, Segment-size, 1)
|
||||
#
|
||||
# write(new-data-segment, "== data\n")
|
||||
|
@ -125,13 +125,13 @@ subx-dquotes: # in : (address buffered-file), out : (address buffered-file)
|
|||
53/push-ebx
|
||||
56/push-esi
|
||||
57/push-edi
|
||||
# var line/ecx : (address stream byte) = stream(512)
|
||||
# var line/ecx : (ref stream byte 512)
|
||||
81 5/subop/subtract 3/mod/direct 4/rm32/esp . . . . . 0x200/imm32 # subtract from esp
|
||||
68/push 0x200/imm32/length
|
||||
68/push 0/imm32/read
|
||||
68/push 0/imm32/write
|
||||
89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx
|
||||
# var word-slice/edx = {0, 0}
|
||||
# var word-slice/edx : (ref slice)
|
||||
68/push 0/imm32/end
|
||||
68/push 0/imm32/start
|
||||
89/copy 3/mod/direct 2/rm32/edx . . . 4/r32/esp . . # copy esp to edx
|
||||
|
@ -193,17 +193,17 @@ $subx-dquotes:check1:
|
|||
e8/call slice-empty?/disp32
|
||||
# . . discard args
|
||||
81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp
|
||||
# . if (eax != 0) break
|
||||
3d/compare-eax-and 0/imm32
|
||||
# . if (eax != false) break
|
||||
3d/compare-eax-and 0/imm32/false
|
||||
0f 85/jump-if-not-equal $subx-dquotes:next-line/disp32
|
||||
$subx-dquotes:check-for-comment:
|
||||
# if (slice-starts-with?(word-slice, "#")) continue
|
||||
# . start/esi = word-slice->start
|
||||
# . var start/esi : (address byte) = word-slice->start
|
||||
8b/copy 0/mod/indirect 2/rm32/edx . . . 6/r32/esi . . # copy *edx to esi
|
||||
# . c/eax = *start
|
||||
# . var c/eax : byte = *start
|
||||
31/xor 3/mod/direct 0/rm32/eax . . . 0/r32/eax . . # clear eax
|
||||
8a/copy-byte 0/mod/indirect 6/rm32/esi . . . 0/r32/AL . . # copy byte at *esi to AL
|
||||
# . if (eax == '#') continue
|
||||
# . if (c == '#') continue
|
||||
3d/compare-eax-and 0x23/imm32/hash
|
||||
74/jump-if-equal $subx-dquotes:word-loop/disp8
|
||||
$subx-dquotes:check-for-string-literal:
|
||||
|
@ -287,7 +287,7 @@ $subx-dquotes:end:
|
|||
|
||||
# Write out 'string-literal' in a new format to 'out-segment', assign it a new
|
||||
# label, and write the new label out to 'out'.
|
||||
process-string-literal: # string-literal : (address slice), out : (address buffered-file), out-segment : (address stream)
|
||||
process-string-literal: # string-literal : (address slice), out : (address buffered-file), out-segment : (address stream byte)
|
||||
# pseudocode:
|
||||
# print(out-segment, "_string#{Next-string-literal}:\n")
|
||||
# emit-string-literal-data(out-segment, string-literal)
|
||||
|
@ -300,7 +300,7 @@ process-string-literal: # string-literal : (address slice), out : (address buff
|
|||
89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp
|
||||
# . save registers
|
||||
51/push-ecx
|
||||
# var int32-stream/ecx = stream(10) # number of decimal digits a 32-bit number can have
|
||||
# var int32-stream/ecx : (ref stream byte 10) # number of decimal digits a 32-bit number can have
|
||||
81 5/subop/subtract 3/mod/direct 4/rm32/esp . . . . . 0xa/imm32 # subtract from esp
|
||||
68/push 0xa/imm32/decimal-digits-in-32bit-number
|
||||
68/push 0/imm32/read
|
||||
|
@ -846,7 +846,7 @@ test-subx-dquotes-processes-string-literals:
|
|||
c3/return
|
||||
|
||||
# generate the data segment contents byte by byte for a given slice
|
||||
emit-string-literal-data: # out : (address stream), word : (address slice)
|
||||
emit-string-literal-data: # out : (address stream byte), word : (address slice)
|
||||
# pseudocode
|
||||
# len = string-length-at-start-of-slice(word->start, word->end)
|
||||
# print(out, "#{len}/imm32 ")
|
||||
|
@ -885,14 +885,14 @@ emit-string-literal-data: # out : (address stream), word : (address slice)
|
|||
56/push-esi
|
||||
# esi = word
|
||||
8b/copy 1/mod/*+disp8 5/rm32/ebp . . . 6/r32/esi 0xc/disp8 . # copy *(ebp+12) to esi
|
||||
# idx/ebx = 0
|
||||
# var idx/ebx : int = 0
|
||||
31/xor 3/mod/direct 3/rm32/ebx . . . 3/r32/ebx . . # clear ebx
|
||||
# curr/edx = word->start
|
||||
# var curr/edx : (address byte) = word->start
|
||||
8b/copy 0/mod/indirect 6/rm32/esi . . . 2/r32/edx . . # copy *esi to edx
|
||||
# max/esi = word->end
|
||||
# var max/esi : (address byte) = word->end
|
||||
8b/copy 1/mod/*+disp8 6/rm32/esi . . . 6/r32/esi 4/disp8 . # copy *(esi+4) to esi
|
||||
$emit-string-literal-data:emit-length:
|
||||
# len/eax = string-length-at-start-of-slice(word->start, word->end)
|
||||
# var len/eax : int = string-length-at-start-of-slice(word->start, word->end)
|
||||
# . . push args
|
||||
56/push-esi
|
||||
52/push-edx
|
||||
|
@ -920,7 +920,7 @@ $emit-string-literal-data:emit-length:
|
|||
$emit-string-literal-data:loop-init:
|
||||
# ++curr # skip initial '"'
|
||||
42/increment-edx
|
||||
# c/ecx = 0
|
||||
# var c/ecx : byte = 0
|
||||
31/xor 3/mod/direct 1/rm32/ecx . . . 1/r32/ecx . . # clear ecx
|
||||
$emit-string-literal-data:loop:
|
||||
# if (curr >= max) break
|
||||
|
@ -955,15 +955,15 @@ $emit-string-literal-data:emit:
|
|||
# . . discard args
|
||||
81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp
|
||||
# if (is-alphanumeric?(*curr)) print(out, "/#{*curr}")
|
||||
# . eax = is-alphanumeric?(CL)
|
||||
# . var eax : boolean = is-alphanumeric?(CL)
|
||||
# . . push args
|
||||
51/push-ecx
|
||||
# . . call
|
||||
e8/call is-alphanumeric?/disp32
|
||||
# . . discard args
|
||||
81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp
|
||||
# . if (eax == 0) goto char-done
|
||||
3d/compare-eax-and 0/imm32
|
||||
# . if (eax == false) goto char-done
|
||||
3d/compare-eax-and 0/imm32/false
|
||||
74/jump-if-equal $emit-string-literal-data:char-done/disp8
|
||||
# . write(out, "/")
|
||||
# . . push args
|
||||
|
@ -1027,22 +1027,22 @@ is-alphanumeric?: # c : int -> eax : boolean
|
|||
89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp
|
||||
# eax = c
|
||||
8b/copy 1/mod/*+disp8 5/rm32/ebp . . . 0/r32/eax 8/disp8 . # copy *(ebp+8) to eax
|
||||
# if (eax < '0') return false
|
||||
# if (c < '0') return false
|
||||
3d/compare-eax-with 0x30/imm32/0
|
||||
7c/jump-if-lesser $is-alphanumeric?:false/disp8
|
||||
# if (eax <= '9') return true
|
||||
# if (c <= '9') return true
|
||||
3d/compare-eax-with 0x39/imm32/9
|
||||
7e/jump-if-lesser-or-equal $is-alphanumeric?:true/disp8
|
||||
# if (eax < 'A') return false
|
||||
# if (c < 'A') return false
|
||||
3d/compare-eax-with 0x41/imm32/A
|
||||
7c/jump-if-lesser $is-alphanumeric?:false/disp8
|
||||
# if (eax <= 'Z') return true
|
||||
# if (c <= 'Z') return true
|
||||
3d/compare-eax-with 0x5a/imm32/Z
|
||||
7e/jump-if-lesser-or-equal $is-alphanumeric?:true/disp8
|
||||
# if (eax < 'a') return false
|
||||
# if (c < 'a') return false
|
||||
3d/compare-eax-with 0x61/imm32/a
|
||||
7c/jump-if-lesser $is-alphanumeric?:false/disp8
|
||||
# if (eax <= 'z') return true
|
||||
# if (c <= 'z') return true
|
||||
3d/compare-eax-with 0x7a/imm32/z
|
||||
7e/jump-if-lesser-or-equal $is-alphanumeric?:true/disp8
|
||||
# return false
|
||||
|
@ -1381,7 +1381,7 @@ test-emit-string-literal-data-handles-newline-escape:
|
|||
# emit everything from a word except the initial datum
|
||||
emit-metadata: # out : (address buffered-file), word : (address slice)
|
||||
# pseudocode
|
||||
# var slice = {0, word->end}
|
||||
# var slice : (ref slice) = {0, word->end}
|
||||
# curr = word->start
|
||||
# if *curr == '"'
|
||||
# curr = skip-string-in-slice(curr, word->end)
|
||||
|
@ -1406,11 +1406,11 @@ emit-metadata: # out : (address buffered-file), word : (address slice)
|
|||
56/push-esi
|
||||
# esi = word
|
||||
8b/copy 1/mod/*+disp8 5/rm32/ebp . . . 6/r32/esi 0xc/disp8 . # copy *(ebp+12) to esi
|
||||
# curr/ecx = word->start
|
||||
# var curr/ecx : (address byte) = word->start
|
||||
8b/copy 0/mod/indirect 6/rm32/esi . . . 1/r32/ecx . . # copy *esi to ecx
|
||||
# end/edx = word->end
|
||||
# var end/edx : (address byte) = word->end
|
||||
8b/copy 1/mod/*+disp8 6/rm32/esi . . . 2/r32/edx 4/disp8 . # copy *(esi+4) to edx
|
||||
# var slice/ebx = {0, end}
|
||||
# var slice/ebx : (ref slice) = {0, end}
|
||||
52/push-edx
|
||||
68/push 0/imm32
|
||||
89/copy 3/mod/direct 3/rm32/ebx . . . 4/r32/esp . . # copy esp to ebx
|
||||
|
@ -1790,9 +1790,9 @@ string-length-at-start-of-slice: # curr : (address byte), end : (address byte)
|
|||
8b/copy 1/mod/*+disp8 5/rm32/ebp . . 1/r32/ecx 8/disp8 . # copy *(ebp+8) to ecx
|
||||
# edx = end
|
||||
8b/copy 1/mod/*+disp8 5/rm32/ebp . . 2/r32/edx 0xc/disp8 . # copy *(ebp+12) to edx
|
||||
# length/eax = 0
|
||||
# var length/eax : int = 0
|
||||
31/xor 3/mod/direct 0/rm32/eax . . . 0/r32/eax . . # clear eax
|
||||
# ebx = 0
|
||||
# var c/ebx : byte = 0
|
||||
31/xor 3/mod/direct 3/rm32/ebx . . . 3/r32/ebx . . # clear ebx
|
||||
# skip initial dquote
|
||||
41/increment-ecx
|
||||
|
@ -1800,14 +1800,14 @@ $string-length-at-start-of-slice:loop:
|
|||
# if (curr >= end) return length
|
||||
39/compare 3/mod/direct 1/rm32/ecx . . . 2/r32/edx . . # compare ecx with edx
|
||||
73/jump-if-greater-unsigned-or-equal $string-length-at-start-of-slice:end/disp8
|
||||
# BL = *curr
|
||||
# c = *curr
|
||||
8a/copy-byte 0/mod/indirect 1/rm32/ecx . . . 3/r32/BL . . # copy byte at *ecx to BL
|
||||
$string-length-at-start-of-slice:dquote:
|
||||
# if (ebx == '"') break
|
||||
# if (c == '"') break
|
||||
81 7/subop/compare 3/mod/direct 3/rm32/ebx . . . . . 0x22/imm32/dquote # compare ebx
|
||||
74/jump-if-equal $string-length-at-start-of-slice:end/disp8
|
||||
$string-length-at-start-of-slice:check-for-escape:
|
||||
# if (ebx == '\') escape next char
|
||||
# if (c == '\') escape next char
|
||||
81 7/subop/compare 3/mod/direct 3/rm32/ebx . . . . . 0x5c/imm32/backslash # compare ebx
|
||||
75/jump-if-not-equal $string-length-at-start-of-slice:continue/disp8
|
||||
$string-length-at-start-of-slice:escape:
|
||||
|
|
BIN
apps/factorial
BIN
apps/factorial
Binary file not shown.
|
@ -45,8 +45,8 @@ Entry: # run tests if necessary, compute `factorial(5)` if not
|
|||
e8/call kernel-string-equal?/disp32
|
||||
# . . discard args
|
||||
81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp
|
||||
# . if (eax == 0) goto run-main
|
||||
3d/compare-eax-and 0/imm32
|
||||
# . if (eax == false) goto run-main
|
||||
3d/compare-eax-and 0/imm32/false
|
||||
74/jump-if-equal $run-main/disp8
|
||||
# run-tests()
|
||||
e8/call run-tests/disp32
|
||||
|
@ -77,10 +77,10 @@ factorial: # n : int -> int/eax
|
|||
b8/copy-to-eax 1/imm32
|
||||
81 7/subop/compare 1/mod/*+disp8 5/rm32/ebp . . . . 8/disp8 1/imm32 # compare *(ebp+8)
|
||||
7e/jump-if-<= $factorial:end/disp8
|
||||
# ebx = n-1
|
||||
# var ebx : int = n-1
|
||||
8b/copy 1/mod/*+disp8 5/rm32/ebp . . 3/r32/ebx 8/disp8 . # copy *(ebp+8) to ebx
|
||||
4b/decrement-ebx
|
||||
# eax = factorial(n-1)
|
||||
# var eax : int = factorial(n-1)
|
||||
# . . push args
|
||||
53/push-ebx
|
||||
# . . call
|
||||
|
|
BIN
apps/handle
BIN
apps/handle
Binary file not shown.
|
@ -44,7 +44,7 @@ $handle-main:end:
|
|||
b8/copy-to-eax 1/imm32/exit
|
||||
cd/syscall 0x80/imm8
|
||||
|
||||
new: # ad : (address allocation-descriptor), n : int, out : (address handle)
|
||||
new: # ad : (address allocation-descriptor), n : int, out : (handle _)
|
||||
# . prologue
|
||||
55/push-ebp
|
||||
89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp
|
||||
|
@ -55,7 +55,7 @@ new: # ad : (address allocation-descriptor), n : int, out : (address handle)
|
|||
# ecx = n+4
|
||||
8b/copy 1/mod/*+disp8 5/rm32/ebp . . . 1/r32/ecx 0xc/disp8 . # copy *(ebp+12) to ecx
|
||||
81 0/subop/add 3/mod/direct 1/rm32/ecx . . . . . 4/imm32 # add to ecx
|
||||
# eax = allocate(ad, ecx)
|
||||
# var eax : (handle _) = allocate(ad, ecx)
|
||||
# . . push args
|
||||
51/push-ecx
|
||||
ff 6/subop/push 1/mod/*+disp8 5/rm32/ebp . . . . 8/disp8 . # push *(ebp+8)
|
||||
|
@ -96,7 +96,7 @@ test-new:
|
|||
# . prologue
|
||||
55/push-ebp
|
||||
89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp
|
||||
# var heap/edx : (address allocation-descriptor) = {0, 0}
|
||||
# var heap/edx : (ref allocation-descriptor)
|
||||
68/push 0/imm32/limit
|
||||
68/push 0/imm32/curr
|
||||
89/copy 3/mod/direct 2/rm32/edx . . . 4/r32/esp . . # copy esp to edx
|
||||
|
@ -110,7 +110,7 @@ test-new:
|
|||
81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp
|
||||
# *Next-alloc-id = 0x34
|
||||
c7 0/subop/copy 0/mod/indirect 5/rm32/.disp32 . . . Next-alloc-id/disp32 0x34/imm32 # copy to *Next-alloc-id
|
||||
# var handle/ecx = {0, 0}
|
||||
# var handle/ecx : (ref handle)
|
||||
68/push 0/imm32/address
|
||||
68/push 0/imm32/alloc-id
|
||||
89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx
|
||||
|
@ -166,7 +166,7 @@ _pending-test-new-failure:
|
|||
# . *Next-alloc-id = 0x34
|
||||
c7 0/subop/copy 0/mod/indirect 5/rm32/.disp32 . . . Next-alloc-id/disp32 0x34/imm32 # copy to *Next-alloc-id
|
||||
# define an allocation-descriptor with no space left
|
||||
# . var ad/eax : (address allocation-descriptor) = {0x10, 0x10}
|
||||
# . var ad/eax : (ref allocation-descriptor) = {0x10, 0x10}
|
||||
68/push 0x10/imm32/limit
|
||||
68/push 0x10/imm32/curr
|
||||
89/copy 3/mod/direct 0/rm32/eax . . . 4/r32/esp . . # copy esp to eax
|
||||
|
@ -282,7 +282,7 @@ test-lookup-success:
|
|||
55/push-ebp
|
||||
89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp
|
||||
# . save registers
|
||||
# var heap/ebx : (address allocation-descriptor) = {0, 0}
|
||||
# var heap/ebx : (ref allocation-descriptor)
|
||||
68/push 0/imm32/limit
|
||||
68/push 0/imm32/curr
|
||||
89/copy 3/mod/direct 3/rm32/ebx . . . 4/r32/esp . . # copy esp to ebx
|
||||
|
@ -294,7 +294,7 @@ test-lookup-success:
|
|||
e8/call new-segment/disp32
|
||||
# . . discard args
|
||||
81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp
|
||||
# var handle/ecx = {0, 0}
|
||||
# var handle/ecx : (ref handle)
|
||||
68/push 0/imm32/address
|
||||
68/push 0/imm32/alloc-id
|
||||
89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx
|
||||
|
@ -350,7 +350,7 @@ test-lookup-failure:
|
|||
# . prologue
|
||||
55/push-ebp
|
||||
89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp
|
||||
# var heap/esi : (address allocation-descriptor) = {0, 0}
|
||||
# var heap/esi : (ref allocation-descriptor)
|
||||
68/push 0/imm32/limit
|
||||
68/push 0/imm32/curr
|
||||
89/copy 3/mod/direct 6/rm32/esi . . . 4/r32/esp . . # copy esp to esi
|
||||
|
@ -362,7 +362,7 @@ test-lookup-failure:
|
|||
e8/call new-segment/disp32
|
||||
# . . discard args
|
||||
81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp
|
||||
# var h1/ecx = {0, 0}
|
||||
# var h1/ecx : (ref handle)
|
||||
68/push 0/imm32/address
|
||||
68/push 0/imm32/alloc-id
|
||||
89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx
|
||||
|
@ -381,7 +381,7 @@ test-lookup-failure:
|
|||
# reset heap->curr to mimic reclamation
|
||||
89/copy 0/mod/indirect 6/rm32/esi . . . 3/r32/ebx . . # copy ebx to *esi
|
||||
# second allocation that returns the same address as the first
|
||||
# var h2/edx = {0, 0}
|
||||
# var h2/edx : (ref handle)
|
||||
68/push 0/imm32/address
|
||||
68/push 0/imm32/alloc-id
|
||||
89/copy 3/mod/direct 2/rm32/edx . . . 4/r32/esp . . # copy esp to edx
|
||||
|
@ -422,7 +422,7 @@ test-lookup-failure:
|
|||
== data
|
||||
|
||||
# Monotonically increasing counter for calls to 'new'
|
||||
Next-alloc-id:
|
||||
Next-alloc-id: # int
|
||||
1/imm32
|
||||
|
||||
# . . vim:nowrap:textwidth=0
|
||||
|
|
|
@ -44,8 +44,8 @@ Entry: # run tests if necessary, convert stdin if not
|
|||
e8/call kernel-string-equal?/disp32
|
||||
# . . discard args
|
||||
81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp
|
||||
# . if (eax == 0) goto interactive
|
||||
3d/compare-eax-and 0/imm32
|
||||
# . if (eax == false) goto interactive
|
||||
3d/compare-eax-and 0/imm32/false
|
||||
74/jump-if-equal $subx-hex-main:interactive/disp8
|
||||
# run-tests()
|
||||
e8/call run-tests/disp32
|
||||
|
@ -54,7 +54,7 @@ Entry: # run tests if necessary, convert stdin if not
|
|||
eb/jump $subx-hex-main:end/disp8
|
||||
$subx-hex-main:interactive:
|
||||
# - otherwise convert stdin
|
||||
# var ed/eax : exit-descriptor
|
||||
# var ed/eax : (ref exit-descriptor)
|
||||
81 5/subop/subtract 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # subtract from esp
|
||||
89/copy 3/mod/direct 0/rm32/eax . . . 4/r32/esp . . # copy esp to eax
|
||||
# configure ed to really exit()
|
||||
|
@ -247,7 +247,7 @@ test-convert-next-octet:
|
|||
# . . discard args
|
||||
81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp
|
||||
# initialize exit-descriptor 'ed' for the call to 'convert-next-octet' below
|
||||
# . var ed/ecx : exit-descriptor
|
||||
# . var ed/ecx : (ref exit-descriptor)
|
||||
81 5/subop/subtract 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # subtract from esp
|
||||
89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx
|
||||
# . tailor-exit-descriptor(ed, 12)
|
||||
|
@ -337,7 +337,7 @@ test-convert-next-octet-handles-Eof:
|
|||
81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp
|
||||
# don't initialize '_test-stream'
|
||||
# initialize exit-descriptor 'ed' for the call to 'convert-next-octet' below
|
||||
# . var ed/ecx : exit-descriptor
|
||||
# . var ed/ecx : (ref exit-descriptor)
|
||||
81 5/subop/subtract 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # subtract from esp
|
||||
89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx
|
||||
# . tailor-exit-descriptor(ed, 12)
|
||||
|
@ -435,7 +435,7 @@ test-convert-next-octet-aborts-on-single-hex-byte:
|
|||
# . . discard args
|
||||
81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp
|
||||
# initialize exit-descriptor 'ed' for the call to 'convert-next-octet' below
|
||||
# . var ed/ecx : exit-descriptor
|
||||
# . var ed/ecx : (ref exit-descriptor)
|
||||
81 5/subop/subtract 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # subtract from esp
|
||||
89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx
|
||||
# . tailor-exit-descriptor(ed, 12)
|
||||
|
@ -604,7 +604,7 @@ test-scan-next-byte:
|
|||
# . . discard args
|
||||
81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp
|
||||
# initialize exit-descriptor 'ed' for the call to 'scan-next-byte' below
|
||||
# . var ed/ecx : exit-descriptor
|
||||
# . var ed/ecx : (ref exit-descriptor)
|
||||
81 5/subop/subtract 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # subtract from esp
|
||||
89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx
|
||||
# . tailor-exit-descriptor(ed, 12)
|
||||
|
@ -702,7 +702,7 @@ test-scan-next-byte-skips-whitespace:
|
|||
# . . discard args
|
||||
81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp
|
||||
# initialize exit-descriptor 'ed' for the call to 'scan-next-byte' below
|
||||
# . var ed/ecx : exit-descriptor
|
||||
# . var ed/ecx : (ref exit-descriptor)
|
||||
81 5/subop/subtract 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # subtract from esp
|
||||
89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx
|
||||
# . tailor-exit-descriptor(ed, 12)
|
||||
|
@ -808,7 +808,7 @@ test-scan-next-byte-skips-comment:
|
|||
# . . discard args
|
||||
81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp
|
||||
# initialize exit-descriptor 'ed' for the call to 'scan-next-byte' below
|
||||
# . var ed/ecx : exit-descriptor
|
||||
# . var ed/ecx : (ref exit-descriptor)
|
||||
81 5/subop/subtract 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # subtract from esp
|
||||
89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx
|
||||
# . tailor-exit-descriptor(ed, 12)
|
||||
|
@ -914,7 +914,7 @@ test-scan-next-byte-skips-comment-and-whitespace:
|
|||
# . . discard args
|
||||
81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp
|
||||
# initialize exit-descriptor 'ed' for the call to 'scan-next-byte' below
|
||||
# . var ed/ecx : exit-descriptor
|
||||
# . var ed/ecx : (ref exit-descriptor)
|
||||
81 5/subop/subtract 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # subtract from esp
|
||||
89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx
|
||||
# . tailor-exit-descriptor(ed, 12)
|
||||
|
@ -1022,7 +1022,7 @@ test-scan-next-byte-skips-whitespace-and-comment:
|
|||
# . . discard args
|
||||
81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp
|
||||
# initialize exit-descriptor 'ed' for the call to 'scan-next-byte' below
|
||||
# . var ed/ecx : exit-descriptor
|
||||
# . var ed/ecx : (ref exit-descriptor)
|
||||
81 5/subop/subtract 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # subtract from esp
|
||||
89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx
|
||||
# . tailor-exit-descriptor(ed, 12)
|
||||
|
@ -1120,7 +1120,7 @@ test-scan-next-byte-reads-final-byte:
|
|||
# . . discard args
|
||||
81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp
|
||||
# initialize exit-descriptor 'ed' for the call to 'scan-next-byte' below
|
||||
# . var ed/ecx : exit-descriptor
|
||||
# . var ed/ecx : (ref exit-descriptor)
|
||||
81 5/subop/subtract 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # subtract from esp
|
||||
89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx
|
||||
# . tailor-exit-descriptor(ed, 12)
|
||||
|
@ -1210,7 +1210,7 @@ test-scan-next-byte-handles-Eof:
|
|||
81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp
|
||||
# leave '_test-stream' empty
|
||||
# initialize exit-descriptor 'ed' for the call to 'scan-next-byte' below
|
||||
# . var ed/ecx : exit-descriptor
|
||||
# . var ed/ecx : (ref exit-descriptor)
|
||||
81 5/subop/subtract 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # subtract from esp
|
||||
89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx
|
||||
# . tailor-exit-descriptor(ed, 12)
|
||||
|
@ -1308,7 +1308,7 @@ test-scan-next-byte-aborts-on-invalid-byte:
|
|||
# . . discard args
|
||||
81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp
|
||||
# initialize exit-descriptor 'ed' for the call to 'scan-next-byte' below
|
||||
# . var ed/ecx : exit-descriptor
|
||||
# . var ed/ecx : (ref exit-descriptor)
|
||||
81 5/subop/subtract 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # subtract from esp
|
||||
89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx
|
||||
# . tailor-exit-descriptor(ed, 12)
|
||||
|
|
451
apps/mu.subx
451
apps/mu.subx
File diff suppressed because it is too large
Load Diff
|
@ -81,12 +81,12 @@ repl: # in : (address buffered-file), out : (address buffered-file)
|
|||
# . save registers
|
||||
50/push-eax
|
||||
{
|
||||
(lisp-read Stdin) # => eax : (address cell)
|
||||
(lisp-read Stdin) # => eax : (handle cell)
|
||||
# if (eax == 0) break
|
||||
3d/compare-eax-and 0/imm32
|
||||
74/jump-if-equal break/disp8
|
||||
#
|
||||
(lisp-eval %eax) # => eax : (address cell)
|
||||
(lisp-eval %eax) # => eax : (handle cell)
|
||||
(lisp-print Stdout %eax)
|
||||
eb/jump loop/disp8
|
||||
}
|
||||
|
@ -104,13 +104,13 @@ $repl:end:
|
|||
# arrays start with '['
|
||||
# symbols start with anything else but quote, backquote, unquote or splice
|
||||
# only one s-expression per line
|
||||
lisp-read: # in : (address buffered-file) -> eax : (address cell)
|
||||
lisp-read: # in : (address buffered-file) -> eax : (handle cell)
|
||||
# . prologue
|
||||
55/push-ebp
|
||||
89/<- %ebp 4/r32/esp
|
||||
# . save registers
|
||||
51/push-ecx
|
||||
# var s/ecx : (stream byte 512)
|
||||
# var s/ecx : (ref stream byte 512)
|
||||
81 5/subop/subtract %esp 0x200/imm32
|
||||
68/push 0x200/imm32/size
|
||||
68/push 0/imm32/read
|
||||
|
@ -142,14 +142,14 @@ $lisp-read:end:
|
|||
5d/pop-to-ebp
|
||||
c3/return
|
||||
|
||||
# lisp-read: in : (address buffered-file) -> (address cell)
|
||||
# lisp-read: in : (address buffered-file) -> (handle cell)
|
||||
# token tmp = next-mulisp-token(in)
|
||||
# if is-int(tmp) return cell(tmp)
|
||||
# if is-string(tmp) return cell(tmp)
|
||||
# if is-pair(tmp) ...
|
||||
# if is-array(tmp) ...
|
||||
|
||||
next-mulisp-token: # in : (address buffered-file), line : (address stream), result : (address slice)
|
||||
next-mulisp-token: # in : (address buffered-file), line : (address stream byte), result : (address slice)
|
||||
# pseudocode:
|
||||
# if (line->read >= line->write)
|
||||
# read-line-buffered(in, line)
|
||||
|
@ -194,11 +194,11 @@ $next-mulisp-token:end:
|
|||
5d/pop-to-ebp
|
||||
c3/return
|
||||
|
||||
new-int-cell: # in : (address slice) -> eax : (address cell)
|
||||
new-int-cell: # in : (address slice) -> eax : (handle cell)
|
||||
|
||||
new-string-cell: # in : (address slice) -> eax : (address cell)
|
||||
new-string-cell: # in : (address slice) -> eax : (handle cell)
|
||||
|
||||
lisp-eval: # in : (address cell) -> eax : (address cell)
|
||||
lisp-eval: # in : (address cell) -> eax : (handle cell)
|
||||
# . prologue
|
||||
55/push-ebp
|
||||
89/<- %ebp 4/r32/esp
|
||||
|
|
260
apps/pack.subx
260
apps/pack.subx
|
@ -45,8 +45,8 @@ Entry: # run tests if necessary, convert stdin if not
|
|||
e8/call kernel-string-equal?/disp32
|
||||
# . . discard args
|
||||
81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp
|
||||
# . if (eax == 0) goto interactive
|
||||
3d/compare-eax-and 0/imm32
|
||||
# . if (eax == false) goto interactive
|
||||
3d/compare-eax-and 0/imm32/false
|
||||
74/jump-if-equal $subx-pack-main:interactive/disp8
|
||||
# run-tests()
|
||||
e8/call run-tests/disp32
|
||||
|
@ -55,7 +55,7 @@ Entry: # run tests if necessary, convert stdin if not
|
|||
eb/jump $subx-pack-main:end/disp8
|
||||
$subx-pack-main:interactive:
|
||||
# - otherwise convert stdin
|
||||
# var ed/eax : exit-descriptor
|
||||
# var ed/eax : (ref exit-descriptor)
|
||||
81 5/subop/subtract 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # subtract from esp
|
||||
89/copy 3/mod/direct 0/rm32/eax . . . 4/r32/esp . . # copy esp to eax
|
||||
# configure ed to really exit()
|
||||
|
@ -99,7 +99,7 @@ $subx-pack-main:end:
|
|||
|
||||
subx-pack: # in : (address buffered-file), out : (address buffered-file)
|
||||
# pseudocode:
|
||||
# var line : (stream byte 512)
|
||||
# var line : (ref stream byte 512)
|
||||
# var in-code? = false
|
||||
# while true
|
||||
# clear-stream(line)
|
||||
|
@ -128,17 +128,17 @@ subx-pack: # in : (address buffered-file), out : (address buffered-file)
|
|||
51/push-ecx
|
||||
52/push-edx
|
||||
53/push-ebx
|
||||
# var line/ecx : (address stream byte) = stream(512)
|
||||
# var line/ecx : (ref stream byte 512)
|
||||
81 5/subop/subtract 3/mod/direct 4/rm32/esp . . . . . 0x200/imm32 # subtract from esp
|
||||
68/push 0x200/imm32/length
|
||||
68/push 0/imm32/read
|
||||
68/push 0/imm32/write
|
||||
89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx
|
||||
# var word-slice/edx = {0, 0}
|
||||
# var word-slice/edx : (ref slice)
|
||||
68/push 0/imm32/end
|
||||
68/push 0/imm32/start
|
||||
89/copy 3/mod/direct 2/rm32/edx . . . 4/r32/esp . . # copy esp to edx
|
||||
# var in-code?/ebx = false
|
||||
# var in-code?/ebx : boolean = false
|
||||
31/xor 3/mod/direct 3/rm32/ebx . . . 3/r32/ebx . . # clear ebx
|
||||
$subx-pack:loop:
|
||||
# clear-stream(line)
|
||||
|
@ -203,8 +203,8 @@ $subx-pack:check1:
|
|||
e8/call slice-empty?/disp32
|
||||
# . . discard args
|
||||
81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp
|
||||
# . if (eax != 0) write-stream-data(out, line)
|
||||
3d/compare-eax-and 0/imm32
|
||||
# . if (eax != false) write-stream-data(out, line)
|
||||
3d/compare-eax-and 0/imm32/false
|
||||
0f 85/jump-if-not-equal $subx-pack:pass-through/disp32
|
||||
$subx-pack:check2:
|
||||
#? # dump word-slice {{{
|
||||
|
@ -256,8 +256,8 @@ $subx-pack:check2:
|
|||
e8/call slice-equal?/disp32
|
||||
# . . discard args
|
||||
81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp
|
||||
# . if (eax == 0) goto check3
|
||||
3d/compare-eax-and 0/imm32
|
||||
# . if (eax == false) goto check3
|
||||
3d/compare-eax-and 0/imm32/false
|
||||
0f 84/jump-if-equal $subx-pack:check3/disp32
|
||||
# word-slice = next-word(line)
|
||||
# . . push args
|
||||
|
@ -328,8 +328,8 @@ $subx-pack:check3:
|
|||
e8/call rewind-stream/disp32
|
||||
# . . discard args
|
||||
81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp
|
||||
# if (in-code? != 0) convert-instruction(line, out)
|
||||
81 7/subop/compare 3/mod/direct 3/rm32/ebx . . . . . 0/imm32 # compare ebx
|
||||
# if (in-code? != false) convert-instruction(line, out)
|
||||
81 7/subop/compare 3/mod/direct 3/rm32/ebx . . . . . 0/imm32/false # compare ebx
|
||||
74/jump-if-equal $subx-pack:data/disp8
|
||||
$subx-pack:code:
|
||||
# . convert-instruction(line, out)
|
||||
|
@ -911,7 +911,7 @@ test-subx-pack-code-and-data-segments:
|
|||
|
||||
convert-data: # line : (address stream byte), out : (address buffered-file)
|
||||
# pseudocode:
|
||||
# var word-slice = {0, 0}
|
||||
# var word-slice : (ref slice)
|
||||
# while true
|
||||
# word-slice = next-word(line)
|
||||
# if slice-empty?(word-slice) # end of file (maybe including trailing whitespace)
|
||||
|
@ -936,7 +936,7 @@ convert-data: # line : (address stream byte), out : (address buffered-file)
|
|||
50/push-eax
|
||||
51/push-ecx
|
||||
52/push-edx
|
||||
# var word-slice/ecx = {0, 0}
|
||||
# var word-slice/ecx : (ref slice)
|
||||
68/push 0/imm32/end
|
||||
68/push 0/imm32/start
|
||||
89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx
|
||||
|
@ -1024,17 +1024,17 @@ $convert-data:check0:
|
|||
e8/call slice-empty?/disp32
|
||||
# . . discard args
|
||||
81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp
|
||||
# . if (eax != 0) break
|
||||
3d/compare-eax-and 0/imm32
|
||||
# . if (eax != false) break
|
||||
3d/compare-eax-and 0/imm32/false
|
||||
0f 85/jump-if-not-equal $convert-data:break/disp32
|
||||
$convert-data:check-for-comment:
|
||||
# if (slice-starts-with?(word-slice, "#"))
|
||||
# . start/edx = word-slice->start
|
||||
# . var start/edx : (address byte) = word-slice->start
|
||||
8b/copy 0/mod/indirect 1/rm32/ecx . . . 2/r32/edx . . # copy *ecx to edx
|
||||
# . c/eax = *start
|
||||
# . var c/eax : byte = *start
|
||||
31/xor 3/mod/direct 0/rm32/eax . . . 0/r32/eax . . # clear eax
|
||||
8a/copy-byte 0/mod/indirect 2/rm32/edx . . . 0/r32/AL . . # copy byte at *edx to AL
|
||||
# . if (eax != '#') goto next check
|
||||
# . if (c != '#') goto next check
|
||||
3d/compare-eax-and 0x23/imm32/hash
|
||||
75/jump-if-not-equal $convert-data:check-for-label/disp8
|
||||
$convert-data:comment:
|
||||
|
@ -1050,12 +1050,12 @@ $convert-data:comment:
|
|||
0f 85/jump-if-not-equal $convert-data:end/disp32
|
||||
$convert-data:check-for-label:
|
||||
# if (slice-ends-with?(word-slice, ":"))
|
||||
# . end/edx = word-slice->end
|
||||
# . var end/edx : (address byte) = word-slice->end
|
||||
8b/copy 1/mod/*+disp8 1/rm32/ecx . . . 2/r32/edx 4/disp8 . # copy *(ecx+4) to edx
|
||||
# . c/eax = *(end-1)
|
||||
# . var c/eax : byte = *(end-1)
|
||||
31/xor 3/mod/direct 0/rm32/eax . . . 0/r32/eax . . # clear eax
|
||||
8a/copy-byte 1/mod/*+disp8 2/rm32/edx . . . 0/r32/AL -1/disp8 . # copy byte at *ecx to AL
|
||||
# . if (eax != ':') goto next check
|
||||
# . if (c != ':') goto next check
|
||||
3d/compare-eax-and 0x3a/imm32/colon
|
||||
75/jump-if-not-equal $convert-data:check-for-imm32/disp8
|
||||
$convert-data:label:
|
||||
|
@ -1079,8 +1079,8 @@ $convert-data:check-for-imm32:
|
|||
e8/call has-metadata?/disp32
|
||||
# . . discard args
|
||||
81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp
|
||||
# . if (eax == 0) process as a single byte
|
||||
3d/compare-eax-and 0/imm32
|
||||
# . if (eax == false) process as a single byte
|
||||
3d/compare-eax-and 0/imm32/false
|
||||
74/jump-if-equal $convert-data:single-byte/disp8
|
||||
$convert-data:imm32:
|
||||
# emit(out, word-slice, 4)
|
||||
|
@ -1837,7 +1837,7 @@ convert-instruction: # line : (address stream byte), out : (address buffered-fi
|
|||
50/push-eax
|
||||
51/push-ecx
|
||||
52/push-edx
|
||||
# var word-slice/ecx = {0, 0}
|
||||
# var word-slice/ecx : (ref slice)
|
||||
68/push 0/imm32/end
|
||||
68/push 0/imm32/start
|
||||
89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx
|
||||
|
@ -1858,27 +1858,27 @@ $convert-instruction:check0:
|
|||
e8/call slice-empty?/disp32
|
||||
# . . discard args
|
||||
81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp
|
||||
# . if (eax != 0) pass through
|
||||
3d/compare-eax-and 0/imm32
|
||||
# . if (eax != false) pass through
|
||||
3d/compare-eax-and 0/imm32/false
|
||||
75/jump-if-not-equal $convert-instruction:pass-through/disp8
|
||||
$convert-instruction:check1:
|
||||
# if (slice-starts-with?(word-slice, "#")) write-stream-data(out, line)
|
||||
# . start/edx = word-slice->start
|
||||
# . var start/edx : (address byte) = word-slice->start
|
||||
8b/copy 0/mod/indirect 1/rm32/ecx . . . 2/r32/edx . . # copy *ecx to edx
|
||||
# . c/eax = *start
|
||||
# . var c/eax : byte = *start
|
||||
31/xor 3/mod/direct 0/rm32/eax . . . 0/r32/eax . . # clear eax
|
||||
8a/copy-byte 0/mod/indirect 2/rm32/edx . . . 0/r32/AL . . # copy byte at *edx to AL
|
||||
# . if (eax == '#') pass through
|
||||
# . if (c == '#') pass through
|
||||
3d/compare-eax-and 0x23/imm32/hash
|
||||
74/jump-if-equal $convert-instruction:pass-through/disp8
|
||||
$convert-instruction:check2:
|
||||
# if (slice-ends-with?(word-slice, ":")) write-stream-data(out, line)
|
||||
# . end/edx = word-slice->end
|
||||
# . var end/edx : (address byte) = word-slice->end
|
||||
8b/copy 1/mod/*+disp8 1/rm32/ecx . . . 2/r32/edx 4/disp8 . # copy *(ecx+4) to edx
|
||||
# . c/eax = *(end-1)
|
||||
# . var c/eax : byte = *(end-1)
|
||||
31/xor 3/mod/direct 0/rm32/eax . . . 0/r32/eax . . # clear eax
|
||||
8a/copy-byte 1/mod/*+disp8 2/rm32/edx . . . 0/r32/AL -1/disp8 . # copy byte at *ecx to AL
|
||||
# . if (eax == ':') pass through
|
||||
# . if (c == ':') pass through
|
||||
3d/compare-eax-and 0x3a/imm32/colon
|
||||
75/jump-if-not-equal $convert-instruction:really-convert/disp8
|
||||
$convert-instruction:pass-through:
|
||||
|
@ -1994,11 +1994,11 @@ emit-opcodes: # line : (address stream byte), out : (address buffered-file)
|
|||
51/push-ecx
|
||||
52/push-edx
|
||||
53/push-ebx
|
||||
# var op1/ecx = {0, 0}
|
||||
# var op1/ecx : (ref slice)
|
||||
68/push 0/imm32/end
|
||||
68/push 0/imm32/start
|
||||
89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx
|
||||
# var op2/edx = {0, 0}
|
||||
# var op2/edx : (ref slice)
|
||||
68/push 0/imm32/end
|
||||
68/push 0/imm32/start
|
||||
89/copy 3/mod/direct 2/rm32/edx . . . 4/r32/esp . . # copy esp to edx
|
||||
|
@ -2026,16 +2026,16 @@ $emit-opcodes:op1:
|
|||
e8/call slice-empty?/disp32
|
||||
# . . discard args
|
||||
81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp
|
||||
# . if (eax != 0) return
|
||||
3d/compare-eax-and 0/imm32
|
||||
# . if (eax != false) return
|
||||
3d/compare-eax-and 0/imm32/false
|
||||
0f 85/jump-if-not-equal $emit-opcodes:end/disp32
|
||||
# if (slice-starts-with?(op1, "#")) return
|
||||
# . start/ebx = op1->start
|
||||
# . var start/ebx : (address byte) = op1->start
|
||||
8b/copy 0/mod/indirect 1/rm32/ecx . . . 3/r32/ebx . . # copy *ecx to ebx
|
||||
# . c/eax = *start
|
||||
# . var c/eax : byte = *start
|
||||
31/xor 3/mod/direct 0/rm32/eax . . . 0/r32/eax . . # clear eax
|
||||
8a/copy-byte 0/mod/indirect 3/rm32/ebx . . . 0/r32/AL . . # copy byte at *ebx to AL
|
||||
# . if (eax == '#') return
|
||||
# . if (c == '#') return
|
||||
3d/compare-eax-and 0x23/imm32/hash
|
||||
0f 84/jump-if-equal $emit-opcodes:end/disp32
|
||||
# op1 = next-token-from-slice(op1->start, op1->end, '/')
|
||||
|
@ -2073,8 +2073,8 @@ $emit-opcodes:op1:
|
|||
e8/call slice-equal?/disp32
|
||||
# . . discard args
|
||||
81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp
|
||||
# . if (eax != 0) goto op2
|
||||
3d/compare-eax-and 0/imm32
|
||||
# . if (eax != false) goto op2
|
||||
3d/compare-eax-and 0/imm32/false
|
||||
75/jump-if-not-equal $emit-opcodes:op2/disp8
|
||||
# if (slice-equal?(op1, "f2")) goto op2
|
||||
# . eax = slice-equal?(op1, "f2")
|
||||
|
@ -2085,8 +2085,8 @@ $emit-opcodes:op1:
|
|||
e8/call slice-equal?/disp32
|
||||
# . . discard args
|
||||
81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp
|
||||
# . if (eax != 0) goto op2
|
||||
3d/compare-eax-and 0/imm32
|
||||
# . if (eax != false) goto op2
|
||||
3d/compare-eax-and 0/imm32/false
|
||||
75/jump-if-not-equal $emit-opcodes:op2/disp8
|
||||
# if (slice-equal?(op1, "f3")) goto op2
|
||||
# . eax = slice-equal?(op1, "f3")
|
||||
|
@ -2097,8 +2097,8 @@ $emit-opcodes:op1:
|
|||
e8/call slice-equal?/disp32
|
||||
# . . discard args
|
||||
81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp
|
||||
# . if (eax != 0) goto op2
|
||||
3d/compare-eax-and 0/imm32
|
||||
# . if (eax != false) goto op2
|
||||
3d/compare-eax-and 0/imm32/false
|
||||
75/jump-if-not-equal $emit-opcodes:op2/disp8
|
||||
# otherwise return
|
||||
e9/jump $emit-opcodes:end/disp32
|
||||
|
@ -2119,16 +2119,16 @@ $emit-opcodes:op2:
|
|||
e8/call slice-empty?/disp32
|
||||
# . . discard args
|
||||
81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp
|
||||
# . if (eax != 0) return
|
||||
3d/compare-eax-and 0/imm32
|
||||
# . if (eax != false) return
|
||||
3d/compare-eax-and 0/imm32/false
|
||||
0f 85/jump-if-not-equal $emit-opcodes:end/disp32
|
||||
# if (slice-starts-with?(op2, "#")) return
|
||||
# . start/ebx = op2->start
|
||||
# . var start/ebx : (address byte) = op2->start
|
||||
8b/copy 0/mod/indirect 2/rm32/edx . . . 3/r32/ebx . . # copy *edx to ebx
|
||||
# . c/eax = *start
|
||||
# . var c/eax : byte = *start
|
||||
31/xor 3/mod/direct 0/rm32/eax . . . 0/r32/eax . . # clear eax
|
||||
8a/copy-byte 0/mod/indirect 3/rm32/ebx . . . 0/r32/AL . . # copy byte at *ebx to AL
|
||||
# . if (eax == '#') return
|
||||
# . if (c == '#') return
|
||||
3d/compare-eax-and 0x23/imm32/hash
|
||||
0f 84/jump-if-equal $emit-opcodes:end/disp32
|
||||
# op2 = next-token-from-slice(op2->start, op2->end, '/')
|
||||
|
@ -2166,8 +2166,8 @@ $emit-opcodes:op2:
|
|||
e8/call slice-equal?/disp32
|
||||
# . . discard args
|
||||
81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp
|
||||
# . if (eax != 0) return
|
||||
3d/compare-eax-and 0/imm32
|
||||
# . if (eax != false) return
|
||||
3d/compare-eax-and 0/imm32/false
|
||||
0f 85/jump-if-not-equal $emit-opcodes:end/disp32
|
||||
# if (!slice-equal?(op2, "0f")) return
|
||||
# . eax = slice-equal?(op2, "0f")
|
||||
|
@ -2178,8 +2178,8 @@ $emit-opcodes:op2:
|
|||
e8/call slice-equal?/disp32
|
||||
# . . discard args
|
||||
81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp
|
||||
# . if (eax == 0) return
|
||||
3d/compare-eax-and 0/imm32
|
||||
# . if (eax == false) return
|
||||
3d/compare-eax-and 0/imm32/false
|
||||
0f 84/jump-if-equal $emit-opcodes:end/disp32
|
||||
$emit-opcodes:op3:
|
||||
# next-word(line, op3) # reuse op2/edx
|
||||
|
@ -2198,16 +2198,16 @@ $emit-opcodes:op3:
|
|||
e8/call slice-empty?/disp32
|
||||
# . . discard args
|
||||
81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp
|
||||
# . if (eax != 0) return
|
||||
3d/compare-eax-and 0/imm32
|
||||
# . if (eax != false) return
|
||||
3d/compare-eax-and 0/imm32/false
|
||||
0f 85/jump-if-not-equal $emit-opcodes:end/disp32
|
||||
# if (slice-starts-with?(op3, "#")) return
|
||||
# . start/ebx = op2->start
|
||||
# . var start/ebx : (address byte) = op2->start
|
||||
8b/copy 0/mod/indirect 2/rm32/edx . . . 3/r32/ebx . . # copy *edx to ebx
|
||||
# . c/eax = *start
|
||||
# . var c/eax : byte = *start
|
||||
31/xor 3/mod/direct 0/rm32/eax . . . 0/r32/eax . . # clear eax
|
||||
8a/copy-byte 0/mod/indirect 3/rm32/ebx . . . 0/r32/AL . . # copy byte at *ebx to AL
|
||||
# . if (eax == '#') return
|
||||
# . if (c == '#') return
|
||||
3d/compare-eax-and 0x23/imm32/hash
|
||||
0f 84/jump-if-equal $emit-opcodes:end/disp32
|
||||
# op3 = next-token-from-slice(op3->start, op3->end, '/')
|
||||
|
@ -2253,7 +2253,7 @@ emit-modrm: # line : (address stream byte), out : (address buffered-file)
|
|||
# pseudocode:
|
||||
# rewind-stream(line)
|
||||
# var has-modrm? = false, mod = 0, rm32 = 0, r32 = 0
|
||||
# var word-slice = {0, 0}
|
||||
# var word-slice : (ref slice)
|
||||
# while true
|
||||
# word-slice = next-word(line)
|
||||
# if (slice-empty?(word-slice)) break
|
||||
|
@ -2285,17 +2285,17 @@ emit-modrm: # line : (address stream byte), out : (address buffered-file)
|
|||
53/push-ebx
|
||||
56/push-esi
|
||||
57/push-edi
|
||||
# var word-slice/ecx = {0, 0}
|
||||
# var word-slice/ecx : (ref slice)
|
||||
68/push 0/imm32/end
|
||||
68/push 0/imm32/start
|
||||
89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx
|
||||
# var has-modrm?/edx = false
|
||||
# var has-modrm?/edx : boolean = false
|
||||
31/xor 3/mod/direct 2/rm32/edx . . . 2/r32/edx . . # clear edx
|
||||
# var mod/ebx = 0
|
||||
# var mod/ebx : byte = 0
|
||||
31/xor 3/mod/direct 3/rm32/ebx . . . 3/r32/ebx . . # clear ebx
|
||||
# var rm32/esi = 0
|
||||
# var rm32/esi : byte = 0
|
||||
31/xor 3/mod/direct 6/rm32/esi . . . 6/r32/esi . . # clear esi
|
||||
# var r32/edi = 0
|
||||
# var r32/edi : byte = 0
|
||||
31/xor 3/mod/direct 7/rm32/edi . . . 7/r32/edi . . # clear edi
|
||||
# rewind-stream(line)
|
||||
# . . push args
|
||||
|
@ -2395,21 +2395,21 @@ $emit-modrm:check0:
|
|||
e8/call slice-empty?/disp32
|
||||
# . . discard args
|
||||
81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp
|
||||
# . if (eax != 0) pass through
|
||||
3d/compare-eax-and 0/imm32
|
||||
# . if (eax != false) pass through
|
||||
3d/compare-eax-and 0/imm32/false
|
||||
0f 85/jump-if-not-equal $emit-modrm:break/disp32
|
||||
$emit-modrm:check1:
|
||||
# if (slice-starts-with?(word-slice, "#")) break
|
||||
# . spill edx
|
||||
52/push-edx
|
||||
# . start/edx = word-slice->start
|
||||
# . var start/edx : (address byte) = word-slice->start
|
||||
8b/copy 0/mod/indirect 1/rm32/ecx . . . 2/r32/edx . . # copy *ecx to edx
|
||||
# . c/eax = *start
|
||||
# . var c/eax : byte = *start
|
||||
31/xor 3/mod/direct 0/rm32/eax . . . 0/r32/eax . . # clear eax
|
||||
8a/copy-byte 0/mod/indirect 2/rm32/edx . . . 0/r32/AL . . # copy byte at *edx to AL
|
||||
# . restore edx
|
||||
5a/pop-to-edx
|
||||
# . if (eax == '#') pass through
|
||||
# . if (c == '#') pass through
|
||||
3d/compare-eax-and 0x23/imm32/hash
|
||||
0f 84/jump-if-equal $emit-modrm:break/disp32
|
||||
$emit-modrm:check-for-mod:
|
||||
|
@ -2422,8 +2422,8 @@ $emit-modrm:check-for-mod:
|
|||
e8/call has-metadata?/disp32
|
||||
# . . discard args
|
||||
81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp
|
||||
# . if (eax == 0) goto next check
|
||||
3d/compare-eax-and 0/imm32
|
||||
# . if (eax == false) goto next check
|
||||
3d/compare-eax-and 0/imm32/false
|
||||
74/jump-if-equal $emit-modrm:check-for-rm32/disp8
|
||||
$emit-modrm:mod:
|
||||
# mod = parse-hex-int(next-token-from-slice(word-slice->start, word-slice->end, '/'))
|
||||
|
@ -2450,8 +2450,8 @@ $emit-modrm:check-for-rm32:
|
|||
e8/call has-metadata?/disp32
|
||||
# . . discard args
|
||||
81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp
|
||||
# . if (eax == 0) goto next check
|
||||
3d/compare-eax-and 0/imm32
|
||||
# . if (eax == false) goto next check
|
||||
3d/compare-eax-and 0/imm32/false
|
||||
74/jump-if-equal $emit-modrm:check-for-r32/disp8
|
||||
$emit-modrm:rm32:
|
||||
# rm32 = parse-hex-int(next-token-from-slice(word-slice->start, word-slice->end, '/'))
|
||||
|
@ -2478,8 +2478,8 @@ $emit-modrm:check-for-r32:
|
|||
e8/call has-metadata?/disp32
|
||||
# . . discard args
|
||||
81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp
|
||||
# . if (eax == 0) goto next check
|
||||
3d/compare-eax-and 0/imm32
|
||||
# . if (eax == false) goto next check
|
||||
3d/compare-eax-and 0/imm32/false
|
||||
74/jump-if-equal $emit-modrm:check-for-subop/disp8
|
||||
$emit-modrm:r32:
|
||||
# r32 = parse-hex-int(next-token-from-slice(word-slice->start, word-slice->end, '/'))
|
||||
|
@ -2506,8 +2506,8 @@ $emit-modrm:check-for-subop:
|
|||
e8/call has-metadata?/disp32
|
||||
# . . discard args
|
||||
81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp
|
||||
# . if (eax == 0) loop
|
||||
3d/compare-eax-and 0/imm32
|
||||
# . if (eax == false) loop
|
||||
3d/compare-eax-and 0/imm32/false
|
||||
0f 84/jump-if-equal $emit-modrm:loop/disp32
|
||||
$emit-modrm:subop:
|
||||
# r32 = parse-hex-int(next-token-from-slice(word-slice->start, word-slice->end, '/'))
|
||||
|
@ -2526,10 +2526,10 @@ $emit-modrm:subop:
|
|||
e9/jump $emit-modrm:loop/disp32
|
||||
$emit-modrm:break:
|
||||
# if (!has-modrm?) return
|
||||
81 7/subop/compare 3/mod/direct 2/rm32/edx . . . . . 0/imm32 # compare edx
|
||||
81 7/subop/compare 3/mod/direct 2/rm32/edx . . . . . 0/imm32/false # compare edx
|
||||
74/jump-if-equal $emit-modrm:end/disp8
|
||||
$emit-modrm:calculate:
|
||||
# modrm/ebx = mod & 0b11
|
||||
# var modrm/ebx : byte = mod & 0b11
|
||||
81 4/subop/and 3/mod/direct 3/rm32/ebx . . . . . 3/imm32/0b11 # bitwise and of ebx
|
||||
# modrm <<= 3
|
||||
c1/shift 4/subop/left 3/mod/direct 3/rm32/ebx . . . . . 3/imm8 # shift ebx left by 3 bits
|
||||
|
@ -2569,7 +2569,7 @@ $emit-modrm:end:
|
|||
emit-sib: # line : (address stream byte), out : (address buffered-file)
|
||||
# pseudocode:
|
||||
# var has-sib? = false, base = 0, index = 0, scale = 0
|
||||
# var word-slice = {0, 0}
|
||||
# var word-slice : (ref slice)
|
||||
# while true
|
||||
# word-slice = next-word(line)
|
||||
# if (slice-empty?(word-slice)) break
|
||||
|
@ -2601,17 +2601,17 @@ emit-sib: # line : (address stream byte), out : (address buffered-file)
|
|||
53/push-ebx
|
||||
56/push-esi
|
||||
57/push-edi
|
||||
# var word-slice/ecx = {0, 0}
|
||||
# var word-slice/ecx : (ref slice)
|
||||
68/push 0/imm32/end
|
||||
68/push 0/imm32/start
|
||||
89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx
|
||||
# var has-sib?/edx = false
|
||||
# var has-sib?/edx : boolean = false
|
||||
31/xor 3/mod/direct 2/rm32/edx . . . 2/r32/edx . . # clear edx
|
||||
# var scale/ebx = 0
|
||||
# var scale/ebx : byte = 0
|
||||
31/xor 3/mod/direct 3/rm32/ebx . . . 3/r32/ebx . . # clear ebx
|
||||
# var base/esi = 0
|
||||
# var base/esi : byte = 0
|
||||
31/xor 3/mod/direct 6/rm32/esi . . . 6/r32/esi . . # clear esi
|
||||
# var index/edi = 0
|
||||
# var index/edi : byte = 0
|
||||
31/xor 3/mod/direct 7/rm32/edi . . . 7/r32/edi . . # clear edi
|
||||
# rewind-stream(line)
|
||||
# . . push args
|
||||
|
@ -2704,21 +2704,21 @@ $emit-sib:check0:
|
|||
e8/call slice-empty?/disp32
|
||||
# . . discard args
|
||||
81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp
|
||||
# . if (eax != 0) pass through
|
||||
3d/compare-eax-and 0/imm32
|
||||
# . if (eax != false) pass through
|
||||
3d/compare-eax-and 0/imm32/false
|
||||
0f 85/jump-if-not-equal $emit-sib:break/disp32
|
||||
$emit-sib:check1:
|
||||
# if (slice-starts-with?(word-slice, "#")) break
|
||||
# . spill edx
|
||||
52/push-edx
|
||||
# . start/edx = word-slice->start
|
||||
# . var start/edx : (address byte) = word-slice->start
|
||||
8b/copy 0/mod/indirect 1/rm32/ecx . . . 2/r32/edx . . # copy *ecx to edx
|
||||
# . c/eax = *start
|
||||
# . var c/eax : byte = *start
|
||||
31/xor 3/mod/direct 0/rm32/eax . . . 0/r32/eax . . # clear eax
|
||||
8a/copy-byte 0/mod/indirect 2/rm32/edx . . . 0/r32/AL . . # copy byte at *edx to AL
|
||||
# . restore edx
|
||||
5a/pop-to-edx
|
||||
# . if (eax == '#') pass through
|
||||
# . if (c == '#') pass through
|
||||
3d/compare-eax-and 0x23/imm32/hash
|
||||
0f 84/jump-if-equal $emit-sib:break/disp32
|
||||
$emit-sib:check-for-scale:
|
||||
|
@ -2731,8 +2731,8 @@ $emit-sib:check-for-scale:
|
|||
e8/call has-metadata?/disp32
|
||||
# . . discard args
|
||||
81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp
|
||||
# . if (eax == 0) goto next check
|
||||
3d/compare-eax-and 0/imm32
|
||||
# . if (eax == false) goto next check
|
||||
3d/compare-eax-and 0/imm32/false
|
||||
74/jump-if-equal $emit-sib:check-for-base/disp8
|
||||
$emit-sib:scale:
|
||||
# scale = parse-hex-int(next-token-from-slice(word-slice->start, word-slice->end, '/'))
|
||||
|
@ -2759,8 +2759,8 @@ $emit-sib:check-for-base:
|
|||
e8/call has-metadata?/disp32
|
||||
# . . discard args
|
||||
81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp
|
||||
# . if (eax == 0) goto next check
|
||||
3d/compare-eax-and 0/imm32
|
||||
# . if (eax == false) goto next check
|
||||
3d/compare-eax-and 0/imm32/false
|
||||
74/jump-if-equal $emit-sib:check-for-index/disp8
|
||||
$emit-sib:base:
|
||||
# base = parse-hex-int(next-token-from-slice(word-slice->start, word-slice->end, '/'))
|
||||
|
@ -2787,8 +2787,8 @@ $emit-sib:check-for-index:
|
|||
e8/call has-metadata?/disp32
|
||||
# . . discard args
|
||||
81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp
|
||||
# . if (eax == 0) loop
|
||||
3d/compare-eax-and 0/imm32
|
||||
# . if (eax == false) loop
|
||||
3d/compare-eax-and 0/imm32/false
|
||||
0f 84/jump-if-equal $emit-sib:loop/disp32
|
||||
$emit-sib:index:
|
||||
# index = parse-hex-int(next-token-from-slice(word-slice->start, word-slice->end, '/'))
|
||||
|
@ -2807,10 +2807,10 @@ $emit-sib:index:
|
|||
e9/jump $emit-sib:loop/disp32
|
||||
$emit-sib:break:
|
||||
# if (!has-sib?) return
|
||||
81 7/subop/compare 3/mod/direct 2/rm32/edx . . . . . 0/imm32 # compare edx
|
||||
81 7/subop/compare 3/mod/direct 2/rm32/edx . . . . . 0/imm32/false # compare edx
|
||||
74/jump-if-equal $emit-sib:end/disp8
|
||||
$emit-sib:calculate:
|
||||
# sib/ebx = scale & 0b11
|
||||
# var sib/ebx : byte = scale & 0b11
|
||||
81 4/subop/and 3/mod/direct 3/rm32/ebx . . . . . 3/imm32/0b11 # bitwise and of ebx
|
||||
# sib <<= 2
|
||||
c1/shift 4/subop/left 3/mod/direct 3/rm32/ebx . . . . . 2/imm8 # shift ebx left by 2 bits
|
||||
|
@ -2850,7 +2850,7 @@ $emit-sib:end:
|
|||
emit-disp: # line : (address stream byte), out : (address buffered-file)
|
||||
# pseudocode:
|
||||
# rewind-stream(line)
|
||||
# var word-slice = {0, 0}
|
||||
# var word-slice : (ref slice)
|
||||
# while true
|
||||
# word-slice = next-word(line)
|
||||
# if (slice-empty?(word-slice)) break
|
||||
|
@ -2872,7 +2872,7 @@ emit-disp: # line : (address stream byte), out : (address buffered-file)
|
|||
50/push-eax
|
||||
51/push-ecx
|
||||
52/push-edx
|
||||
# var word-slice/ecx = {0, 0}
|
||||
# var word-slice/ecx : (ref slice)
|
||||
68/push 0/imm32/end
|
||||
68/push 0/imm32/start
|
||||
89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx
|
||||
|
@ -2967,17 +2967,17 @@ $emit-disp:check0:
|
|||
e8/call slice-empty?/disp32
|
||||
# . . discard args
|
||||
81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp
|
||||
# . if (eax != 0) pass through
|
||||
3d/compare-eax-and 0/imm32
|
||||
# . if (eax != false) pass through
|
||||
3d/compare-eax-and 0/imm32/false
|
||||
0f 85/jump-if-not-equal $emit-disp:break/disp32
|
||||
$emit-disp:check1:
|
||||
# if (slice-starts-with?(word-slice, "#")) break
|
||||
# . start/edx = word-slice->start
|
||||
# . var start/edx : (address byte) = word-slice->start
|
||||
8b/copy 0/mod/indirect 1/rm32/ecx . . . 2/r32/edx . . # copy *ecx to edx
|
||||
# . c/eax = *start
|
||||
# . var c/eax : byte = *start
|
||||
31/xor 3/mod/direct 0/rm32/eax . . . 0/r32/eax . . # clear eax
|
||||
8a/copy-byte 0/mod/indirect 2/rm32/edx . . . 0/r32/AL . . # copy byte at *edx to AL
|
||||
# . if (eax == '#') break
|
||||
# . if (c == '#') break
|
||||
3d/compare-eax-and 0x23/imm32/hash
|
||||
0f 84/jump-if-equal $emit-disp:break/disp32
|
||||
$emit-disp:check-for-disp32:
|
||||
|
@ -2990,8 +2990,8 @@ $emit-disp:check-for-disp32:
|
|||
e8/call has-metadata?/disp32
|
||||
# . . discard args
|
||||
81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp
|
||||
# . if (eax == 0) goto next check
|
||||
3d/compare-eax-and 0/imm32
|
||||
# . if (eax == false) goto next check
|
||||
3d/compare-eax-and 0/imm32/false
|
||||
74/jump-if-equal $emit-disp:check-for-disp16/disp8
|
||||
$emit-disp:disp32:
|
||||
# emit(out, word-slice, 4)
|
||||
|
@ -3015,8 +3015,8 @@ $emit-disp:check-for-disp16:
|
|||
e8/call has-metadata?/disp32
|
||||
# . . discard args
|
||||
81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp
|
||||
# . if (eax == 0) goto next check
|
||||
3d/compare-eax-and 0/imm32
|
||||
# . if (eax == false) goto next check
|
||||
3d/compare-eax-and 0/imm32/false
|
||||
74/jump-if-equal $emit-disp:check-for-disp8/disp8
|
||||
$emit-disp:disp16:
|
||||
# emit(out, word-slice, 2)
|
||||
|
@ -3040,8 +3040,8 @@ $emit-disp:check-for-disp8:
|
|||
e8/call has-metadata?/disp32
|
||||
# . . discard args
|
||||
81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp
|
||||
# . if (eax == 0) loop
|
||||
3d/compare-eax-and 0/imm32
|
||||
# . if (eax == false) loop
|
||||
3d/compare-eax-and 0/imm32/false
|
||||
0f 84/jump-if-equal $emit-disp:loop/disp32
|
||||
$emit-disp:disp8:
|
||||
# emit(out, word-slice, 1)
|
||||
|
@ -3069,7 +3069,7 @@ $emit-disp:break:
|
|||
emit-imm: # line : (address stream byte), out : (address buffered-file)
|
||||
# pseudocode:
|
||||
# rewind-stream(line)
|
||||
# var word-slice = {0, 0}
|
||||
# var word-slice : (ref slice)
|
||||
# while true
|
||||
# word-slice = next-word(line)
|
||||
# if (slice-empty?(word-slice)) break
|
||||
|
@ -3091,7 +3091,7 @@ emit-imm: # line : (address stream byte), out : (address buffered-file)
|
|||
50/push-eax
|
||||
51/push-ecx
|
||||
52/push-edx
|
||||
# var word-slice/ecx = {0, 0}
|
||||
# var word-slice/ecx : (ref slice)
|
||||
68/push 0/imm32/end
|
||||
68/push 0/imm32/start
|
||||
89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx
|
||||
|
@ -3186,17 +3186,17 @@ $emit-imm:check0:
|
|||
e8/call slice-empty?/disp32
|
||||
# . . discard args
|
||||
81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp
|
||||
# . if (eax != 0) pass through
|
||||
3d/compare-eax-and 0/imm32
|
||||
# . if (eax != false) pass through
|
||||
3d/compare-eax-and 0/imm32/false
|
||||
0f 85/jump-if-not-equal $emit-imm:break/disp32
|
||||
$emit-imm:check1:
|
||||
# if (slice-starts-with?(word-slice, "#")) break
|
||||
# . start/edx = slice->start
|
||||
# . var start/edx : (address byte) = slice->start
|
||||
8b/copy 0/mod/indirect 1/rm32/ecx . . . 2/r32/edx . . # copy *ecx to edx
|
||||
# . c/eax = *start
|
||||
# . var c/eax : byte = *start
|
||||
31/xor 3/mod/direct 0/rm32/eax . . . 0/r32/eax . . # clear eax
|
||||
8a/copy-byte 0/mod/indirect 2/rm32/edx . . . 0/r32/AL . . # copy byte at *edx to AL
|
||||
# . if (eax == '#') break
|
||||
# . if (c == '#') break
|
||||
3d/compare-eax-and 0x23/imm32/hash
|
||||
0f 84/jump-if-equal $emit-imm:break/disp32
|
||||
$emit-imm:check-for-imm32:
|
||||
|
@ -3209,8 +3209,8 @@ $emit-imm:check-for-imm32:
|
|||
e8/call has-metadata?/disp32
|
||||
# . . discard args
|
||||
81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp
|
||||
# . if (eax == 0) goto next check
|
||||
3d/compare-eax-and 0/imm32
|
||||
# . if (eax == false) goto next check
|
||||
3d/compare-eax-and 0/imm32/false
|
||||
74/jump-if-equal $emit-imm:check-for-imm16/disp8
|
||||
$emit-imm:imm32:
|
||||
# emit(out, word-slice, 4)
|
||||
|
@ -3234,8 +3234,8 @@ $emit-imm:check-for-imm16:
|
|||
e8/call has-metadata?/disp32
|
||||
# . . discard args
|
||||
81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp
|
||||
# . if (eax == 0) goto next check
|
||||
3d/compare-eax-and 0/imm32
|
||||
# . if (eax == false) goto next check
|
||||
3d/compare-eax-and 0/imm32/false
|
||||
74/jump-if-equal $emit-imm:check-for-imm8/disp8
|
||||
$emit-imm:imm16:
|
||||
# emit(out, word-slice, 2)
|
||||
|
@ -3259,8 +3259,8 @@ $emit-imm:check-for-imm8:
|
|||
e8/call has-metadata?/disp32
|
||||
# . . discard args
|
||||
81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp
|
||||
# . if (eax == 0) loop
|
||||
3d/compare-eax-and 0/imm32
|
||||
# . if (eax == false) loop
|
||||
3d/compare-eax-and 0/imm32/false
|
||||
0f 84/jump-if-equal $emit-imm:loop/disp32
|
||||
$emit-imm:imm8:
|
||||
# emit(out, word-slice, 1)
|
||||
|
@ -5837,7 +5837,7 @@ test-convert-instruction-handles-imm8-operand:
|
|||
c3/return
|
||||
|
||||
# shortcut for parse-hex-int(next-token-from-slice(word->start, word->end, '/'))
|
||||
parse-datum-of-word: # word : (address slice) -> value/eax
|
||||
parse-datum-of-word: # word : (address slice) -> value/eax : int
|
||||
# . prologue
|
||||
55/push-ebp
|
||||
89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp
|
||||
|
@ -5846,7 +5846,7 @@ parse-datum-of-word: # word : (address slice) -> value/eax
|
|||
56/push-esi
|
||||
# esi = word
|
||||
8b/copy 1/mod/*+disp8 5/rm32/ebp . . . 6/r32/esi 8/disp8 . # copy *(ebp+8) to esi
|
||||
# var slice/ecx = {0, 0}
|
||||
# var slice/ecx : (ref slice)
|
||||
68/push 0/imm32/end
|
||||
68/push 0/imm32/start
|
||||
89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx
|
||||
|
@ -5860,7 +5860,7 @@ parse-datum-of-word: # word : (address slice) -> value/eax
|
|||
e8/call next-token-from-slice/disp32
|
||||
# . . discard args
|
||||
81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0x10/imm32 # add to esp
|
||||
# value/eax = parse-hex-int(slice)
|
||||
# return parse-hex-int(slice)
|
||||
# . . push args
|
||||
51/push-ecx
|
||||
# . . call
|
||||
|
|
BIN
apps/sigils
BIN
apps/sigils
Binary file not shown.
|
@ -78,8 +78,8 @@ Entry: # run tests if necessary, convert stdin if not
|
|||
e8/call kernel-string-equal?/disp32
|
||||
# . . discard args
|
||||
81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp
|
||||
# . if (eax == 0) goto interactive
|
||||
3d/compare-eax-and 0/imm32
|
||||
# . if (eax == false) goto interactive
|
||||
3d/compare-eax-and 0/imm32/false
|
||||
74/jump-if-equal $subx-sigils-main:interactive/disp8
|
||||
# run-tests()
|
||||
e8/call run-tests/disp32
|
||||
|
@ -147,7 +147,7 @@ subx-sigils: # in : (address buffered-file), out : (address buffered-file)
|
|||
68/push 0/imm32/read
|
||||
68/push 0/imm32/write
|
||||
89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx
|
||||
# var word-slice/edx = {0, 0}
|
||||
# var word-slice/edx : (ref slice)
|
||||
68/push 0/imm32/end
|
||||
68/push 0/imm32/start
|
||||
89/copy 3/mod/direct 2/rm32/edx . . . 4/r32/esp . . # copy esp to edx
|
||||
|
@ -189,8 +189,8 @@ $subx-sigils:check1:
|
|||
e8/call slice-empty?/disp32
|
||||
# . . discard args
|
||||
81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp
|
||||
# . if (eax != 0) break
|
||||
3d/compare-eax-and 0/imm32
|
||||
# . if (eax != false) break
|
||||
3d/compare-eax-and 0/imm32/false
|
||||
0f 85/jump-if-not-equal $subx-sigils:next-line/disp32
|
||||
$subx-sigils:check-for-comment:
|
||||
# if (slice-starts-with?(word-slice, "#")) continue
|
||||
|
@ -269,8 +269,8 @@ $subx-sigils:check-for-indirect-mode:
|
|||
e8/call disp32-mode?/disp32
|
||||
# . . discard args
|
||||
81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp
|
||||
# . if (eax == 0) goto indirect mode
|
||||
3d/compare-eax-and 0/imm32
|
||||
# . if (eax == false) goto indirect mode
|
||||
3d/compare-eax-and 0/imm32/false
|
||||
74/jump-if-equal $subx-sigils:indirect-mode/disp8
|
||||
$subx-sigils:disp32-mode:
|
||||
# emit-indirect-mode(out, word-slice)
|
||||
|
@ -1365,7 +1365,7 @@ emit-direct-mode: # out : (address buffered-file), word-slice : (address slice)
|
|||
89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp
|
||||
# . save registers
|
||||
50/push-eax
|
||||
# var local-slice/eax : (address slice) = {word-slice->start, word-slice->end}
|
||||
# var local-slice/eax : (ref slice) = {word-slice->start, word-slice->end}
|
||||
8b/copy 1/mod/*+disp8 5/rm32/ebp . . . 0/r32/eax 0xc/disp8 . # copy *(ebp+12) to eax
|
||||
ff 6/subop/push 1/mod/*+disp8 0/rm32/eax . . . . 4/disp8 . # push *(eax+4)
|
||||
ff 6/subop/push 0/mod/indirect 0/rm32/eax . . . . . . # push *eax
|
||||
|
@ -1834,7 +1834,7 @@ test-next-word-or-expression:
|
|||
e8/call clear-stream/disp32
|
||||
# . . discard args
|
||||
81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp
|
||||
# var slice/ecx = {0, 0}
|
||||
# var slice/ecx : (ref slice)
|
||||
68/push 0/imm32/end
|
||||
68/push 0/imm32/start
|
||||
89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx
|
||||
|
@ -1907,7 +1907,7 @@ test-next-word-or-expression-returns-whole-comment:
|
|||
e8/call clear-stream/disp32
|
||||
# . . discard args
|
||||
81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp
|
||||
# var slice/ecx = {0, 0}
|
||||
# var slice/ecx : (ref slice)
|
||||
68/push 0/imm32/end
|
||||
68/push 0/imm32/start
|
||||
89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx
|
||||
|
@ -1980,7 +1980,7 @@ test-next-word-or-expression-returns-empty-slice-on-eof:
|
|||
e8/call clear-stream/disp32
|
||||
# . . discard args
|
||||
81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp
|
||||
# var slice/ecx = {0, 0}
|
||||
# var slice/ecx : (ref slice)
|
||||
68/push 0/imm32/end
|
||||
68/push 0/imm32/start
|
||||
89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx
|
||||
|
@ -2022,7 +2022,7 @@ test-next-word-or-expression-returns-string-literal:
|
|||
e8/call clear-stream/disp32
|
||||
# . . discard args
|
||||
81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp
|
||||
# var slice/ecx = {0, 0}
|
||||
# var slice/ecx : (ref slice)
|
||||
68/push 0/imm32/end
|
||||
68/push 0/imm32/start
|
||||
89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx
|
||||
|
@ -2085,7 +2085,7 @@ test-next-word-or-expression-returns-string-with-escapes:
|
|||
e8/call clear-stream/disp32
|
||||
# . . discard args
|
||||
81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp
|
||||
# var slice/ecx = {0, 0}
|
||||
# var slice/ecx : (ref slice)
|
||||
68/push 0/imm32/end
|
||||
68/push 0/imm32/start
|
||||
89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx
|
||||
|
@ -2148,7 +2148,7 @@ test-next-word-or-expression-returns-whole-expression:
|
|||
e8/call clear-stream/disp32
|
||||
# . . discard args
|
||||
81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp
|
||||
# var slice/ecx = {0, 0}
|
||||
# var slice/ecx : (ref slice)
|
||||
68/push 0/imm32/end
|
||||
68/push 0/imm32/start
|
||||
89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx
|
||||
|
@ -2250,7 +2250,7 @@ parse-effective-address: # word-slice : (address slice) -> base/eax, index/ecx,
|
|||
# . save registers
|
||||
56/push-esi
|
||||
57/push-edi
|
||||
# var local-slice/esi : (address slice) = {word-slice->start, word-slice->end}
|
||||
# var local-slice/esi : (ref slice) = {word-slice->start, word-slice->end}
|
||||
8b/copy 1/mod/*+disp8 5/rm32/ebp . . . 6/r32/esi 8/disp8 . # copy *(ebp+8) to esi
|
||||
ff 6/subop/push 1/mod/*+disp8 6/rm32/esi . . . . 4/disp8 . # push *(esi+4)
|
||||
ff 6/subop/push 0/mod/indirect 6/rm32/esi . . . . . . # push *esi
|
||||
|
@ -2679,7 +2679,7 @@ next-register: # in : (address slice) -> reg/eax : int
|
|||
56/push-esi
|
||||
# esi = in
|
||||
8b/copy 1/mod/*+disp8 5/rm32/ebp . . . 6/r32/esi 8/disp8 . # copy *(ebp+8) to esi
|
||||
# var reg-slice/ecx : (address slice) = {in->start, in->start + 3}
|
||||
# var reg-slice/ecx : (ref slice) = {in->start, in->start + 3}
|
||||
8b/copy 0/mod/indirect 6/rm32/esi . . . 0/r32/eax . . # copy *esi to eax
|
||||
05/add-to-eax 3/imm32
|
||||
50/push-eax
|
||||
|
@ -3865,7 +3865,7 @@ disp32-mode?: # in : (address slice) -> reg/eax : boolean
|
|||
# . save registers
|
||||
56/push-esi
|
||||
57/push-edi
|
||||
# var local-slice/esi : (address slice) = {in->start, in->end}
|
||||
# var local-slice/esi : (ref slice) = {in->start, in->end}
|
||||
8b/copy 1/mod/*+disp8 5/rm32/ebp . . . 6/r32/esi 8/disp8 . # copy *(ebp+8) to esi
|
||||
ff 6/subop/push 1/mod/*+disp8 6/rm32/esi . . . . 4/disp8 . # push *(esi+4)
|
||||
ff 6/subop/push 0/mod/indirect 6/rm32/esi . . . . . . # push *esi
|
||||
|
@ -3923,7 +3923,7 @@ emit-indirect-disp32: # out : (address buffered-file), word-slice : (address sl
|
|||
89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp
|
||||
# . save registers
|
||||
56/push-esi
|
||||
# var local-slice/esi : (address slice) = {in->start, in->end}
|
||||
# var local-slice/esi : (ref slice) = {in->start, in->end}
|
||||
8b/copy 1/mod/*+disp8 5/rm32/ebp . . . 6/r32/esi 0xc/disp8 . # copy *(ebp+12) to esi
|
||||
ff 6/subop/push 1/mod/*+disp8 6/rm32/esi . . . . 4/disp8 . # push *(esi+4)
|
||||
ff 6/subop/push 0/mod/indirect 6/rm32/esi . . . . . . # push *esi
|
||||
|
@ -4055,8 +4055,8 @@ $next-hex-int:loop:
|
|||
e8/call is-hex-digit?/disp32
|
||||
# . . discard args
|
||||
81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp
|
||||
# . if (eax == 0) break
|
||||
3d/compare-eax-and 0/imm32
|
||||
# . if (eax == false) break
|
||||
3d/compare-eax-and 0/imm32/false
|
||||
74/jump-if-equal $next-hex-int:break/disp8
|
||||
# eax = from-hex-char(*curr)
|
||||
# . . copy arg to eax
|
||||
|
@ -4071,7 +4071,8 @@ $next-hex-int:loop:
|
|||
# loop
|
||||
eb/jump $next-hex-int:loop/disp8
|
||||
$next-hex-int:break:
|
||||
81 7/subop/compare 3/mod/direct 3/rm32/ebx . . . . . 0/imm32 # compare ebx
|
||||
# if (negate?) result = -result
|
||||
81 7/subop/compare 3/mod/direct 3/rm32/ebx . . . . . 0/imm32/false # compare ebx
|
||||
74/jump-if-equal $next-hex-int:end/disp8
|
||||
$next-hex-int:negate:
|
||||
f7 3/subop/negate 3/mod/direct 7/rm32/edi . . . . . . # negate edi
|
||||
|
@ -4437,8 +4438,8 @@ $next-positive-hex-int:loop:
|
|||
e8/call is-hex-digit?/disp32
|
||||
# . . discard args
|
||||
81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp
|
||||
# . if (eax == 0) break
|
||||
3d/compare-eax-and 0/imm32
|
||||
# . if (eax == false) break
|
||||
3d/compare-eax-and 0/imm32/false
|
||||
74/jump-if-equal $next-positive-hex-int:end/disp8
|
||||
# eax = from-hex-char(*curr)
|
||||
# . . copy arg to eax
|
||||
|
|
BIN
apps/survey
BIN
apps/survey
Binary file not shown.
142
apps/survey.subx
142
apps/survey.subx
|
@ -74,8 +74,8 @@ Entry: # run tests if necessary, convert stdin if not
|
|||
e8/call kernel-string-equal?/disp32
|
||||
# . . discard args
|
||||
81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp
|
||||
# . if (eax == 0) goto interactive
|
||||
3d/compare-eax-and 0/imm32
|
||||
# . if (eax == false) goto interactive
|
||||
3d/compare-eax-and 0/imm32/false
|
||||
74/jump-if-equal $subx-survey-main:interactive/disp8
|
||||
# run-tests()
|
||||
e8/call run-tests/disp32
|
||||
|
@ -115,9 +115,9 @@ $subx-survey-main:end:
|
|||
|
||||
subx-survey: # infile : (address buffered-file), out : (address buffered-file)
|
||||
# pseudocode
|
||||
# var in : (address stream byte) = stream(4096)
|
||||
# var in : (ref stream byte 4096)
|
||||
# slurp(infile, in)
|
||||
# var segments : (stream segment-info 10)
|
||||
# var segments : (stream segment-info)
|
||||
# var labels : (stream label-info Max-labels)
|
||||
# compute-offsets(in, segments, labels)
|
||||
# compute-addresses(segments, labels)
|
||||
|
@ -131,13 +131,13 @@ subx-survey: # infile : (address buffered-file), out : (address buffered-file)
|
|||
51/push-ecx
|
||||
52/push-edx
|
||||
56/push-esi
|
||||
# var segments/ecx = stream(10 * 16)
|
||||
# var segments/ecx : (ref 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
|
||||
68/push 0xa0/imm32/length
|
||||
68/push 0/imm32/read
|
||||
68/push 0/imm32/write
|
||||
89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx
|
||||
# var labels/edx = stream(Max-labels * 16)
|
||||
# var labels/edx : (ref stream label-info Max-labels*16)
|
||||
# . data
|
||||
2b/subtract 0/mod/indirect 5/rm32/.disp32 . . 4/r32/esp Max-labels/disp32 # subtract *Max-labels from esp
|
||||
# . length
|
||||
|
@ -147,7 +147,7 @@ subx-survey: # infile : (address buffered-file), out : (address buffered-file)
|
|||
# . write
|
||||
68/push 0/imm32/write
|
||||
89/copy 3/mod/direct 2/rm32/edx . . . 4/r32/esp . . # copy esp to edx
|
||||
# var in/esi = stream(Input-size * 1)
|
||||
# var in/esi : (ref stream byte Input-size)
|
||||
# . data
|
||||
2b/subtract 0/mod/indirect 5/rm32/.disp32 . . 4/r32/esp Input-size/disp32 # subtract *Input-size from esp
|
||||
# . length
|
||||
|
@ -618,7 +618,7 @@ compute-offsets:segment-tmp: # slice
|
|||
|
||||
== code
|
||||
|
||||
compute-offsets: # in : (address stream), segments : (address stream {string, segment-info}), labels : (address stream {string, label-info})
|
||||
compute-offsets: # in : (address stream byte), segments : (address stream {string, segment-info}), labels : (address stream {string, label-info})
|
||||
# skeleton:
|
||||
# for lines in 'in'
|
||||
# for words in line
|
||||
|
@ -833,8 +833,8 @@ $compute-offsets:case-empty:
|
|||
e8/call slice-empty?/disp32
|
||||
# . . discard args
|
||||
81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp
|
||||
# . if (eax != 0) break
|
||||
3d/compare-eax-and 0/imm32
|
||||
# . if (eax != false) break
|
||||
3d/compare-eax-and 0/imm32/false
|
||||
0f 85/jump-if-not-equal $compute-offsets:line-loop/disp32
|
||||
$compute-offsets:case-comment:
|
||||
# if slice-starts-with?(word-slice, "#") continue
|
||||
|
@ -843,8 +843,8 @@ $compute-offsets:case-comment:
|
|||
e8/call slice-starts-with?/disp32
|
||||
# . . discard args
|
||||
81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp
|
||||
# . if (eax != 0) break
|
||||
3d/compare-eax-and 0/imm32
|
||||
# . if (eax != false) break
|
||||
3d/compare-eax-and 0/imm32/false
|
||||
0f 85/jump-if-not-equal $compute-offsets:line-loop/disp32
|
||||
$compute-offsets:case-segment-header:
|
||||
# if (!slice-equal?(word-slice/edx, "==")) goto next case
|
||||
|
@ -854,8 +854,8 @@ $compute-offsets:case-segment-header:
|
|||
e8/call slice-equal?/disp32
|
||||
# . . discard args
|
||||
81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp
|
||||
# . if (eax == 0) goto next case
|
||||
3d/compare-eax-and 0/imm32
|
||||
# . if (eax == false) goto next case
|
||||
3d/compare-eax-and 0/imm32/false
|
||||
0f 84/jump-if-equal $compute-offsets:case-label/disp32
|
||||
# if (curr-segment-name == 0) goto construct-next-segment
|
||||
81 7/subop/compare 3/mod/direct 6/rm32/esi . . . . . 0/imm32 # compare esi
|
||||
|
@ -973,8 +973,8 @@ $compute-offsets:update-curr-segment-name:
|
|||
e8/call slice-empty?/disp32
|
||||
# . . discard args
|
||||
81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp
|
||||
# . if (eax != 0) abort
|
||||
3d/compare-eax-and 0/imm32
|
||||
# . if (eax != false) abort
|
||||
3d/compare-eax-and 0/imm32/false
|
||||
0f 85/jump-if-not-equal $compute-offsets:abort/disp32
|
||||
# seg/ebx = get-or-insert(segments, curr-segment-name, row-size=16)
|
||||
# . . push args
|
||||
|
@ -1022,8 +1022,8 @@ $compute-offsets:case-label:
|
|||
e8/call is-label?/disp32
|
||||
# . . discard args
|
||||
81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp
|
||||
# . if (eax == 0) goto next case
|
||||
3d/compare-eax-and 0/imm32
|
||||
# . if (eax == false) goto next case
|
||||
3d/compare-eax-and 0/imm32/false
|
||||
74/jump-if-equal $compute-offsets:case-default/disp8
|
||||
# strip trailing ':' from word-slice
|
||||
ff 1/subop/decrement 1/mod/*+disp8 2/rm32/edx . . . . 4/disp8 . # decrement *(edx+4)
|
||||
|
@ -1219,13 +1219,13 @@ test-compute-offsets:
|
|||
e8/call clear-stream/disp32
|
||||
# . . discard args
|
||||
81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp
|
||||
# var segments/ecx = stream(2 * 16)
|
||||
# var segments/ecx : (ref stream byte 2*16)
|
||||
81 5/subop/subtract 3/mod/direct 4/rm32/esp . . . . . 0x20/imm32 # subtract from esp
|
||||
68/push 0x20/imm32/length
|
||||
68/push 0/imm32/read
|
||||
68/push 0/imm32/write
|
||||
89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx
|
||||
# var labels/edx = stream(2 * 16)
|
||||
# var labels/edx : (ref stream byte 2*16)
|
||||
81 5/subop/subtract 3/mod/direct 4/rm32/esp . . . . . 0x20/imm32 # subtract from esp
|
||||
68/push 0x20/imm32/length
|
||||
68/push 0/imm32/read
|
||||
|
@ -1381,7 +1381,7 @@ test-compute-offsets:
|
|||
compute-addresses: # segments : (address stream {string, segment-info}), labels : (address stream {string, label-info})
|
||||
# pseudocode:
|
||||
# srow : (address segment-info) = segments->data
|
||||
# max = segments->data + segments->write
|
||||
# max = &segments->data[segments->write]
|
||||
# num-segments = segments->write / 16
|
||||
# starting-offset = 0x34 + (num-segments * 0x20)
|
||||
# while true
|
||||
|
@ -1392,7 +1392,7 @@ compute-addresses: # segments : (address stream {string, segment-info}), labels
|
|||
# trace-sssns("segment " s->key " starts at address " s->address)
|
||||
# srow += 16 # row-size
|
||||
# lrow : (address label-info) = labels->data
|
||||
# max = labels->data + labels->write
|
||||
# max = &labels->data[labels->write]
|
||||
# while true
|
||||
# if (lrow >= max) break
|
||||
# seg-name : (address string) = lrow->segment-name
|
||||
|
@ -1422,7 +1422,7 @@ compute-addresses: # segments : (address stream {string, segment-info}), labels
|
|||
81 0/subop/add 3/mod/direct 7/rm32/edi . . . . . 0x34/imm32 # add to edi
|
||||
# srow/eax = segments->data
|
||||
8d/copy-address 1/mod/*+disp8 6/rm32/esi . . . 0/r32/eax 0xc/disp8 . # copy esi+12 to eax
|
||||
# max/ecx = segments->data + segments->write
|
||||
# max/ecx = &segments->data[segments->write]
|
||||
8b/copy 0/mod/indirect 6/rm32/esi . . . 1/r32/ecx . . # copy *esi to ecx
|
||||
01/add 3/mod/direct 1/rm32/ecx . . . 6/r32/esi . . # add esi to ecx
|
||||
$compute-addresses:segment-loop:
|
||||
|
@ -1489,7 +1489,7 @@ $compute-addresses:segment-break:
|
|||
8b/copy 1/mod/*+disp8 5/rm32/ebp . . . 6/r32/esi 0xc/disp8 . # copy *(ebp+12) to esi
|
||||
# lrow/eax = labels->data
|
||||
8d/copy-address 1/mod/*+disp8 6/rm32/esi . . . 0/r32/eax 0xc/disp8 . # copy esi+12 to eax
|
||||
# max/ecx = labels->data + labels->write
|
||||
# max/ecx = &labels->data[labels->write]
|
||||
8b/copy 0/mod/indirect 6/rm32/esi . . . 1/r32/ecx . . # copy *esi to ecx
|
||||
01/add 3/mod/direct 1/rm32/ecx . . . 6/r32/esi . . # add esi to ecx
|
||||
$compute-addresses:label-loop:
|
||||
|
@ -1621,13 +1621,13 @@ test-compute-addresses:
|
|||
55/push-ebp
|
||||
89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp
|
||||
# setup
|
||||
# . var segments/ecx = stream(10 * 16)
|
||||
# . var segments/ecx : (ref stream byte 10*16)
|
||||
81 5/subop/subtract 3/mod/direct 4/rm32/esp . . . . . 0xa0/imm32 # subtract from esp
|
||||
68/push 0xa0/imm32/length
|
||||
68/push 0/imm32/read
|
||||
68/push 0/imm32/write
|
||||
89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx
|
||||
# . var labels/edx = stream(512 * 16)
|
||||
# . var labels/edx : (ref stream byte 512*16)
|
||||
81 5/subop/subtract 3/mod/direct 4/rm32/esp . . . . . 0x2000/imm32 # subtract from esp
|
||||
68/push 0x2000/imm32/length
|
||||
68/push 0/imm32/read
|
||||
|
@ -1790,13 +1790,13 @@ test-compute-addresses-large-segments:
|
|||
55/push-ebp
|
||||
89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp
|
||||
# setup
|
||||
# . var segments/ecx = stream(10 * 16)
|
||||
# . var segments/ecx : (ref stream byte 10*16)
|
||||
81 5/subop/subtract 3/mod/direct 4/rm32/esp . . . . . 0xa0/imm32 # subtract from esp
|
||||
68/push 0xa0/imm32/length
|
||||
68/push 0/imm32/read
|
||||
68/push 0/imm32/write
|
||||
89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx
|
||||
# . var labels/edx = stream(512 * 16)
|
||||
# . var labels/edx : (ref stream byte 512*16)
|
||||
81 5/subop/subtract 3/mod/direct 4/rm32/esp . . . . . 0x2000/imm32 # subtract from esp
|
||||
68/push 0x2000/imm32/length
|
||||
68/push 0/imm32/read
|
||||
|
@ -1871,7 +1871,7 @@ test-compute-addresses-large-segments:
|
|||
5d/pop-to-ebp
|
||||
c3/return
|
||||
|
||||
emit-output: # in : (address stream), out : (address buffered-file), segments : (address stream {string, segment-info}), labels : (address stream {string, label-info})
|
||||
emit-output: # in : (address stream byte), out : (address buffered-file), segments : (address stream {string, segment-info}), labels : (address stream {string, label-info})
|
||||
# pseudocode:
|
||||
# emit-headers(out, segments, labels)
|
||||
# emit-segments(in, out, segments, labels)
|
||||
|
@ -1922,7 +1922,7 @@ $emit-output:end:
|
|||
5d/pop-to-ebp
|
||||
c3/return
|
||||
|
||||
emit-segments: # in : (address stream), out : (address buffered-file), segments : (address stream {string, segment-info}), labels : (address stream {string, label-info})
|
||||
emit-segments: # in : (address stream byte), out : (address buffered-file), segments : (address stream {string, segment-info}), labels : (address stream {string, label-info})
|
||||
# pseudocode:
|
||||
# var offset-of-next-instruction = 0
|
||||
# var line : (stream byte 512)
|
||||
|
@ -1993,11 +1993,11 @@ emit-segments: # in : (address stream), out : (address buffered-file), segments
|
|||
68/push 0/imm32/read
|
||||
68/push 0/imm32/write
|
||||
89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx
|
||||
# var word-slice/edx = {0, 0}
|
||||
# var word-slice/edx : (ref slice)
|
||||
68/push 0/imm32/end
|
||||
68/push 0/imm32/start
|
||||
89/copy 3/mod/direct 2/rm32/edx . . . 4/r32/esp . . # copy esp to edx
|
||||
# var datum/edi = {0, 0}
|
||||
# var datum/edi : (ref slice)
|
||||
68/push 0/imm32/end
|
||||
68/push 0/imm32/start
|
||||
89/copy 3/mod/direct 7/rm32/edi . . . 4/r32/esp . . # copy esp to edi
|
||||
|
@ -2139,8 +2139,8 @@ $emit-segments:check-for-label:
|
|||
e8/call is-label?/disp32
|
||||
# . . discard args
|
||||
81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp
|
||||
# . if (eax != 0) break
|
||||
3d/compare-eax-and 0/imm32
|
||||
# . if (eax != false) break
|
||||
3d/compare-eax-and 0/imm32/false
|
||||
0f 85/jump-if-not-equal $emit-segments:line-loop/disp32
|
||||
$emit-segments:check-for-segment-header:
|
||||
# if (slice-equal?(word-slice, "==")) break
|
||||
|
@ -2152,8 +2152,8 @@ $emit-segments:check-for-segment-header:
|
|||
e8/call slice-equal?/disp32
|
||||
# . . discard args
|
||||
81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp
|
||||
# . if (eax != 0) break
|
||||
3d/compare-eax-and 0/imm32
|
||||
# . if (eax != false) break
|
||||
3d/compare-eax-and 0/imm32/false
|
||||
0f 85/jump-if-not-equal $emit-segments:line-loop/disp32
|
||||
$emit-segments:2-character:
|
||||
# if (length(word-slice) != 2) goto next check
|
||||
|
@ -2275,8 +2275,8 @@ $emit-segments:check-global-variable:
|
|||
e8/call string-equal?/disp32
|
||||
# . . discard args
|
||||
81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp
|
||||
# . if (eax != 0) goto code label checks
|
||||
3d/compare-eax-and 0/imm32
|
||||
# . if (eax != false) goto code label checks
|
||||
3d/compare-eax-and 0/imm32/false
|
||||
0f 85/jump-if-not-equal $emit-segments:check-code-label-for-imm8/disp32
|
||||
$emit-segments:check-global-variable-for-disp8:
|
||||
# if has-metadata?(word-slice, "disp8") abort
|
||||
|
@ -2288,8 +2288,8 @@ $emit-segments:check-global-variable-for-disp8:
|
|||
e8/call has-metadata?/disp32
|
||||
# . . discard args
|
||||
81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp
|
||||
# . if (eax != 0) abort
|
||||
3d/compare-eax-and 0/imm32
|
||||
# . if (eax != false) abort
|
||||
3d/compare-eax-and 0/imm32/false
|
||||
0f 85/jump-if-not-equal $emit-segments:global-variable-abort/disp32
|
||||
$emit-segments:check-global-variable-for-imm8:
|
||||
# if has-metadata?(word-slice, "imm8") abort
|
||||
|
@ -2301,8 +2301,8 @@ $emit-segments:check-global-variable-for-imm8:
|
|||
e8/call has-metadata?/disp32
|
||||
# . . discard args
|
||||
81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp
|
||||
# . if (eax != 0) abort
|
||||
3d/compare-eax-and 0/imm32
|
||||
# . if (eax != false) abort
|
||||
3d/compare-eax-and 0/imm32/false
|
||||
0f 85/jump-if-not-equal $emit-segments:global-variable-abort/disp32
|
||||
$emit-segments:emit-global-variable:
|
||||
# emit-hex(out, info->address, 4)
|
||||
|
@ -2326,8 +2326,8 @@ $emit-segments:check-code-label-for-imm8:
|
|||
e8/call has-metadata?/disp32
|
||||
# . . discard args
|
||||
81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp
|
||||
# . if (eax != 0) abort
|
||||
3d/compare-eax-and 0/imm32
|
||||
# . if (eax != false) abort
|
||||
3d/compare-eax-and 0/imm32/false
|
||||
0f 85/jump-if-not-equal $emit-segments:imm8-abort/disp32
|
||||
$emit-segments:check-code-label-for-imm32:
|
||||
# if (!has-metadata?(word-slice, "imm32")) goto next check
|
||||
|
@ -2339,7 +2339,7 @@ $emit-segments:check-code-label-for-imm32:
|
|||
e8/call has-metadata?/disp32
|
||||
# . . discard args
|
||||
81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp
|
||||
# . if (eax == 0) goto next check
|
||||
# . if (eax == false) goto next check
|
||||
3d/compare-eax-and 0/imm32
|
||||
74/jump-if-equal $emit-segments:check-code-label-for-disp8/disp8
|
||||
#? # dump info->address {{{
|
||||
|
@ -2397,8 +2397,8 @@ $emit-segments:check-code-label-for-disp8:
|
|||
e8/call has-metadata?/disp32
|
||||
# . . discard args
|
||||
81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp
|
||||
# . if (eax == 0) goto next check
|
||||
3d/compare-eax-and 0/imm32
|
||||
# . if (eax == false) goto next check
|
||||
3d/compare-eax-and 0/imm32/false
|
||||
74/jump-if-equal $emit-segments:check-code-label-for-disp32/disp8
|
||||
$emit-segments:emit-code-label-disp8:
|
||||
# emit-hex(out, info->offset - offset-of-next-instruction, 1)
|
||||
|
@ -2424,8 +2424,8 @@ $emit-segments:check-code-label-for-disp32:
|
|||
e8/call has-metadata?/disp32
|
||||
# . . discard args
|
||||
81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp
|
||||
# . if (eax == 0) abort
|
||||
3d/compare-eax-and 0/imm32
|
||||
# . if (eax == false) abort
|
||||
3d/compare-eax-and 0/imm32/false
|
||||
0f 84/jump-if-equal $emit-segments:abort/disp32
|
||||
$emit-segments:emit-code-label-disp32:
|
||||
# emit-hex(out, info->offset - offset-of-next-instruction, 4)
|
||||
|
@ -2577,13 +2577,13 @@ test-emit-segments-global-variable:
|
|||
e8/call clear-stream/disp32
|
||||
# . . discard args
|
||||
81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp
|
||||
# . var segments/ecx = stream(10 * 16)
|
||||
# . var segments/ecx : (ref stream byte 10*16)
|
||||
81 5/subop/subtract 3/mod/direct 4/rm32/esp . . . . . 0xa0/imm32 # subtract from esp
|
||||
68/push 0xa0/imm32/length
|
||||
68/push 0/imm32/read
|
||||
68/push 0/imm32/write
|
||||
89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx
|
||||
# . var labels/edx = stream(512 * 16)
|
||||
# . var labels/edx : (ref stream byte 512*16)
|
||||
81 5/subop/subtract 3/mod/direct 4/rm32/esp . . . . . 0x2000/imm32 # subtract from esp
|
||||
68/push 0x2000/imm32/length
|
||||
68/push 0/imm32/read
|
||||
|
@ -2814,13 +2814,13 @@ test-emit-segments-code-label:
|
|||
e8/call clear-stream/disp32
|
||||
# . . discard args
|
||||
81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp
|
||||
# . var segments/ecx = stream(10 * 16)
|
||||
# . var segments/ecx : (ref stream byte 10*16)
|
||||
81 5/subop/subtract 3/mod/direct 4/rm32/esp . . . . . 0xa0/imm32 # subtract from esp
|
||||
68/push 0xa0/imm32/length
|
||||
68/push 0/imm32/read
|
||||
68/push 0/imm32/write
|
||||
89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx
|
||||
# . var labels/edx = stream(512 * 16)
|
||||
# . var labels/edx : (ref stream byte 512*16)
|
||||
81 5/subop/subtract 3/mod/direct 4/rm32/esp . . . . . 0x2000/imm32 # subtract from esp
|
||||
68/push 0x2000/imm32/length
|
||||
68/push 0/imm32/read
|
||||
|
@ -3016,13 +3016,13 @@ test-emit-segments-code-label-absolute:
|
|||
e8/call clear-stream/disp32
|
||||
# . . discard args
|
||||
81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp
|
||||
# . var segments/ecx = stream(10 * 16)
|
||||
# . var segments/ecx : (ref stream byte 10*16)
|
||||
81 5/subop/subtract 3/mod/direct 4/rm32/esp . . . . . 0xa0/imm32 # subtract from esp
|
||||
68/push 0xa0/imm32/length
|
||||
68/push 0/imm32/read
|
||||
68/push 0/imm32/write
|
||||
89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx
|
||||
# . var labels/edx = stream(512 * 16)
|
||||
# . var labels/edx : (ref stream byte 512*16)
|
||||
81 5/subop/subtract 3/mod/direct 4/rm32/esp . . . . . 0x2000/imm32 # subtract from esp
|
||||
68/push 0x2000/imm32/length
|
||||
68/push 0/imm32/read
|
||||
|
@ -3177,7 +3177,7 @@ emit-headers: # out : (address buffered-file), segments : (address stream {stri
|
|||
# pseudocode:
|
||||
# emit-elf-header(out, segments, labels)
|
||||
# curr-segment = segments->data
|
||||
# max = segments->data + segments->write
|
||||
# max = &segments->data[segments->write]
|
||||
# while true
|
||||
# if (curr-segment >= max) break
|
||||
# emit-elf-program-header-entry(out, curr-segment)
|
||||
|
@ -3213,7 +3213,7 @@ emit-headers: # out : (address buffered-file), segments : (address stream {stri
|
|||
8b/copy 0/mod/indirect 0/rm32/eax . . . 1/r32/ecx . . # copy *eax to ecx
|
||||
# curr-segment/eax = segments->data
|
||||
8d/copy-address 1/mod/*+disp8 0/rm32/eax . . . 0/r32/eax 0xc/disp8 . # copy eax+12 to eax
|
||||
# max/ecx = segments->data + segments->write
|
||||
# max/ecx = &segments->data[segments->write]
|
||||
01/add 3/mod/direct 1/rm32/ecx . . . 0/r32/eax . . # add eax to ecx
|
||||
$emit-headers:loop:
|
||||
# if (curr-segment >= max) break
|
||||
|
@ -3431,8 +3431,8 @@ emit-elf-program-header-entry: # out : (address buffered-file), curr-segment :
|
|||
e8/call string-equal?/disp32
|
||||
# . . discard args
|
||||
81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp
|
||||
# . if (eax == 0) goto next check
|
||||
3d/compare-eax-and 0/imm32
|
||||
# . if (eax == false) goto next check
|
||||
3d/compare-eax-and 0/imm32/false
|
||||
74/jump-if-equal $emit-elf-program-header-entry:data/disp8
|
||||
# *$Elf_p_flags = r-x
|
||||
c7 0/subop/copy 0/mod/indirect 5/rm32/.disp32 . . . $Elf_p_flags/disp32 5/imm32 # copy to *$Elf_p_flags
|
||||
|
@ -3479,12 +3479,12 @@ stream-add4: # in : (address stream byte), key : address, val1 : address, val2
|
|||
56/push-esi
|
||||
# esi = in
|
||||
8b/copy 1/mod/*+disp8 5/rm32/ebp . . . 6/r32/esi 8/disp8 . # copy *(ebp+8) to esi
|
||||
# curr/eax = in->data + in->write
|
||||
# curr/eax = &in->data[in->write]
|
||||
# . eax = in->write
|
||||
8b/copy 0/mod/indirect 6/rm32/esi . . . 0/r32/eax . . # copy *esi to eax
|
||||
# . 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
|
||||
# max/edx = in->data + in->length
|
||||
# max/edx = &in->data[in->length]
|
||||
# . edx = in->length
|
||||
8b/copy 1/mod/*+disp8 6/rm32/esi . . . 2/r32/edx 8/disp8 . # copy *(esi+8) to edx
|
||||
# . edx = esi+edx+12
|
||||
|
@ -3830,7 +3830,7 @@ test-trace-slsls:
|
|||
8b/copy 0/mod/indirect 0/rm32/eax . . . 1/r32/ecx . . # copy *eax to ecx
|
||||
8d/copy-address 1/mod/*+disp8 4/rm32/sib 0/base/eax 1/index/ecx . 1/r32/ecx 4/disp8 . # copy eax+ecx+4 to ecx
|
||||
05/add-to-eax 4/imm32
|
||||
# var b/ebx : (address slice) = {eax, ecx}
|
||||
# var b/ebx : (ref slice) = {eax, ecx}
|
||||
51/push-ecx
|
||||
50/push-eax
|
||||
89/copy 3/mod/direct 3/rm32/ebx . . . 4/r32/esp . . # copy esp to ebx
|
||||
|
@ -3839,7 +3839,7 @@ test-trace-slsls:
|
|||
8b/copy 0/mod/indirect 0/rm32/eax . . . 1/r32/ecx . . # copy *eax to ecx
|
||||
8d/copy-address 1/mod/*+disp8 4/rm32/sib 0/base/eax 1/index/ecx . 1/r32/ecx 4/disp8 . # copy eax+ecx+4 to ecx
|
||||
05/add-to-eax 4/imm32
|
||||
# var d/edx : (address slice) = {eax, ecx}
|
||||
# var d/edx : (ref slice) = {eax, ecx}
|
||||
51/push-ecx
|
||||
50/push-eax
|
||||
89/copy 3/mod/direct 2/rm32/edx . . . 4/r32/esp . . # copy esp to edx
|
||||
|
@ -3955,7 +3955,7 @@ test-trace-slsns:
|
|||
8b/copy 0/mod/indirect 0/rm32/eax . . . 1/r32/ecx . . # copy *eax to ecx
|
||||
8d/copy-address 1/mod/*+disp8 4/rm32/sib 0/base/eax 1/index/ecx . 1/r32/ecx 4/disp8 . # copy eax+ecx+4 to ecx
|
||||
05/add-to-eax 4/imm32
|
||||
# var b/ebx : (address slice) = {eax, ecx}
|
||||
# var b/ebx : (ref slice) = {eax, ecx}
|
||||
51/push-ecx
|
||||
50/push-eax
|
||||
89/copy 3/mod/direct 3/rm32/ebx . . . 4/r32/esp . . # copy esp to ebx
|
||||
|
@ -4071,7 +4071,7 @@ test-trace-slsss:
|
|||
8b/copy 0/mod/indirect 0/rm32/eax . . . 1/r32/ecx . . # copy *eax to ecx
|
||||
8d/copy-address 1/mod/*+disp8 4/rm32/sib 0/base/eax 1/index/ecx . 1/r32/ecx 4/disp8 . # copy eax+ecx+4 to ecx
|
||||
05/add-to-eax 4/imm32
|
||||
# var b/ebx : (address slice) = {eax, ecx}
|
||||
# var b/ebx : (ref slice) = {eax, ecx}
|
||||
51/push-ecx
|
||||
50/push-eax
|
||||
89/copy 3/mod/direct 3/rm32/ebx . . . 4/r32/esp . . # copy esp to ebx
|
||||
|
@ -4125,7 +4125,7 @@ test-trace-slsss:
|
|||
5d/pop-to-ebp
|
||||
c3/return
|
||||
|
||||
num-bytes: # line : (address stream) -> eax : int
|
||||
num-bytes: # line : (address stream byte) -> eax : int
|
||||
# pseudocode:
|
||||
# result = 0
|
||||
# while true
|
||||
|
@ -4150,7 +4150,7 @@ num-bytes: # line : (address stream) -> eax : int
|
|||
53/push-ebx
|
||||
# var result/eax = 0
|
||||
31/xor 3/mod/direct 0/rm32/eax . . . 0/r32/eax . . # clear eax
|
||||
# var word-slice/ecx = {0, 0}
|
||||
# var word-slice/ecx : (ref slice)
|
||||
68/push 0/imm32/end
|
||||
68/push 0/imm32/start
|
||||
89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx
|
||||
|
@ -4247,8 +4247,8 @@ $num-bytes:check0:
|
|||
e8/call slice-empty?/disp32
|
||||
# . . discard args
|
||||
81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp
|
||||
# . if (eax != 0) break
|
||||
3d/compare-eax-and 0/imm32
|
||||
# . if (eax != false) break
|
||||
3d/compare-eax-and 0/imm32/false
|
||||
# . restore result now that ZF is set
|
||||
58/pop-to-eax
|
||||
75/jump-if-not-equal $num-bytes:end/disp8
|
||||
|
@ -4284,8 +4284,8 @@ $num-bytes:check-for-segment-header:
|
|||
e8/call slice-equal?/disp32
|
||||
# . . discard args
|
||||
81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp
|
||||
# . if (eax != 0) break
|
||||
3d/compare-eax-and 0/imm32
|
||||
# . if (eax != false) break
|
||||
3d/compare-eax-and 0/imm32/false
|
||||
# . restore result now that ZF is set
|
||||
58/pop-to-eax
|
||||
75/jump-if-not-equal $num-bytes:end/disp8
|
||||
|
|
BIN
apps/tests
BIN
apps/tests
Binary file not shown.
|
@ -43,8 +43,8 @@ Entry: # run tests if necessary, convert stdin if not
|
|||
e8/call kernel-string-equal?/disp32
|
||||
# . . discard args
|
||||
81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp
|
||||
# . if (eax == 0) goto run-main
|
||||
3d/compare-eax-and 0/imm32
|
||||
# . if (eax == false) goto run-main
|
||||
3d/compare-eax-and 0/imm32/false
|
||||
74/jump-if-equal $subx-tests-main:interactive/disp8
|
||||
# run-tests()
|
||||
e8/call run-tests/disp32
|
||||
|
@ -101,13 +101,13 @@ subx-gen-run-tests: # in : (address buffered-file), out : (address buffered-fil
|
|||
52/push-edx
|
||||
53/push-ebx
|
||||
57/push-edi
|
||||
# var line/ecx : (address stream byte) = stream(512)
|
||||
# var line/ecx : (ref stream byte 512)
|
||||
81 5/subop/subtract 3/mod/direct 4/rm32/esp . . . . . 0x200/imm32 # subtract from esp
|
||||
68/push 0x200/imm32/length
|
||||
68/push 0/imm32/read
|
||||
68/push 0/imm32/write
|
||||
89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx
|
||||
# var word-slice/edx = {0, 0}
|
||||
# var word-slice/edx : (ref slice)
|
||||
68/push 0/imm32/end
|
||||
68/push 0/imm32/start
|
||||
89/copy 3/mod/direct 2/rm32/edx . . . 4/r32/esp . . # copy esp to edx
|
||||
|
@ -178,8 +178,8 @@ $subx-gen-run-tests:check-for-label:
|
|||
e8/call is-label?/disp32
|
||||
# . . discard args
|
||||
81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp
|
||||
# . if (eax == 0) continue
|
||||
3d/compare-eax-and 0/imm32
|
||||
# . if (eax == false) continue
|
||||
3d/compare-eax-and 0/imm32/false
|
||||
74/jump-if-equal $subx-gen-run-tests:continue/disp8
|
||||
$subx-gen-run-tests:check-label-prefix:
|
||||
# strip trailing ':' from word-slice
|
||||
|
@ -192,8 +192,8 @@ $subx-gen-run-tests:check-label-prefix:
|
|||
e8/call slice-starts-with?/disp32
|
||||
# . . discard args
|
||||
81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp
|
||||
# . if (eax == 0) break
|
||||
3d/compare-eax-and 0/imm32
|
||||
# . if (eax == false) break
|
||||
3d/compare-eax-and 0/imm32/false
|
||||
74/jump-if-equal $subx-gen-run-tests:continue/disp8
|
||||
$subx-gen-run-tests:call-test-function:
|
||||
# tests-found? = true
|
||||
|
@ -242,7 +242,7 @@ $subx-gen-run-tests:continue:
|
|||
e9/jump $subx-gen-run-tests:loop/disp32
|
||||
$subx-gen-run-tests:break:
|
||||
# if (!tests-found?) goto end
|
||||
81 7/subop/compare 3/mod/direct 3/rm32/ebx . . . . . 0/imm32 # compare ebx
|
||||
81 7/subop/compare 3/mod/direct 3/rm32/ebx . . . . . 0/imm32/false # compare ebx
|
||||
74/jump-if-equal $subx-gen-run-tests:end/disp8
|
||||
# write(new-code-segment, " c3/return\n")
|
||||
# . . push args
|
||||
|
|
Loading…
Reference in New Issue