This commit is contained in:
Kartik Agaram 2020-01-27 00:36:44 -08:00
parent 1a65c3af0f
commit 71eb22a5bf
64 changed files with 891 additions and 891 deletions

View File

@ -11,7 +11,7 @@ Entry: # just exit; can't test _write just yet
b8/copy-to-eax 1/imm32/exit
cd/syscall 0x80/imm8
_write: # fd : int, s : (addr array byte)
_write: # fd: int, s: (addr array byte)
# . prologue
55/push-ebp
89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp
@ -21,12 +21,12 @@ _write: # fd : int, s : (addr array byte)
52/push-edx
53/push-ebx
# syscall(write, fd, (data) s+4, (size) *s)
# . fd : ebx
# . ebx = fd
8b/copy 1/mod/*+disp8 5/rm32/ebp . . . 3/r32/ebx 8/disp8 . # copy *(ebp+8) to ebx
# . data : ecx = s+4
# . var data/ecx: (addr byte) = s+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
# . size : edx = *s
# . var size/edx: int = *s
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
# . syscall

View File

@ -21,7 +21,7 @@ Entry: # manual test
cd/syscall 0x80/imm8
# print msg to stderr if a != b, otherwise print "."
check-ints-equal: # a : int, b : int, msg : (addr array byte)
check-ints-equal: # a: int, b: int, msg: (addr array byte)
# . prologue
55/push-ebp
89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp
@ -81,7 +81,7 @@ $check-ints-equal:end:
# length-prefixed string containing just a single newline
# convenient to have when printing messages and so on
Newline: # (array byte)
# size : int
# size: int
1/imm32
# data
0a/newline
@ -92,14 +92,14 @@ Num-test-failures: # int
# length-prefixed string containing just a single space
Space: # (array byte)
# size : int
# size: int
1/imm32
# data
20/space
# length-prefixed string containing just a single slash
Slash: # (array byte)
# size : int
# size: int
1/imm32
# data
2f/slash

View File

@ -30,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 : (addr kernel-string), benchmark : (addr array byte) -> eax : boolean
kernel-string-equal?: # s: (addr kernel-string), benchmark: (addr array byte) -> eax: boolean
# pseudocode:
# n = benchmark->length
# s1 = s
@ -61,19 +61,19 @@ kernel-string-equal?: # s : (addr kernel-string), benchmark : (addr array byte)
53/push-ebx
56/push-esi
57/push-edi
# var s1/edi : (addr byte) = s
# var s1/edi: (addr byte) = s
8b/copy 1/mod/*+disp8 5/rm32/ebp . . . 7/r32/edi 8/disp8 . # copy *(ebp+8) to edi
# var n/edx : int = 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
# var s2/esi : (addr byte) = benchmark->data
# var s2/esi: (addr 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
# var i/ecx : int = 0
# var i/ecx: int = 0
b9/copy-to-ecx 0/imm32/exit
# var c1/eax : byte = 0
# var c1/eax: byte = 0
b8/copy-to-eax 0/imm32
# var c2/ebx : byte = 0
# var c2/ebx: byte = 0
bb/copy-to-ebx 0/imm32
$kernel-string-equal?:loop:
# if (i >= n) break

View File

@ -5,8 +5,8 @@
# Currently an allocation descriptor consists of just the bounds of the pool of
# available memory:
#
# curr : address
# end : address
# curr: address
# end: address
#
# This isn't enough information to reclaim individual allocations. We can't
# support arbitrary reclamation yet.
@ -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 : allocation-descriptor
# var ad/ecx: 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
# var eax : (addr _) = ad->curr
# var eax: (addr _) = 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 : allocation-descriptor
new-segment: # len: int, ad: (addr allocation-descriptor)
# . prologue
55/push-ebp
89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp
@ -55,9 +55,9 @@ new-segment: # len : int, ad : allocation-descriptor
# copy {eax, eax+len} to *ad
# . ebx = ad
8b/copy 1/mod/*+disp8 5/rm32/ebp . . . 3/r32/ebx 0xc/disp8 . # copy *(ebp+12) to ebx
# . *ebx = eax
# . ad->curr = eax
89/copy 0/mod/indirect 3/rm32/ebx . . . 0/r32/eax . . # copy eax to *ebx
# . *(ebx+4) = eax+len
# . ad->end = eax+len
03/add 1/mod/*+disp8 5/rm32/ebp . . . 0/r32/eax 8/disp8 . # add *(ebp+8) to eax
89/copy 1/mod/*+disp8 3/rm32/ebx . . . 0/r32/eax 4/disp8 . # copy eax to *(ebx+4)
$new-segment:end:

View File

@ -13,7 +13,7 @@ Entry: # run all tests
b8/copy-to-eax 1/imm32/exit
cd/syscall 0x80/imm8
string-equal?: # s : (addr array byte), benchmark : (addr array byte) -> eax : boolean
string-equal?: # s: (addr array byte), benchmark: (addr array byte) -> eax: boolean
# pseudocode:
# if (s->length != benchmark->length) return false
# currs = s->data
@ -51,15 +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-!= $string-equal?:false/disp8
# var currs/esi : (addr byte) = s->data
# var currs/esi: (addr byte) = s->data
81 0/subop/add 3/mod/direct 6/rm32/esi . . . . . 4/imm32 # add to esi
# var maxs/ecx : (addr byte) = &s->data[s->length]
# var maxs/ecx: (addr byte) = &s->data[s->length]
01/add 3/mod/direct 1/rm32/ecx . . . 6/r32/esi . . # add esi to ecx
# var currb/edi : (addr byte) = benchmark->data
# var currb/edi: (addr byte) = benchmark->data
81 0/subop/add 3/mod/direct 7/rm32/edi . . . . . 4/imm32 # add to edi
# var c1/eax : byte = 0
# var c1/eax: byte = 0
31/xor 3/mod/direct 0/rm32/eax . . . 0/r32/eax . . # clear eax
# var c2/edx : byte = 0
# 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
@ -176,13 +176,13 @@ test-compare-inequal-strings-equal-lengths:
c3/return
# helper for later tests
check-strings-equal: # s : (addr array byte), expected : (addr array byte), msg : (addr array byte)
check-strings-equal: # s: (addr array byte), expected: (addr array byte), msg: (addr array byte)
# . prologue
55/push-ebp
89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp
# . save registers
50/push-eax
# var eax : boolean = 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)

View File

@ -1,9 +1,9 @@
# streams: data structure for operating on arrays in a stateful manner
#
# 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
# write: int # index at which writes go
# read: int # index that we've read until
# data: (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 : (addr stream byte)
clear-stream: # f: (addr stream byte)
# . prologue
55/push-ebp
89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp
@ -23,15 +23,15 @@ clear-stream: # f : (addr stream byte)
51/push-ecx
# eax = f
8b/copy 1/mod/*+disp8 5/rm32/ebp . . 0/r32/eax 8/disp8 . # copy *(ebp+8) to eax
# var count/ecx : int = f->length
# var count/ecx: int = f->length
8b/copy 1/mod/*+disp8 0/rm32/eax . . . 1/r32/ecx 8/disp8 . # copy *(eax+8) to ecx
# var max/ecx : (addr byte) = &f->data[f->length]
# var max/ecx: (addr byte) = &f->data[f->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)
# var curr/eax : (addr byte) = f->data
# var curr/eax: (addr byte) = f->data
81 0/subop/add 3/mod/direct 0/rm32/eax . . . . . 0xc/imm32 # add to eax
$clear-stream:loop:
# if (curr >= max) break
@ -51,7 +51,7 @@ $clear-stream:end:
5d/pop-to-ebp
c3/return
rewind-stream: # f : (addr stream byte)
rewind-stream: # f: (addr stream byte)
# . prologue
55/push-ebp
89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp

View File

@ -1,9 +1,9 @@
# primitives for emitting traces to a 'trace' stream, and for tests to make assertions on its contents
#
# A trace stream looks like a regular stream:
# write : int # index at which writes go
# read : int # index that we've read until
# data : (array byte) # prefixed by length as usual
# write: int # index at which writes go
# read: int # index that we've read until
# data: (array byte) # prefixed by length as usual
# Usually the trace stream will be in a separate segment set aside for the purpose.
#
# primitives for operating on traces (arguments in quotes):
@ -45,7 +45,7 @@ _test-trace-stream: # (stream byte)
# Allocate a new segment for the trace stream, initialize its length, and save its address to Trace-stream.
# The Trace-stream segment will consist of variable-length lines separated by newlines (0x0a)
initialize-trace-stream: # n : int
initialize-trace-stream: # n: int
# . prologue
55/push-ebp
89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp
@ -83,7 +83,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 : (addr array byte)
trace: # line: (addr array byte)
# . prologue
55/push-ebp
89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp
@ -94,13 +94,13 @@ trace: # line : (addr array byte)
53/push-ebx
56/push-esi
57/push-edi
# var edi : (addr stream byte) = *Trace-stream
# var edi: (addr 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
# var ecx : int = t->write
# var ecx: int = t->write
8b/copy 0/mod/indirect 7/rm32/edi . . . 1/r32/ecx . . # copy *edi to ecx
# var edx : int = 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
@ -250,7 +250,7 @@ test-trace-empty-line:
# end
c3/return
check-trace-contains: # line : (addr string), msg : (addr string)
check-trace-contains: # line: (addr string), msg: (addr string)
# . prologue
55/push-ebp
89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp
@ -275,7 +275,7 @@ $check-trace-contains:end:
5d/pop-to-ebp
c3/return
check-trace-scans-to: # line : (addr string), msg : (addr string)
check-trace-scans-to: # line: (addr string), msg: (addr string)
# . prologue
55/push-ebp
89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp
@ -306,7 +306,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 : (addr array byte) -> result/eax : boolean
trace-scan: # line: (addr array byte) -> result/eax: boolean
# pseudocode:
# push Trace-stream->read
# while true:
@ -558,7 +558,7 @@ test-trace-scan-failure-leaves-read-index-untouched:
# . end
c3/return
next-line-matches?: # t : (addr stream byte), line : (addr array byte) -> result/eax : boolean
next-line-matches?: # t: (addr stream byte), line: (addr array byte) -> result/eax: boolean
# pseudocode:
# while true:
# if (currl >= maxl) break
@ -579,24 +579,24 @@ next-line-matches?: # t : (addr stream byte), line : (addr array byte) -> resul
57/push-edi
# edx = line
8b/copy 1/mod/*+disp8 5/rm32/ebp . . 2/r32/edx 0xc/disp8 . # copy *(ebp+12) to edx
# var currl/esi : (addr byte) = line->data
# var currl/esi: (addr 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
# var maxl/ecx : (addr byte) = &line->data[line->size]
# var maxl/ecx: (addr 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 = &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
# var ebx : (addr byte) = t->data
# var ebx: (addr byte) = t->data
8d/copy-address 1/mod/*+disp8 7/rm32/edi . . . 3/r32/ebx 0xc/disp8 . # copy edi+12 to ebx
# var maxt/edx : (addr byte) = &t->data[t->write]
# var maxt/edx: (addr byte) = &t->data[t->write]
# . eax = t->write
8b/copy 0/mod/indirect 7/rm32/edi . . 0/r32/eax . . # copy *edi to 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
# var currt/edi : (addr byte) = &t->data[t->read]
# var currt/edi: (addr 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 = &t->data[t->read]
@ -613,9 +613,9 @@ $next-line-matches?:loop:
# 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 : byte = *currt
# . eax: byte = *currt
8a/copy-byte 0/mod/indirect 7/rm32/edi . . 0/r32/eax . . # copy *edi to eax
# . ebx : byte = *currl
# . 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
@ -630,7 +630,7 @@ $next-line-matches?:loop:
$next-line-matches?:break:
# return *currt == '\n'
31/xor 3/mod/direct 0/rm32/eax . . . 0/r32/eax . . # clear eax
# . eax : byte = *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
@ -734,7 +734,7 @@ test-next-line-matches?-match:
c3/return
# move t->read to _after_ next newline
skip-next-line: # t : (addr stream byte)
skip-next-line: # t: (addr stream byte)
# pseudocode:
# max = &t->data[t->write]
# i = t->read
@ -760,13 +760,13 @@ skip-next-line: # t : (addr stream byte)
8d/copy-address 1/mod/*+disp8 1/rm32/ecx . . . 2/r32/edx 0xc/disp8 . # copy ecx+12 to edx
# eax = t->write
8b/copy 0/mod/indirect 1/rm32/ecx . . . 0/r32/eax . . # copy *ecx to eax
# var max/ebx : (addr byte) = &t->data[t->write]
# var max/ebx: (addr 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->read
8b/copy 1/mod/*+disp8 1/rm32/ecx . . . 0/r32/eax 4/disp8 . # copy *(ecx+4) to edx
# var curr/ecx : (addr byte) = &t->data[t->read]
# var curr/ecx: (addr 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
# var i/edx : int = t->read
# 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 >= max) break
@ -862,7 +862,7 @@ $clear-trace-stream:end:
# - helpers
# 3-argument variant of _append
_append-3: # out : (addr byte), outend : (addr byte), s : (addr array byte) -> num_bytes_appended/eax
_append-3: # out: (addr byte), outend: (addr byte), s: (addr 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
@ -894,7 +894,7 @@ $_append-3:end:
c3/return
# 4-argument variant of _append
_append-4: # out : (addr byte), outend : (addr byte), in : (addr byte), inend : (addr byte) -> num_bytes_appended/eax : int
_append-4: # out: (addr byte), outend: (addr byte), in: (addr byte), inend: (addr 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

View File

@ -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 (addr stream byte), s : (addr array byte)
write: # f: fd or (addr stream byte), s: (addr array byte)
# . prologue
55/push-ebp
89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp

View File

@ -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 : (addr stream byte), s : (addr array byte) -> eax : boolean
stream-data-equal?: # f: (addr stream byte), s: (addr array byte) -> eax: boolean
# . prologue
55/push-ebp
89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp
@ -19,9 +19,9 @@ stream-data-equal?: # f : (addr stream byte), s : (addr array byte) -> eax : bo
8b/copy 1/mod/*+disp8 5/rm32/ebp . . . 6/r32/esi 8/disp8 . # copy *(ebp+8) to esi
# eax = f->write
8b/copy 0/mod/indirect 6/rm32/esi . . . 0/r32/eax . . # copy *esi to eax
# var maxf/edx : (addr byte) = &f->data[f->write]
# var maxf/edx: (addr byte) = &f->data[f->write]
8d/copy-address 1/mod/*+disp8 4/rm32/sib 6/base/esi 0/index/eax . 2/r32/edx 0xc/disp8 . # copy esi+eax+12 to edx
# var currf/esi : (addr byte) = f->data
# var currf/esi: (addr byte) = f->data
81 0/subop/add 3/mod/direct 6/rm32/esi . . . . . 0xc/imm32 # add to esi
# edi = s
8b/copy 1/mod/*+disp8 5/rm32/ebp . . . 7/r32/edi 0xc/disp8 . # copy *(ebp+12) to edi
@ -29,11 +29,11 @@ $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-!= $stream-data-equal?:false/disp8
# var currs/edi : (addr byte) = s->data
# var currs/edi: (addr byte) = s->data
81 0/subop/add 3/mod/direct 7/rm32/edi . . . . . 4/imm32 # add to edi
# var eax : byte = 0
# var eax: byte = 0
31/xor 3/mod/direct 0/rm32/eax . . . 0/r32/eax . . # clear eax
# var ecx : byte = 0
# 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
@ -191,7 +191,7 @@ test-stream-data-equal-length-check:
c3/return
# helper for later tests
check-stream-equal: # f : (addr stream byte), s : (addr array byte), msg : (addr array byte)
check-stream-equal: # f: (addr stream byte), s: (addr array byte), msg: (addr array byte)
# . prologue
55/push-ebp
89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp
@ -227,10 +227,10 @@ $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 : (addr stream byte), s : (addr array byte) -> eax : boolean
next-stream-line-equal?: # f: (addr stream byte), s: (addr array byte) -> eax: boolean
# pseudocode:
# currf = f->read # bound: f->write
# currs = 0 # bound : s->length
# currs = 0 # bound: s->length
# while true
# if currf >= f->write
# return currs >= s->length
@ -244,7 +244,7 @@ next-stream-line-equal?: # f : (addr stream byte), s : (addr array byte) -> eax
#
# collapsing the two branches that can return true:
# currf = f->read # bound: f->write
# currs = 0 # bound : s->length
# currs = 0 # bound: s->length
# while true
# if (currf >= f->write) break
# if (f[currf] == '\n') break
@ -274,15 +274,15 @@ next-stream-line-equal?: # f : (addr stream byte), s : (addr array byte) -> eax
57/push-edi
# esi = f
8b/copy 1/mod/*+disp8 5/rm32/ebp . . . 6/r32/esi 8/disp8 . # copy *(ebp+8) to esi
# var currf/ecx : int = f->read
# var currf/ecx: int = f->read
8b/copy 1/mod/*+disp8 6/rm32/esi . . . 1/r32/ecx 4/disp8 . # copy *(esi+4) to ecx
# edi = s
8b/copy 1/mod/*+disp8 5/rm32/ebp . . . 7/r32/edi 0xc/disp8 . # copy *(ebp+12) to edi
# var currs/edx : int = 0
# var currs/edx: int = 0
31/xor 3/mod/direct 2/rm32/edx . . . 2/r32/edx . . # clear edx
# var c1/eax : byte = 0
# var c1/eax: byte = 0
31/xor 3/mod/direct 0/rm32/eax . . . 0/r32/eax . . # clear eax
# var c2/ebx : byte = 0
# 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

View File

@ -16,8 +16,8 @@
# input target with an output status parameter into a type called 'exit-descriptor'.
#
# So the exit-descriptor looks like this:
# target : address # return address for 'stop' to unwind to
# value : int # exit status stop was called with
# target: address # return address for 'stop' to unwind to
# value: int # exit status stop was called with
#
# 'stop' thus takes two parameters: an exit-descriptor and the exit status.
#
@ -41,7 +41,7 @@
# the stack.
# Ugly that we need to know the size of args. Don't allocate variables between
# tailor-exit-descriptor and the call it's for.
tailor-exit-descriptor: # ed : (addr exit-descriptor), nbytes : int
tailor-exit-descriptor: # ed: (addr exit-descriptor), nbytes: int
# . prologue
55/push-ebp
89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp
@ -89,7 +89,7 @@ $tailor-exit-descriptor:end:
5d/pop-to-ebp
c3/return
stop: # ed : (addr exit-descriptor), value : int
stop: # ed: (addr exit-descriptor), value: int
# no prologue; one way or another, we're going to clobber registers
# eax = ed
8b/copy 1/mod/*+disp8 4/rm32/sib 4/base/esp 4/index/none . 0/r32/eax 4/disp8 . # copy *(esp+4) to eax
@ -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 : exit-descriptor
# var ed/eax: 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
@ -161,7 +161,7 @@ test-stop-skips-returns-on-exit:
5d/pop-to-ebp
c3/return
_test-stop-1: # ed : (addr exit-descriptor)
_test-stop-1: # ed: (addr exit-descriptor)
# . prologue
55/push-ebp
89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp
@ -188,7 +188,7 @@ $_test-stop-1:dead-end:
5d/pop-to-ebp
c3/return
_test-stop-2: # ed : (addr exit-descriptor)
_test-stop-2: # ed: (addr exit-descriptor)
# . prologue
55/push-ebp
89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp

View File

@ -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 (addr stream byte), s : (addr stream byte) -> num-bytes-read/eax : int
read: # f: fd or (addr stream byte), s: (addr 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
@ -110,7 +110,7 @@ $read:end:
# '_buffer' is like '_append', but silently stops instead of aborting when it runs out of space
# 3-argument variant of _buffer
_buffer-3: # out : address, outend : address, s : (array byte) -> num_bytes_buffered/eax
_buffer-3: # out: address, outend: address, s: (array byte) -> num_bytes_buffered/eax
# . prologue
55/push-ebp
89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp
@ -142,7 +142,7 @@ $_buffer-3:end:
c3/return
# 4-argument variant of _buffer
_buffer-4: # out : address, outend : address, in : address, inend : address -> num_bytes_buffered/eax
_buffer-4: # out: address, outend: address, in: address, inend: address -> num_bytes_buffered/eax
# . prologue
55/push-ebp
89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp
@ -195,7 +195,7 @@ $_buffer-4:end:
# 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 : (addr stream byte) -> num-bytes-read/eax : int
_read: # fd: int, s: (addr 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
@ -211,11 +211,11 @@ _read: # fd : int, s : (addr stream byte) -> num-bytes-read/eax : int
# edx = s->length
8b/copy 1/mod/*+disp8 6/rm32/esi . . . 2/r32/edx 8/disp8 . # copy *(esi+8) to edx
# syscall(read, fd, &s->data[s->write], s->length - s->write)
# . . fd : ebx
# . . fd: ebx
8b/copy 1/mod/*+disp8 5/rm32/ebp . . . 3/r32/ebx 8/disp8 . # copy *(ebp+8) to ebx
# . . data : ecx = &s->data[s->write]
# . . data: ecx = &s->data[s->write]
8d/copy-address 1/mod/*+disp8 4/rm32/sib 6/base/esi 0/index/eax . 1/r32/ecx 0xc/disp8 . # copy esi+eax+12 to ecx
# . . size : edx = s->length - s->write
# . . size: edx = s->length - s->write
29/subtract 3/mod/direct 2/rm32/edx . . . 0/r32/eax . . # subtract eax from edx
# . . syscall
b8/copy-to-eax 3/imm32/read

View File

@ -35,7 +35,7 @@ $Stdin->buffer:
# return next byte value in eax, with top 3 bytes cleared.
# On reaching end of file, return 0xffffffff (Eof).
read-byte-buffered: # f : (addr buffered-file) -> byte-or-Eof/eax
read-byte-buffered: # f: (addr buffered-file) -> byte-or-Eof/eax
# . prologue
55/push-ebp
89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp

View File

@ -15,7 +15,7 @@
#? b8/copy-to-eax 1/imm32/exit
#? cd/syscall 0x80/imm8
write-stream: # f : fd or (addr stream byte), s : (addr stream byte)
write-stream: # f: fd or (addr stream byte), s: (addr 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 : (addr stream byte)
_write-stream: # fd: int, s: (addr stream byte)
# . prologue
55/push-ebp
89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp
@ -93,11 +93,11 @@ _write-stream: # fd : int, s : (addr stream byte)
# edx = s->write
8b/copy 0/mod/indirect 6/rm32/esi . . . 2/r32/edx . . # copy *esi to edx
# syscall(write, fd, &s->data[s->read], s->write - s->read)
# . . fd : ebx
# . . fd: ebx
8b/copy 1/mod/*+disp8 5/rm32/ebp . . . 3/r32/ebx 8/disp8 . # copy *(ebp+8) to ebx
# . . data : ecx = &s->data[s->read]
# . . data: ecx = &s->data[s->read]
8d/copy-address 1/mod/*+disp8 4/rm32/sib 6/base/esi 7/index/edi . 1/r32/ecx 0xc/disp8 . # copy esi+edi+12 to ecx
# . . size : edx = s->write - s->read
# . . size: edx = s->write - s->read
29/subtract 3/mod/direct 2/rm32/edx . . . 7/r32/edi . . # subtract edi from edx
# . . syscall
b8/copy-to-eax 4/imm32/write

View File

@ -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 : (addr exit-descriptor), out : fd or (addr stream byte), msg : (addr array byte)
error: # ed: (addr exit-descriptor), out: fd or (addr stream byte), msg: (addr array byte)
# . prologue
55/push-ebp
89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp

View File

@ -30,7 +30,7 @@ $Stdout->buffer:
# . 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 lower byte of 'n' to 'f'.
write-byte-buffered: # f : (addr buffered-file), n : int
write-byte-buffered: # f: (addr buffered-file), n: int
# . prologue
55/push-ebp
89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp
@ -78,7 +78,7 @@ $write-byte-buffered:end:
5d/pop-to-ebp
c3/return
flush: # f : (addr buffered-file)
flush: # f: (addr buffered-file)
# . prologue
55/push-ebp
89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp
@ -205,7 +205,7 @@ test-write-byte-buffered-multiple-flushes:
# - variant without buffering
# Write lower byte of 'n' to 'f'.
append-byte: # f : (addr stream byte), n : int
append-byte: # f: (addr stream byte), n: int
# . prologue
55/push-ebp
89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp

View File

@ -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-buffered: # f : (addr buffered-file), msg : (addr array byte)
write-buffered: # f: (addr buffered-file), msg: (addr array byte)
# pseudocode:
# in = msg->data
# inend = &msg->data[msg->length]
@ -38,9 +38,9 @@ write-buffered: # f : (addr buffered-file), msg : (addr 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
# var in/esi : (addr byte) = msg->data
# var in/esi: (addr byte) = msg->data
8d/copy-address 1/mod/*+disp8 0/rm32/eax . . . 6/r32/esi 4/disp8 . # copy eax+4 to esi
# var inend/ecx : (addr byte) = &msg->data[msg->length]
# var inend/ecx: (addr 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

View File

@ -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
# 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
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
@ -18,7 +18,7 @@ $to-hex-char:else:
05/add-to-eax 0x57/imm32/a-10
c3/return
append-byte-hex: # f : (addr stream byte), n : int
append-byte-hex: # f: (addr stream byte), n: int
# . prologue
55/push-ebp
89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp
@ -90,7 +90,7 @@ test-append-byte-hex:
c3/return
# print the hex representation for the lowest byte of a number
print-byte-buffered: # f : (addr buffered-file), n : int
print-byte-buffered: # f: (addr buffered-file), n: int
# . prologue
55/push-ebp
89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp
@ -175,7 +175,7 @@ test-print-byte-buffered:
# . end
c3/return
print-int32: # f : (addr stream byte), n : int
print-int32: # f: (addr stream byte), n: int
# pseudocode:
# write(f, "0x")
# ecx = 28
@ -263,7 +263,7 @@ test-print-int32:
# . end
c3/return
print-int32-buffered: # f : (addr buffered-file), n : int
print-int32-buffered: # f: (addr buffered-file), n: int
# pseudocode:
# write-buffered(f, "0x")
# ecx = 28

View File

@ -6,7 +6,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
is-hex-int?: # in : (addr slice) -> eax : boolean
is-hex-int?: # in: (addr slice) -> eax: boolean
# . prologue
55/push-ebp
89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp
@ -18,7 +18,7 @@ is-hex-int?: # in : (addr 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
# var curr/ecx : (addr byte) = s->start
# var curr/ecx: (addr 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-addr>= $is-hex-int?:true/disp8
# var eax : boolean = 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 : slice = {eax, ecx}
# var slice/ecx: 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 : slice = {eax, ecx}
# var slice/ecx: 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 : slice = {eax, ecx}
# var slice/ecx: 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 : slice = {eax, ecx}
# var slice/ecx: 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 : slice = ""
# var slice/ecx: 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 : slice = {eax, ecx}
# var slice/ecx: 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 : slice = {eax, ecx}
# var slice/ecx: 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 : slice = {eax, ecx}
# var slice/ecx: 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 : (addr slice) -> result/eax : int
parse-hex-int: # in: (addr slice) -> result/eax: int
# . prologue
55/push-ebp
89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp
@ -360,15 +360,15 @@ parse-hex-int: # in : (addr slice) -> result/eax : int
52/push-edx
53/push-ebx
56/push-esi
# var result/ebx : int = 0
# var result/ebx: int = 0
31/xor 3/mod/direct 3/rm32/ebx . . . 3/r32/ebx . . # clear ebx
# ecx = in
8b/copy 1/mod/*+disp8 5/rm32/ebp . . . 1/r32/ecx 8/disp8 . # copy *(ebp+8) to ecx
# edx = in->end
8b/copy 1/mod/*+disp8 1/rm32/ecx . . . 2/r32/edx 4/disp8 . # copy *(ecx+4) to edx
# var curr/ecx : (addr byte) = in->start
# var curr/ecx: (addr byte) = in->start
8b/copy 0/mod/indirect 1/rm32/ecx . . . 1/r32/ecx . . # copy *ecx to ecx
# var negate?/esi : boolean = 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 == '-') ++curr, negate = true
@ -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-addr>= $parse-hex-int:negate/disp8
# var eax : int = 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
@ -442,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 : slice = {eax, ecx}
# var slice/ecx: slice = {eax, ecx}
51/push-ecx
50/push-eax
89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx
@ -476,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 : slice = {eax, ecx}
# var slice/ecx: slice = {eax, ecx}
51/push-ecx
50/push-eax
89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx
@ -510,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 : slice = {eax, ecx}
# var slice/ecx: slice = {eax, ecx}
51/push-ecx
50/push-eax
89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx
@ -544,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 : slice = {eax, ecx}
# var slice/ecx: slice = {eax, ecx}
51/push-ecx
50/push-eax
89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx
@ -578,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 : slice = {eax, ecx}
# var slice/ecx: slice = {eax, ecx}
51/push-ecx
50/push-eax
89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx
@ -612,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 : slice = {eax, ecx}
# var slice/ecx: slice = {eax, ecx}
51/push-ecx
50/push-eax
89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx
@ -637,7 +637,7 @@ test-parse-hex-int-negative:
5d/pop-to-ebp
c3/return
is-hex-digit?: # c : byte -> eax : boolean
is-hex-digit?: # c: byte -> eax: boolean
# . prologue
55/push-ebp
89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp
@ -800,7 +800,7 @@ test-hex-above-f:
81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32 # add to esp
c3/return
from-hex-char: # in/eax : byte -> out/eax : nibble
from-hex-char: # in/eax: byte -> out/eax: nibble
$from-hex-char:check0:
# if (eax < '0') goto abort
3d/compare-eax-with 0x30/imm32/0

View File

@ -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: 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()
@ -24,7 +24,7 @@
#? cd/syscall 0x80/imm8
# write(out, "Error: "+msg+": "+byte) then stop(ed, 1)
error-byte: # ed : (addr exit-descriptor), out : (addr buffered-file), msg : (addr array byte), n : byte
error-byte: # ed: (addr exit-descriptor), out: (addr buffered-file), msg: (addr array byte), n: byte
# . prologue
55/push-ebp
89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp

View File

@ -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 : (addr allocation-descriptor), n : int -> address-or-null/eax : (addr _)
allocate: # ad: (addr allocation-descriptor), n: int -> address-or-null/eax: (addr _)
# . 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 : allocation-descriptor = {11, 15}
# var ad/ecx: 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
# var eax : (handle byte) = 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 : allocation-descriptor = {11, 15}
# var ad/ecx: 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
# var eax : (handle byte) = 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 : (addr allocation-descriptor), n : int -> new-ad : (handle allocation-descriptor)
allocate-region: # ad: (addr 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

View File

@ -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 : (addr allocation-descriptor), length : int, elemsize : int -> address/eax : (handle stream _)
new-stream: # ad: (addr 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
# var n/eax : int = 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 : (addr allocation-descriptor), length : int, elemsize : int -
89/copy 3/mod/direct 2/rm32/edx . . . 0/r32/eax . . # copy eax to edx
# . eax += 12
05/add-to-eax 0xc/imm32
# var eax : (handle stream _) = 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 : allocation-descriptor
# var heap/ecx: 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
# var eax : (handle stream byte) = 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

View File

@ -6,7 +6,7 @@
# 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-buffered: # f : (addr buffered-file), s : (addr stream byte)
read-line-buffered: # f: (addr buffered-file), s: (addr stream byte)
# pseudocode:
# while true
# if (s->write >= s->length) abort
@ -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 : (addr stream byte), s : (addr stream byte)
read-line: # f: (addr stream byte), s: (addr stream byte)
# pseudocode:
# while true
# if (s->write >= s->length) abort

View File

@ -6,7 +6,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
slice-empty?: # s : (addr slice) -> eax : boolean
slice-empty?: # s: (addr slice) -> eax: boolean
# . prologue
55/push-ebp
89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp
@ -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 : slice = {34, 34}
# var slice/ecx: 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 : slice = {32, 34}
# var slice/ecx: slice = {32, 34}
68/push 34/imm32/end
68/push 32/imm32/start
89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx
@ -92,7 +92,7 @@ test-slice-empty-if-start-greater-than-end:
# . prologue
55/push-ebp
89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp
# var slice/ecx : slice = {34, 32}
# var slice/ecx: slice = {34, 32}
68/push 32/imm32/end
68/push 34/imm32/start
89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx
@ -117,7 +117,7 @@ test-slice-empty-if-start-greater-than-end:
5d/pop-to-ebp
c3/return
slice-equal?: # s : (addr slice), p : (addr array byte) -> eax : boolean
slice-equal?: # s: (addr slice), p: (addr array byte) -> eax: boolean
# pseudocode:
# if (p == 0) return (s == 0)
# currs = s->start
@ -147,11 +147,11 @@ slice-equal?: # s : (addr slice), p : (addr array byte) -> 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
# var currs/edx : (addr byte) = s->start
# var currs/edx: (addr byte) = s->start
8b/copy 0/mod/indirect 6/rm32/esi . . . 2/r32/edx . . # copy *esi to edx
# var maxs/esi : (addr byte) = s->end
# var maxs/esi: (addr byte) = s->end
8b/copy 1/mod/*+disp8 6/rm32/esi . . . 6/r32/esi 4/disp8 . # copy *(esi+4) to esi
# var slen/eax : int = 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
@ -168,11 +168,11 @@ $slice-equal?:nonnull-string:
# if (slen != p->length) return false
39/compare 0/mod/indirect 3/rm32/ebx . . . 0/r32/eax . . # compare *ebx and eax
75/jump-if-!= $slice-equal?:false/disp8
# var currp/ebx : (addr byte) = p->data
# var currp/ebx: (addr byte) = p->data
81 0/subop/add 3/mod/direct 3/rm32/ebx . . . . . 4/imm32 # add to ebx
# var c1/eax : byte = 0
# var c1/eax: byte = 0
31/xor 3/mod/direct 0/rm32/eax . . . 0/r32/eax . . # clear eax
# var c2/ecx : byte = 0
# 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
@ -216,7 +216,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 : slice = {eax, ecx}
# var slice/ecx: slice = {eax, ecx}
51/push-ecx
50/push-eax
89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx
@ -252,7 +252,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 : slice = {eax, ecx}
# var slice/ecx: slice = {eax, ecx}
51/push-ecx
50/push-eax
89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx
@ -288,7 +288,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 : slice = {eax, ecx}
# var slice/ecx: slice = {eax, ecx}
51/push-ecx
50/push-eax
89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx
@ -324,7 +324,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 : slice = {eax, ecx}
# var slice/ecx: slice = {eax, ecx}
51/push-ecx
50/push-eax
89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx
@ -355,7 +355,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 : slice
# var slice/ecx: 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
@ -391,7 +391,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 : slice = {eax, ecx}
# var slice/ecx: slice = {eax, ecx}
51/push-ecx
50/push-eax
89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx
@ -422,7 +422,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 : slice
# var slice/ecx: 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
@ -458,7 +458,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 : slice = {eax, ecx}
# var slice/ecx: slice = {eax, ecx}
51/push-ecx
50/push-eax
89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx
@ -484,7 +484,7 @@ test-slice-equal-with-null:
5d/pop-to-ebp
c3/return
slice-starts-with?: # s : (addr slice), head : (addr array byte) -> eax : boolean
slice-starts-with?: # s: (addr slice), head: (addr array byte) -> eax: boolean
# pseudocode
# lenh = head->length
# if (lenh > s->end - s->start) return false
@ -517,25 +517,25 @@ slice-starts-with?: # s : (addr slice), head : (addr array byte) -> eax : boole
57/push-edi
# esi = s
8b/copy 1/mod/*+disp8 5/rm32/ebp . . . 6/r32/esi 8/disp8 . # copy *(ebp+8) to esi
# var lens/ecx : int = 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
# var lenh/edx : int = 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 > lens) return false
39/compare 3/mod/direct 2/rm32/edx . . . 1/r32/ecx . . # compare edx with ecx
7f/jump-if-> $slice-starts-with?:false/disp8
# var currs/esi : (addr byte) = s->start
# var currs/esi: (addr byte) = s->start
8b/subtract 0/mod/indirect 6/rm32/esi . . . 6/r32/esi . . # copy *esi to esi
# var currh/edi : (addr byte) = head->data
# var currh/edi: (addr byte) = head->data
81 0/subop/add 3/mod/direct 7/rm32/edi . . . . . 4/imm32 # add to edi
# var i/ecx : int = 0
# var i/ecx: int = 0
31/xor 3/mod/direct 1/rm32/ecx . . . 1/r32/ecx . . # clear ecx
# var c1/eax : byte = 0
# var c1/eax: byte = 0
31/xor 3/mod/direct 0/rm32/eax . . . 0/r32/eax . . # clear eax
# var c2/ebx : byte = 0
# 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
@ -582,7 +582,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 : slice = {eax, ecx}
# var slice/ecx: slice = {eax, ecx}
51/push-ecx
50/push-eax
89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx
@ -618,7 +618,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 : slice = {eax, ecx}
# var slice/ecx: slice = {eax, ecx}
51/push-ecx
50/push-eax
89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx
@ -654,7 +654,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 : slice = {eax, ecx}
# var slice/ecx: slice = {eax, ecx}
51/push-ecx
50/push-eax
89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx
@ -690,7 +690,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 : slice = {eax, ecx}
# var slice/ecx: slice = {eax, ecx}
51/push-ecx
50/push-eax
89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx
@ -726,7 +726,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 : slice = {eax, ecx}
# var slice/ecx: slice = {eax, ecx}
51/push-ecx
50/push-eax
89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx
@ -762,7 +762,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 : slice = {eax, ecx}
# var slice/ecx: slice = {eax, ecx}
51/push-ecx
50/push-eax
89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx
@ -790,7 +790,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 : (addr stream byte), s : (addr slice)
write-slice: # out: (addr stream byte), s: (addr slice)
# . prologue
55/push-ebp
89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp
@ -803,9 +803,9 @@ write-slice: # out : (addr stream byte), s : (addr slice)
57/push-edi
# esi = s
8b/copy 1/mod/*+disp8 5/rm32/ebp . . . 6/r32/esi 0xc/disp8 . # copy *(ebp+12) to esi
# var curr/ecx : (addr byte) = s->start
# var curr/ecx: (addr byte) = s->start
8b/copy 0/mod/indirect 6/rm32/esi . . . 1/r32/ecx . . # copy *esi to ecx
# var max/esi : (addr byte) = s->end
# var max/esi: (addr 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
@ -879,7 +879,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 : slice = {eax, ecx}
# var slice/ecx: slice = {eax, ecx}
51/push-ecx
50/push-eax
89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx
@ -906,7 +906,7 @@ test-write-slice:
c3/return
# write a slice to a buffered-file
write-slice-buffered: # out : (addr buffered-file), s : (addr slice)
write-slice-buffered: # out: (addr buffered-file), s: (addr slice)
# . prologue
55/push-ebp
89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp
@ -919,9 +919,9 @@ write-slice-buffered: # out : (addr buffered-file), s : (addr slice)
57/push-edi
# esi = s
8b/copy 1/mod/*+disp8 5/rm32/ebp . . . 6/r32/esi 0xc/disp8 . # copy *(ebp+12) to esi
# var curr/ecx : (addr byte) = s->start
# var curr/ecx: (addr byte) = s->start
8b/copy 0/mod/indirect 6/rm32/esi . . . 1/r32/ecx . . # copy *esi to ecx
# var max/esi : (addr byte) = s->end
# var max/esi: (addr 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
@ -1007,7 +1007,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 : slice = {eax, ecx}
# var slice/ecx: slice = {eax, ecx}
51/push-ecx
50/push-eax
89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx
@ -1041,7 +1041,7 @@ test-write-slice-buffered:
c3/return
# copy a slice into a new (dynamically allocated) string
slice-to-string: # ad : (addr allocation-descriptor), in : (addr slice) -> out/eax : (addr array byte)
slice-to-string: # ad: (addr allocation-descriptor), in: (addr slice) -> out/eax: (addr array byte)
# . prologue
55/push-ebp
89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp
@ -1052,15 +1052,15 @@ slice-to-string: # ad : (addr allocation-descriptor), in : (addr slice) -> out/
56/push-esi
# esi = in
8b/copy 1/mod/*+disp8 5/rm32/ebp . . . 6/r32/esi 0xc/disp8 . # copy *(ebp+12) to esi
# var curr/edx : (addr byte) = in->start
# var curr/edx: (addr byte) = in->start
8b/copy 0/mod/indirect 6/rm32/esi . . . 2/r32/edx . . # copy *esi to edx
# var max/ebx : (addr byte) = in->end
# var max/ebx: (addr byte) = in->end
8b/copy 1/mod/*+disp8 6/rm32/esi . . . 3/r32/ebx 4/disp8 . # copy *(esi+4) to ebx
# var size/ecx : int = max - curr + 4 # total size of output string (including the initial length)
# var size/ecx: int = max - curr + 4 # total size of output string (including the initial 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
# var out/eax : (handle array byte) = 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)
@ -1123,7 +1123,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 : allocation-descriptor
# var heap/edx: 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
@ -1140,7 +1140,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 : slice = {eax, ecx}
# var slice/ecx: slice = {eax, ecx}
51/push-ecx
50/push-eax
89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx

View File

@ -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 : (addr stream byte), delimiter : byte, out : (addr slice)
next-token: # in: (addr stream byte), delimiter: byte, out: (addr slice)
# . prologue
55/push-ebp
89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp
@ -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 : slice
# var slice/ecx: 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 : slice
# var slice/ecx: 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
@ -160,7 +160,7 @@ test-next-token-Eof:
# extract the next run of characters that are different from a given 'delimiter' (skipping multiple delimiters if necessary)
# on reaching end of file, return an empty interval
next-token-from-slice: # start : (addr byte), end : (addr byte), delimiter : byte, out : (addr slice)
next-token-from-slice: # start: (addr byte), end: (addr byte), delimiter: byte, out: (addr slice)
# . prologue
55/push-ebp
89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp
@ -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 : slice
# var out/edi: slice
68/push 0/imm32/end
68/push 0/imm32/start
89/copy 3/mod/direct 7/rm32/edi . . . 4/r32/esp . . # copy esp to edi
@ -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 : slice
# var out/edi: slice
68/push 0/imm32/end
68/push 0/imm32/start
89/copy 3/mod/direct 7/rm32/edi . . . 4/r32/esp . . # copy esp to edi
@ -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 : slice
# var out/edi: slice
68/push 0/imm32/end
68/push 0/imm32/start
89/copy 3/mod/direct 7/rm32/edi . . . 4/r32/esp . . # copy esp to edi
@ -338,7 +338,7 @@ test-next-token-from-slice-nothing:
5d/pop-to-ebp
c3/return
skip-chars-matching: # in : (addr stream byte), delimiter : byte
skip-chars-matching: # in: (addr 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 : (addr stream byte)
skip-chars-matching-whitespace: # in: (addr 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 : (addr stream byte), delimiter : byte
skip-chars-not-matching: # in: (addr 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 : (addr stream byte)
skip-chars-not-matching-whitespace: # in: (addr stream byte)
# . prologue
55/push-ebp
89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp
@ -801,7 +801,7 @@ test-skip-chars-not-matching-whitespace:
# end
c3/return
skip-chars-matching-in-slice: # curr : (addr byte), end : (addr byte), delimiter : byte -> curr/eax
skip-chars-matching-in-slice: # curr: (addr byte), end: (addr byte), delimiter: byte -> curr/eax
# . prologue
55/push-ebp
89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp
@ -815,7 +815,7 @@ skip-chars-matching-in-slice: # curr : (addr byte), end : (addr byte), delimite
8b/copy 1/mod/*+disp8 5/rm32/ebp . . . 1/r32/ecx 0xc/disp8 . # copy *(ebp+12) to ecx
# edx = delimiter
8b/copy 1/mod/*+disp8 5/rm32/ebp . . . 2/r32/edx 0x10/disp8 . # copy *(ebp+16) to edx
# var c/ebx : byte = 0
# 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
@ -897,7 +897,7 @@ test-skip-chars-matching-in-slice-none:
# end
c3/return
skip-chars-matching-whitespace-in-slice: # curr : (addr byte), end : (addr byte) -> curr/eax
skip-chars-matching-whitespace-in-slice: # curr: (addr byte), end: (addr byte) -> curr/eax
# . prologue
55/push-ebp
89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp
@ -908,7 +908,7 @@ skip-chars-matching-whitespace-in-slice: # curr : (addr byte), end : (addr byte
8b/copy 1/mod/*+disp8 5/rm32/ebp . . . 0/r32/eax 8/disp8 . # copy *(ebp+8) to eax
# ecx = end
8b/copy 1/mod/*+disp8 5/rm32/ebp . . . 1/r32/ecx 0xc/disp8 . # copy *(ebp+12) to ecx
# var c/ebx : byte = 0
# 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
@ -970,7 +970,7 @@ test-skip-chars-matching-whitespace-in-slice:
c3/return
# minor fork of 'skip-chars-matching-in-slice'
skip-chars-not-matching-in-slice: # curr : (addr byte), end : (addr byte), delimiter : byte -> curr/eax
skip-chars-not-matching-in-slice: # curr: (addr byte), end: (addr byte), delimiter: byte -> curr/eax
# . prologue
55/push-ebp
89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp
@ -984,7 +984,7 @@ skip-chars-not-matching-in-slice: # curr : (addr byte), end : (addr byte), deli
8b/copy 1/mod/*+disp8 5/rm32/ebp . . . 1/r32/ecx 0xc/disp8 . # copy *(ebp+12) to ecx
# edx = delimiter
8b/copy 1/mod/*+disp8 5/rm32/ebp . . . 2/r32/edx 0x10/disp8 . # copy *(ebp+16) to edx
# var c/ebx : byte = 0
# 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
@ -1095,7 +1095,7 @@ test-skip-chars-not-matching-in-slice-all:
# end
c3/return
skip-chars-not-matching-whitespace-in-slice: # curr : (addr byte), end : (addr byte) -> curr/eax
skip-chars-not-matching-whitespace-in-slice: # curr: (addr byte), end: (addr byte) -> curr/eax
# . prologue
55/push-ebp
89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp
@ -1106,7 +1106,7 @@ skip-chars-not-matching-whitespace-in-slice: # curr : (addr byte), end : (addr
8b/copy 1/mod/*+disp8 5/rm32/ebp . . . 0/r32/eax 8/disp8 . # copy *(ebp+8) to eax
# ecx = end
8b/copy 1/mod/*+disp8 5/rm32/ebp . . . 1/r32/ecx 0xc/disp8 . # copy *(ebp+12) to ecx
# var c/ebx : byte = 0
# 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
@ -1168,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 : (addr stream byte)
skip-string: # line: (addr stream byte)
# . prologue
55/push-ebp
89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp
@ -1410,7 +1410,7 @@ test-skip-string-works-from-mid-stream:
5d/pop-to-ebp
c3/return
skip-string-in-slice: # curr : (addr byte), end : (addr byte) -> new_curr/eax
skip-string-in-slice: # curr: (addr byte), end: (addr byte) -> new_curr/eax
# . prologue
55/push-ebp
89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp
@ -1422,7 +1422,7 @@ skip-string-in-slice: # curr : (addr byte), end : (addr byte) -> new_curr/eax
8b/copy 1/mod/*+disp8 5/rm32/ebp . . 1/r32/ecx 8/disp8 . # copy *(ebp+8) to ecx
# edx = end
8b/copy 1/mod/*+disp8 5/rm32/ebp . . 2/r32/edx 0xc/disp8 . # copy *(ebp+12) to edx
# var c/eax : byte = 0
# var c/eax: byte = 0
31/xor 3/mod/direct 0/rm32/eax . . . 0/r32/eax . . # clear eax
# skip initial dquote
41/increment-ecx
@ -1596,7 +1596,7 @@ test-skip-string-in-slice-stops-at-end:
# update line->read to ')'
# line->read ends at ')'
skip-until-close-paren: # line : (addr stream byte)
skip-until-close-paren: # line: (addr stream byte)
# . prologue
55/push-ebp
89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp
@ -1783,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 : (addr byte), end : (addr byte) -> new_curr/eax : (addr byte)
skip-until-close-paren-in-slice: # curr: (addr byte), end: (addr byte) -> new_curr/eax: (addr byte)
# . prologue
55/push-ebp
89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp
@ -1794,7 +1794,7 @@ skip-until-close-paren-in-slice: # curr : (addr byte), end : (addr byte) -> new
8b/copy 1/mod/*+disp8 5/rm32/ebp . . 1/r32/ecx 8/disp8 . # copy *(ebp+8) to ecx
# edx = end
8b/copy 1/mod/*+disp8 5/rm32/ebp . . 2/r32/edx 0xc/disp8 . # copy *(ebp+12) to edx
# var c/eax : byte = 0
# var c/eax: byte = 0
31/xor 3/mod/direct 0/rm32/eax . . . 0/r32/eax . . # clear eax
# skip initial dquote
41/increment-ecx

View File

@ -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 : (addr buffered-file), s : (addr stream byte)
write-stream-data: # f: (addr buffered-file), s: (addr stream byte)
# . prologue
55/push-ebp
89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp
@ -18,7 +18,7 @@ write-stream-data: # f : (addr buffered-file), s : (addr stream byte)
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 : slice = {s->data, &s->data[s->write]}
# var slice/ecx: 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

View File

@ -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 : (addr stream byte), n : int32
print-int32-decimal: # out: (addr 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
#
@ -48,7 +48,7 @@ print-int32-decimal: # out : (addr stream byte), n : int32
b9/copy-to-ecx 0xa/imm32
# push sentinel
68/push 0/imm32/sentinel
# var eax : int = 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->= $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
# var w/edx : int = out->write
# var w/edx: int = out->write
8b/copy 0/mod/indirect 7/rm32/edi . . . 2/r32/edx . . # copy *edi to edx
# var curr/ecx : (addr byte) = &out->data[out->write]
# var curr/ecx: (addr byte) = &out->data[out->write]
8d/copy-address 1/mod/*+disp8 4/rm32/sib 7/base/edi 2/index/edx . 1/r32/ecx 0xc/disp8 . # copy ebx+edx+12 to ecx
# var max/ebx : (addr byte) = &out->data[out->length]
# var max/ebx: (addr 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:
@ -304,7 +304,7 @@ test-print-int32-decimal-negative-multiple-digits:
# . end
c3/return
is-decimal-digit?: # c : byte -> eax : boolean
is-decimal-digit?: # c: byte -> eax: boolean
# . prologue
55/push-ebp
89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp

View File

@ -7,7 +7,7 @@
# (re)compute the bounds of the next word in the line
# return empty string on reaching end of file
next-word: # line : (addr stream byte), out : (addr slice)
next-word: # line: (addr stream byte), out: (addr slice)
# . prologue
55/push-ebp
89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp
@ -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 : slice
# var slice/ecx: 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 : slice
# var slice/ecx: 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 : slice
# var slice/ecx: 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

View File

@ -5,9 +5,9 @@
# . 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
has-metadata?: # word : (addr slice), s : (addr string) -> eax : boolean
has-metadata?: # word: (addr slice), s: (addr string) -> eax: boolean
# pseudocode:
# var twig : &slice = next-token-from-slice(word->start, word->end, '/') # skip name
# var twig: &slice = next-token-from-slice(word->start, word->end, '/') # skip name
# curr = twig->end
# while true
# twig = next-token-from-slice(curr, word->end, '/')
@ -25,9 +25,9 @@ has-metadata?: # word : (addr slice), s : (addr 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
# var edx : (addr byte) = word->end
# var edx: (addr byte) = word->end
8b/copy 1/mod/*+disp8 6/rm32/esi . . . 2/r32/edx 4/disp8 . # copy *(esi+4) to edx
# var twig/edi : slice
# var twig/edi: slice
68/push 0/imm32/end
68/push 0/imm32/start
89/copy 3/mod/direct 7/rm32/edi . . . 4/r32/esp . . # copy esp to edi
@ -101,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 : slice = {eax, ecx}
# var in/esi: slice = {eax, ecx}
51/push-ecx
50/push-eax
89/copy 3/mod/direct 6/rm32/esi . . . 4/r32/esp . . # copy esp to esi
@ -136,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 : slice = {eax, ecx}
# var in/esi: slice = {eax, ecx}
51/push-ecx
50/push-eax
89/copy 3/mod/direct 6/rm32/esi . . . 4/r32/esp . . # copy esp to esi
@ -171,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 : slice = {eax, ecx}
# var in/esi: slice = {eax, ecx}
51/push-ecx
50/push-eax
89/copy 3/mod/direct 6/rm32/esi . . . 4/r32/esp . . # copy esp to esi
@ -206,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 : slice = {eax, ecx}
# var in/esi: slice = {eax, ecx}
51/push-ecx
50/push-eax
89/copy 3/mod/direct 6/rm32/esi . . . 4/r32/esp . . # copy esp to esi
@ -241,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 : slice = {eax, ecx}
# var in/esi: slice = {eax, ecx}
51/push-ecx
50/push-eax
89/copy 3/mod/direct 6/rm32/esi . . . 4/r32/esp . . # copy esp to esi
@ -275,7 +275,7 @@ test-has-metadata-multiple-false:
#: - if it starts with '0x' it's treated as a number. (redundant)
#: - if it's two characters long, it can't be a name. Either it's a hex
#: byte, or it raises an error.
is-valid-name?: # in : (addr slice) -> eax : boolean
is-valid-name?: # in: (addr slice) -> eax: boolean
# . prologue
55/push-ebp
89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp
@ -284,21 +284,21 @@ is-valid-name?: # in : (addr 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
# var start/ecx : (addr byte) = in->start
# var start/ecx: (addr byte) = in->start
8b/copy 0/mod/indirect 6/rm32/esi . . . 1/r32/ecx . . # copy *esi to ecx
$is-valid-name?:check0:
# 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-addr>= $is-valid-name?:false/disp8
$is-valid-name?:check1:
# var len/eax : int = in->end - start
# 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-= $is-valid-name?:false/disp8
$is-valid-name?:check2:
# var c/eax : (addr byte) = *start
# var c/eax: (addr 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
@ -337,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 : slice = {eax, ecx}
# var slice/ecx: slice = {eax, ecx}
51/push-ecx
50/push-eax
89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx
@ -371,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 : slice = {eax, ecx}
# var slice/ecx: slice = {eax, ecx}
51/push-ecx
50/push-eax
89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx
@ -405,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 : slice = {eax, ecx}
# var slice/ecx: slice = {eax, ecx}
51/push-ecx
50/push-eax
89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx
@ -439,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 : slice = {eax, ecx}
# var slice/ecx: slice = {eax, ecx}
51/push-ecx
50/push-eax
89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx
@ -473,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 : slice = {eax, ecx}
# var slice/ecx: slice = {eax, ecx}
51/push-ecx
50/push-eax
89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx
@ -507,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 : slice = {eax, ecx}
# var slice/ecx: slice = {eax, ecx}
51/push-ecx
50/push-eax
89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx
@ -532,7 +532,7 @@ test-is-valid-name-starts-with-digit:
5d/pop-to-ebp
c3/return
is-label?: # word : (addr slice) -> eax : boolean
is-label?: # word: (addr slice) -> eax: boolean
# . prologue
55/push-ebp
89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp
@ -540,7 +540,7 @@ is-label?: # word : (addr 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
# var end/ecx : (addr byte) = word->end
# var end/ecx: (addr byte) = word->end
8b/copy 1/mod/*+disp8 1/rm32/ecx . . . 1/r32/ecx 4/disp8 . # copy *(ecx+4) to ecx
# return *(end - 1) == ':'
# . eax = *(end-1)
@ -569,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 : slice = {eax, ecx}
# var slice/ecx: slice = {eax, ecx}
51/push-ecx
50/push-eax
89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx
@ -595,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 : slice = {eax, ecx}
# var slice/ecx: slice = {eax, ecx}
51/push-ecx
50/push-eax
89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx

View File

@ -4,7 +4,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
# print 'n' in hex in 'width' bytes in lower-endian order, with a space after every byte
emit-hex: # out : (addr buffered-file), n : int, width : int
emit-hex: # out: (addr buffered-file), n: int, width: int
# . prologue
55/push-ebp
89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp
@ -20,7 +20,7 @@ emit-hex: # out : (addr 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 : int = 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

View File

@ -7,7 +7,7 @@
# it in 'width' bytes of hex, least significant first.
# Otherwise just print the entire word including metadata.
# Always print a trailing space.
emit: # out : (addr buffered-file), word : (addr slice), width : int
emit: # out: (addr buffered-file), word: (addr slice), width: int
# . prologue
55/push-ebp
89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp
@ -17,7 +17,7 @@ emit: # out : (addr buffered-file), word : (addr 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 datum/edi : slice
# var datum/edi: slice
68/push 0/imm32/end
68/push 0/imm32/start
89/copy 3/mod/direct 7/rm32/edi . . . 4/r32/esp . . # copy esp to edi
@ -68,7 +68,7 @@ $emit:name:
# want to make sure that valid names aren't treated as (valid) hex
# numbers.)
$emit:hex-int:
# . var value/eax : int = parse-hex-int(datum)
# . var value/eax: int = parse-hex-int(datum)
# . . push args
57/push-edi
# . . call
@ -120,7 +120,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 : slice = {eax, ecx}
# var slice/ecx: slice = {eax, ecx}
51/push-ecx
50/push-eax
89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx
@ -179,7 +179,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 : slice = {eax, ecx}
# var slice/ecx: slice = {eax, ecx}
51/push-ecx
50/push-eax
89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx
@ -237,7 +237,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 : slice = {eax, ecx}
# var slice/ecx: slice = {eax, ecx}
51/push-ecx
50/push-eax
89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx
@ -296,7 +296,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 : slice = {eax, ecx}
# var slice/ecx: slice = {eax, ecx}
51/push-ecx
50/push-eax
89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx
@ -354,7 +354,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 : slice = {eax, ecx}
# var slice/ecx: 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 +412,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 : slice = {eax, ecx}
# var slice/ecx: slice = {eax, ecx}
51/push-ecx
50/push-eax
89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx

View File

@ -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 : (addr byte), len : int
zero-out: # start: (addr byte), len: int
# pseudocode:
# curr/esi = start
# i/ecx = 0
@ -25,7 +25,7 @@ zero-out: # start : (addr byte), 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
# var i/ecx : int = 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

View File

@ -24,7 +24,7 @@
# if no row is found, abort
# type string_key = (addr array byte)
get: # table : (addr stream {string_key, T}), key : string_key, row-size : int, abort-message-prefix : (addr array byte) -> eax : (addr T)
get: # table: (addr stream {string_key, T}), key: string_key, row-size: int, abort-message-prefix: (addr array byte) -> eax: (addr T)
# pseudocode:
# curr = table->data
# max = &table->data[table->write]
@ -43,9 +43,9 @@ get: # table : (addr stream {string_key, T}), key : string_key, row-size : int,
56/push-esi
# esi = table
8b/copy 1/mod/*+disp8 5/rm32/ebp . . . 6/r32/esi 8/disp8 . # copy *(ebp+8) to esi
# var curr/ecx : (addr string_key) = table->data
# var curr/ecx: (addr string_key) = table->data
8d/copy-address 1/mod/*+disp8 6/rm32/esi . . . 1/r32/ecx 0xc/disp8 . # copy esi+12 to ecx
# var max/edx : (addr byte) = &table->data[table->write]
# var max/edx: (addr 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:
@ -125,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 : (stream {string, number} 16) # 2 rows * 8 bytes/row
# var table/ecx: (stream {string, number} 16) # 2 rows * 8 bytes/row
81 5/subop/subtract 3/mod/direct 4/rm32/esp . . . . . 0x10/imm32 # subtract from esp
68/push 0x10/imm32/length
68/push 0/imm32/read
@ -198,7 +198,7 @@ $test-get:end:
c3/return
# if no row is found, abort
get-slice: # table : (addr stream {string_key, T}), key : (addr slice), row-size : int, abort-message-prefix : (addr array byte) -> eax : (addr T)
get-slice: # table: (addr stream {string_key, T}), key: (addr slice), row-size: int, abort-message-prefix: (addr array byte) -> eax: (addr T)
# pseudocode:
# curr = table->data
# max = &table->data[table->write]
@ -217,9 +217,9 @@ get-slice: # table : (addr stream {string_key, T}), key : (addr slice), row-siz
56/push-esi
# esi = table
8b/copy 1/mod/*+disp8 5/rm32/ebp . . . 6/r32/esi 8/disp8 . # copy *(ebp+8) to esi
# var curr/ecx : (addr string_key) = table->data
# var curr/ecx: (addr string_key) = table->data
8d/copy-address 1/mod/*+disp8 6/rm32/esi . . . 1/r32/ecx 0xc/disp8 . # copy esi+12 to ecx
# var max/edx : (addr byte) = &table->data[table->write]
# var max/edx: (addr 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:
@ -306,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 : (stream {string, number} 16) # 2 rows * 8 bytes/row
# var table/ecx: (stream {string, number} 16) # 2 rows * 8 bytes/row
81 5/subop/subtract 3/mod/direct 4/rm32/esp . . . . . 0x10/imm32 # subtract from esp
68/push 0x10/imm32/length
68/push 0/imm32/read
@ -336,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 : slice = {eax, edx}
# var slice/edx: slice = {eax, edx}
52/push-edx
50/push-eax
89/copy 3/mod/direct 2/rm32/edx . . . 4/r32/esp . . # copy esp to edx
@ -366,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 : slice = {eax, edx}
# var slice/edx: slice = {eax, edx}
52/push-edx
50/push-eax
89/copy 3/mod/direct 2/rm32/edx . . . 4/r32/esp . . # copy esp to edx
@ -401,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 : (addr stream {string_key, T}), key : string_key, row-size : int -> eax : (addr T)
get-or-insert: # table: (addr stream {string_key, T}), key: string_key, row-size: int -> eax: (addr T)
# pseudocode:
# curr = table->data
# max = &table->data[table->write]
@ -425,9 +425,9 @@ get-or-insert: # table : (addr stream {string_key, T}), key : string_key, 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
# var curr/ecx : (addr string_key) = table->data
# var curr/ecx: (addr string_key) = table->data
8d/copy-address 1/mod/*+disp8 6/rm32/esi . . . 1/r32/ecx 0xc/disp8 . # copy esi+12 to ecx
# var max/edx : (addr string_key) = &table->data[table->write]
# var max/edx: (addr 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:
@ -512,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 : (stream {string, number} 16) # 2 rows * 8 bytes/row
# var table/ecx: (stream {string, number} 16) # 2 rows * 8 bytes/row
81 5/subop/subtract 3/mod/direct 4/rm32/esp . . . . . 0x10/imm32 # subtract from esp
68/push 0x10/imm32/length
68/push 0/imm32/read
@ -652,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 : (addr stream {string_key, T}), key : (addr slice), row-size : int -> eax : (addr T)
leaky-get-or-insert-slice: # table: (addr stream {string_key, T}), key: (addr slice), row-size: int -> eax: (addr T)
# pseudocode:
# curr = table->data
# max = &table->data[table->write]
@ -676,9 +676,9 @@ leaky-get-or-insert-slice: # table : (addr stream {string_key, T}), key : (addr
56/push-esi
# esi = table
8b/copy 1/mod/*+disp8 5/rm32/ebp . . . 6/r32/esi 8/disp8 . # copy *(ebp+8) to esi
# var curr/ecx : (addr string_key) = table->data
# var curr/ecx: (addr string_key) = table->data
8d/copy-address 1/mod/*+disp8 6/rm32/esi . . . 1/r32/ecx 0xc/disp8 . # copy esi+12 to ecx
# var max/edx : (addr string_key) = &table->data[table->write]
# var max/edx: (addr 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:
@ -769,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 : (stream {string, number} 16) # 2 rows * 8 bytes/row
# var table/ecx: (stream {string, number} 16) # 2 rows * 8 bytes/row
81 5/subop/subtract 3/mod/direct 4/rm32/esp . . . . . 0x10/imm32 # subtract from esp
68/push 0x10/imm32/length
68/push 0/imm32/read
@ -780,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 : slice = {eax, edx}
# var slice/edx: slice = {eax, edx}
52/push-edx
50/push-eax
89/copy 3/mod/direct 2/rm32/edx . . . 4/r32/esp . . # copy esp to edx
@ -873,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 : slice = {eax, edx}
# var slice/edx: slice = {eax, edx}
52/push-edx
50/push-eax
89/copy 3/mod/direct 2/rm32/edx . . . 4/r32/esp . . # copy esp to edx
@ -924,9 +924,9 @@ $test-leaky-get-or-insert-slice:end:
c3/return
# if no row is found, stop(ed)
get-or-stop: # table : (addr stream {string_key, T}), key : string_key, row-size : int,
# abort-message-prefix : (addr array byte), err : (addr buffered-file), ed : (addr exit-descriptor)
# -> eax : (addr T)
get-or-stop: # table: (addr stream {string_key, T}), key: string_key, row-size: int,
# abort-message-prefix: (addr array byte), err: (addr buffered-file), ed: (addr exit-descriptor)
# -> eax: (addr T)
# pseudocode:
# curr = table->data
# max = &table->data[table->write]
@ -946,9 +946,9 @@ get-or-stop: # table : (addr stream {string_key, T}), key : string_key, row-siz
56/push-esi
# esi = table
8b/copy 1/mod/*+disp8 5/rm32/ebp . . . 6/r32/esi 8/disp8 . # copy *(ebp+8) to esi
# var curr/ecx : (addr string_key) = table->data
# var curr/ecx: (addr string_key) = table->data
8d/copy-address 1/mod/*+disp8 6/rm32/esi . . . 1/r32/ecx 0xc/disp8 . # copy esi+12 to ecx
# var max/edx : (addr byte) = &table->data[table->write]
# var max/edx: (addr 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:
@ -1051,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 : (stream {string, number} 16) # 2 rows * 8 bytes/row
# var table/ecx: (stream {string, number} 16) # 2 rows * 8 bytes/row
81 5/subop/subtract 3/mod/direct 4/rm32/esp . . . . . 0x10/imm32 # subtract from esp
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 : exit-descriptor
# var ed/edx: 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
@ -1140,9 +1140,9 @@ $test-get-or-stop:end:
c3/return
# if no row is found, stop(ed)
get-slice-or-stop: # table : (addr stream {string_key, _}), key : (addr slice), row-size : int,
# abort-message-prefix : (addr string), err : (addr buffered-file), ed : (addr exit-descriptor)
# -> eax : (addr _)
get-slice-or-stop: # table: (addr stream {string_key, _}), key: (addr slice), row-size: int,
# abort-message-prefix: (addr string), err: (addr buffered-file), ed: (addr exit-descriptor)
# -> eax: (addr _)
# pseudocode:
# curr = table->data
# max = &table->data[table->write]
@ -1162,9 +1162,9 @@ get-slice-or-stop: # table : (addr stream {string_key, _}), key : (addr slice),
56/push-esi
# esi = table
8b/copy 1/mod/*+disp8 5/rm32/ebp . . . 6/r32/esi 8/disp8 . # copy *(ebp+8) to esi
# var curr/ecx : (addr string_key) = table->data
# var curr/ecx: (addr string_key) = table->data
8d/copy-address 1/mod/*+disp8 6/rm32/esi . . . 1/r32/ecx 0xc/disp8 . # copy esi+12 to ecx
# var max/edx : (addr byte) = &table->data[table->write]
# var max/edx: (addr 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:
@ -1267,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 : (stream {string, number} 16) # 2 rows * 8 bytes/row
# var table/ecx: (stream {string, number} 16) # 2 rows * 8 bytes/row
81 5/subop/subtract 3/mod/direct 4/rm32/esp . . . . . 0x10/imm32 # subtract from esp
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 : exit-descriptor
# var ed/edx: 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 : slice = "code"
# var slice/ebx: 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
@ -1379,7 +1379,7 @@ $test-get-slice-or-stop:end:
c3/return
# if no row is found, return null (0)
maybe-get: # table : (addr stream {string_key, T}), key : string_key, row-size : int -> eax : (addr T)
maybe-get: # table: (addr stream {string_key, T}), key: string_key, row-size: int -> eax: (addr T)
# pseudocode:
# curr = table->data
# max = &table->data[table->write]
@ -1398,9 +1398,9 @@ maybe-get: # table : (addr stream {string_key, T}), key : string_key, 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
# var curr/ecx : (addr string_key) = table->data
# var curr/ecx: (addr string_key) = table->data
8d/copy-address 1/mod/*+disp8 6/rm32/esi . . . 1/r32/ecx 0xc/disp8 . # copy esi+12 to ecx
# var max/edx : (addr byte) = &table->data[table->write]
# var max/edx: (addr 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:
@ -1443,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 : (stream {string, number} 16) # 2 rows * 8 bytes/row
# var table/ecx: (stream {string, number} 16) # 2 rows * 8 bytes/row
81 5/subop/subtract 3/mod/direct 4/rm32/esp . . . . . 0x10/imm32 # subtract from esp
68/push 0x10/imm32/length
68/push 0/imm32/read
@ -1526,7 +1526,7 @@ $test-maybe-get:end:
c3/return
# if no row is found, return null (0)
maybe-get-slice: # table : (addr stream {string_key, T}), key : (addr slice), row-size : int -> eax : (addr T)
maybe-get-slice: # table: (addr stream {string_key, T}), key: (addr slice), row-size: int -> eax: (addr T)
# pseudocode:
# curr = table->data
# max = &table->data[table->write]
@ -1545,9 +1545,9 @@ maybe-get-slice: # table : (addr stream {string_key, T}), key : (addr slice), r
56/push-esi
# esi = table
8b/copy 1/mod/*+disp8 5/rm32/ebp . . . 6/r32/esi 8/disp8 . # copy *(ebp+8) to esi
# var curr/ecx : (addr string_key) = table->data
# var curr/ecx: (addr string_key) = table->data
8d/copy-address 1/mod/*+disp8 6/rm32/esi . . . 1/r32/ecx 0xc/disp8 . # copy esi+12 to ecx
# var max/edx : (addr byte) = &table->data[table->write]
# var max/edx: (addr 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:
@ -1590,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 : (stream {string, number} 16) # 2 rows * 8 bytes/row
# var table/ecx: (stream {string, number} 16) # 2 rows * 8 bytes/row
81 5/subop/subtract 3/mod/direct 4/rm32/esp . . . . . 0x10/imm32 # subtract from esp
68/push 0x10/imm32/length
68/push 0/imm32/read
@ -1612,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 : slice = {eax, edx}
# var slice/edx: slice = {eax, edx}
52/push-edx
50/push-eax
89/copy 3/mod/direct 2/rm32/edx . . . 4/r32/esp . . # copy esp to edx
@ -1662,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 : slice = {eax, edx}
# var slice/edx: slice = {eax, edx}
52/push-edx
50/push-eax
89/copy 3/mod/direct 2/rm32/edx . . . 4/r32/esp . . # copy esp to edx

View File

@ -5,7 +5,7 @@
# read all bytes from 'f' and store them into 's'
# abort if 's' is too small
slurp: # f : (addr buffered-file), s : (addr stream byte)
slurp: # f: (addr buffered-file), s: (addr stream byte)
# pseudocode:
# while true
# if (s->write >= s->length) abort
@ -63,7 +63,7 @@ $slurp:loop:
3d/compare-eax-and 0/imm32
74/jump-if-= $slurp:end/disp8
$slurp:from-stream:
# var c/eax : byte = 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] = c

View File

@ -8,7 +8,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
compute-width: # word : (addr array byte) -> eax : int
compute-width: # word: (addr array byte) -> eax: int
# . prologue
55/push-ebp
89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp
@ -16,12 +16,12 @@ compute-width: # word : (addr 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
# var ecx : (addr byte) = &word[word->length]
# var ecx: (addr 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 : slice = {eax, ecx}
# var in/ecx: slice = {eax, ecx}
51/push-ecx
50/push-eax
89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx
@ -42,7 +42,7 @@ $compute-width:end:
5d/pop-to-ebp
c3/return
compute-width-of-slice: # s : (addr slice) -> eax : int
compute-width-of-slice: # s: (addr slice) -> eax: int
# . prologue
55/push-ebp
89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp

View File

@ -4,7 +4,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
# print 'arr' in hex with a space after every byte
emit-hex-array: # out : (addr buffered-file), arr : (addr array byte)
emit-hex-array: # out: (addr buffered-file), arr: (addr array byte)
# . prologue
55/push-ebp
89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp
@ -17,12 +17,12 @@ emit-hex-array: # out : (addr buffered-file), arr : (addr array byte)
8b/copy 1/mod/*+disp8 5/rm32/ebp . . . 7/r32/edi 8/disp8 . # copy *(ebp+8) to edi
# edx = arr
8b/copy 1/mod/*+disp8 5/rm32/ebp . . . 2/r32/edx 0xc/disp8 . # copy *(ebp+12) to edx
# var curr/ecx : (addr byte) = arr->data
# var curr/ecx: (addr byte) = arr->data
8d/copy-address 1/mod/*+disp8 2/rm32/edx . . . 1/r32/ecx 4/disp8 . # copy edx+4 to ecx
# var max/edx : (addr byte) = &arr->data[arr->length]
# var max/edx: (addr 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
# var c/eax : byte = 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

View File

@ -5,7 +5,7 @@
# (re)compute the bounds of the next word or string literal in the line
# return empty string on reaching end of file
next-word-or-string: # line : (addr stream byte), out : (addr slice)
next-word-or-string: # line: (addr stream byte), out: (addr slice)
# . prologue
55/push-ebp
89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp
@ -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 : slice
# var slice/ecx: 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 : slice
# var slice/ecx: 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 : slice
# var slice/ecx: 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 : slice
# var slice/ecx: 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 : slice
# var slice/ecx: 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

View File

@ -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 : (addr stream byte), n : int
write-int: # out: (addr stream byte), n: int
# . prologue
55/push-ebp
89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp

View File

@ -7,7 +7,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-stack: # s : (addr stack)
clear-stack: # s: (addr stack)
# . prologue
55/push-ebp
89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp
@ -16,12 +16,12 @@ clear-stack: # s : (addr stack)
51/push-ecx
# eax = s
8b/copy 1/mod/*+disp8 5/rm32/ebp . . . 0/r32/eax 8/disp8 . # copy *(ebp+8) to eax
# var max/ecx : (addr byte) = &s->data[s->length]
# var max/ecx: (addr byte) = &s->data[s->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
# var curr/eax : (addr byte) = s->data
# var curr/eax: (addr byte) = s->data
81 0/subop/add 3/mod/direct 0/rm32/eax . . . . . 8/imm32 # add to eax
$clear-stack:loop:
# if (curr >= max) break
@ -107,7 +107,7 @@ test-clear-stack:
5d/pop-to-ebp
c3/return
push: # s : (addr stack), n : int
push: # s: (addr stack), n: int
# . prologue
55/push-ebp
89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp
@ -227,7 +227,7 @@ test-push:
5d/pop-to-ebp
c3/return
pop: # s : (addr stack) -> n/eax : int
pop: # s: (addr stack) -> n/eax: int
# . prologue
55/push-ebp
89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp
@ -331,7 +331,7 @@ test-pop:
5d/pop-to-ebp
c3/return
top: # s : (addr stack) -> n/eax : int
top: # s: (addr stack) -> n/eax: int
# . prologue
55/push-ebp
89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp

View File

@ -2,7 +2,7 @@
== code
array-equal?: # a : (addr array int), b : (addr array int) -> eax : boolean
array-equal?: # a: (addr array int), b: (addr array int) -> eax: boolean
# pseudocode:
# lena = a->length
# if (lena != b->length) return false
@ -37,27 +37,27 @@ array-equal?: # a : (addr array int), b : (addr array int) -> eax : boolean
8b/-> *(ebp+8) 6/r32/esi
# edi = b
8b/-> *(ebp+0xc) 7/r32/edi
# var lena/edx : int = a->length
# var lena/edx: int = a->length
8b/-> *esi 2/r32/edx
$array-equal?:lengths:
# if (lena != b->length) return false
39/compare *edi 2/r32/edx
75/jump-if-!= $array-equal?:false/disp8
# var curra/esi : (addr byte) = a->data
# var curra/esi: (addr byte) = a->data
81 0/subop/add %esi 4/imm32
# var currb/edi : (addr byte) = b->data
# var currb/edi: (addr byte) = b->data
81 0/subop/add %edi 4/imm32
# var i/ecx : int = 0
# var i/ecx: int = 0
31/xor %ecx 1/r32/ecx
# var vala/eax : int
# var valb/ebx : int
# var vala/eax: int
# var valb/ebx: int
$array-equal?:loop:
# if (i >= lena) return true
39/compare %ecx 2/r32/edx
7d/jump-if->= $array-equal?:true/disp8
# var vala/eax : int = *curra
# var vala/eax: int = *curra
8b/-> *esi 0/r32/eax
# var valb/ebx : int = *currb
# var valb/ebx: int = *currb
8b/-> *edi 3/r32/ebx
# if (vala != valb) return false
39/compare %eax 3/r32/ebx
@ -90,10 +90,10 @@ test-compare-empty-with-empty-array:
# . prologue
55/push-ebp
89/<- %ebp 4/r32/esp
# var ecx : (array _) = []
# var ecx: (array _) = []
68/push 0/imm32/size
89/<- %ecx 4/r32/esp
# var edx : (array _) = []
# var edx: (array _) = []
68/push 0/imm32/size
89/<- %edx 4/r32/esp
# eax = array-equal?(ecx, edx)
@ -122,11 +122,11 @@ test-compare-empty-with-non-empty-array: # also checks length-mismatch code pat
# . prologue
55/push-ebp
89/<- %ebp 4/r32/esp
# var ecx : (array int) = [1]
# var ecx: (array int) = [1]
68/push 1/imm32
68/push 4/imm32/size
89/<- %ecx 4/r32/esp
# var edx : (array int) = []
# var edx: (array int) = []
68/push 0/imm32/size
89/<- %edx 4/r32/esp
# eax = array-equal?(ecx, edx)
@ -155,13 +155,13 @@ test-compare-equal-arrays:
# . prologue
55/push-ebp
89/<- %ebp 4/r32/esp
# var ecx : (array int) = [1, 2, 3]
# var ecx: (array int) = [1, 2, 3]
68/push 3/imm32
68/push 2/imm32
68/push 1/imm32
68/push 0xc/imm32/size
89/<- %ecx 4/r32/esp
# var edx : (array int) = [1, 2, 3]
# var edx: (array int) = [1, 2, 3]
68/push 3/imm32
68/push 2/imm32
68/push 1/imm32
@ -193,13 +193,13 @@ test-compare-inequal-arrays-equal-lengths:
# . prologue
55/push-ebp
89/<- %ebp 4/r32/esp
# var ecx : (array int) = [1, 4, 3]
# var ecx: (array int) = [1, 4, 3]
68/push 3/imm32
68/push 4/imm32
68/push 1/imm32
68/push 0xc/imm32/size
89/<- %ecx 4/r32/esp
# var edx : (array int) = [1, 2, 3]
# var edx: (array int) = [1, 2, 3]
68/push 3/imm32
68/push 2/imm32
68/push 1/imm32
@ -227,7 +227,7 @@ test-compare-inequal-arrays-equal-lengths:
5d/pop-to-ebp
c3/return
parse-array-of-ints: # ad : (addr allocation-descriptor), s : (addr string) -> result/eax : (handle array int)
parse-array-of-ints: # ad: (addr allocation-descriptor), s: (addr string) -> result/eax: (handle array int)
# pseudocode
# end = &s->data[s->length]
# curr = s->data
@ -240,7 +240,7 @@ parse-array-of-ints: # ad : (addr allocation-descriptor), s : (addr string) ->
# ++size
# result = allocate(ad, (size+1)*4)
# result->size = (size+1)*4
# var slice : slice = {s->data, 0}
# var slice: slice = {s->data, 0}
# out = result->data
# while true
# if (slice->start >= end) break
@ -263,14 +263,14 @@ parse-array-of-ints: # ad : (addr allocation-descriptor), s : (addr string) ->
57/push-edi
# esi = s
8b/-> *(ebp+0xc) 6/r32/esi
# var curr/ecx : (addr byte) = s->data
# var curr/ecx: (addr byte) = s->data
8d/copy-address *(esi+4) 1/r32/ecx
# var end/edx : (addr byte) = &s->data[s->length]
# var end/edx: (addr byte) = &s->data[s->length]
# . edx = s->length
8b/-> *esi 2/r32/edx
# . edx += curr
01/add %edx 1/r32/ecx
# var size/ebx : int = 0
# var size/ebx: int = 0
31/xor %ebx 3/r32/ebx
$parse-array-of-ints:loop1:
# if (curr >= end) break
@ -307,7 +307,7 @@ $parse-array-of-ints:loop1:
81 0/subop/add %ebx 4/imm32
eb/jump $parse-array-of-ints:loop1/disp8
$parse-array-of-ints:break1:
# var result/edi : (handle array int) = allocate(ad, size+4)
# var result/edi: (handle array int) = allocate(ad, size+4)
# . eax = allocate(ad, size+4)
# . . push args
89/<- %eax 3/r32/ebx
@ -323,12 +323,12 @@ $parse-array-of-ints:break1:
# result->size = size
89/<- *eax 3/r32/ebx
$parse-array-of-ints:pass2:
# var slice/ecx : slice = {s->data, 0}
# var slice/ecx: slice = {s->data, 0}
68/push 0/imm32/end
8d/copy-address *(esi+4) 1/r32/ecx
51/push-ecx
89/<- %ecx 4/r32/esp
# var out/ebx : (addr byte) = result->data
# var out/ebx: (addr byte) = result->data
8d/copy-address *(eax+4) 3/r32/ebx
$parse-array-of-ints:loop2:
# if (slice->start >= end) break
@ -398,7 +398,7 @@ test-parse-array-of-ints:
# . prologue
55/push-ebp
89/<- %ebp 4/r32/esp
# var ecx : (array int) = [1, 2, 3]
# var ecx: (array int) = [1, 2, 3]
68/push 3/imm32
68/push 2/imm32
68/push 1/imm32
@ -492,7 +492,7 @@ test-parse-array-of-ints-extra-whitespace:
# . prologue
55/push-ebp
89/<- %ebp 4/r32/esp
# var ecx : (array int) = [1, 2, 3]
# var ecx: (array int) = [1, 2, 3]
68/push 3/imm32
68/push 2/imm32
68/push 1/imm32
@ -530,13 +530,13 @@ test-parse-array-of-ints-extra-whitespace:
# helper for later tests
# compare an array with a string representation of an array literal
check-array-equal: # a : (addr array int), expected : (addr string), msg : (addr string)
check-array-equal: # a: (addr array int), expected: (addr string), msg: (addr string)
# . prologue
55/push-ebp
89/<- %ebp 4/r32/esp
# . save registers
50/push-eax
# var b/ecx : (handle array int) = 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 *(ebp+0xc)
@ -576,7 +576,7 @@ test-check-array-equal:
# . prologue
55/push-ebp
89/<- %ebp 4/r32/esp
# var ecx : (array int) = [1, 2, 3]
# var ecx: (array int) = [1, 2, 3]
68/push 3/imm32
68/push 2/imm32
68/push 1/imm32

View File

@ -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: 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()
@ -86,9 +86,9 @@ $subx-assort-main:end:
# table: (addr stream {string, (addr stream byte)}) (8 bytes per row)
# inefficient; uses sequential search for looking up segments by name
subx-assort: # in : (addr buffered-file), out : (addr buffered-file)
subx-assort: # in: (addr buffered-file), out: (addr buffered-file)
# pseudocode:
# var table : (addr stream {string, (addr stream byte)} 10/rows)
# var table: (addr stream {string, (addr stream byte)} 10/rows)
# read-segments(in, table)
# write-segments(out, table)
#
@ -97,7 +97,7 @@ subx-assort: # in : (addr buffered-file), out : (addr 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 : (stream {string, (addr stream byte)} 80) # 10 rows * 8 bytes/row
# var table/ecx: (stream {string, (addr 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
@ -453,10 +453,10 @@ test-subx-assort:
# type string_key = (addr array byte)
# beware: leaks memory (one name per segment read)
read-segments: # in : (addr buffered-file), table : (addr stream {string_key, (handle stream byte)})
read-segments: # in: (addr buffered-file), table: (addr stream {string_key, (handle stream byte)})
# pseudocode:
# var curr-segment : (handle stream byte) = 0
# var line : (stream byte 512)
# var curr-segment: (handle stream byte) = 0
# var line: (stream byte 512)
# while true
# clear-stream(line)
# read-line-buffered(in, line)
@ -496,13 +496,13 @@ read-segments: # in : (addr buffered-file), table : (addr stream {string_key, (
52/push-edx
53/push-ebx
56/push-esi
# var line/ecx : (stream byte 512)
# var line/ecx: (stream byte 512)
81 5/subop/subtract 3/mod/direct 4/rm32/esp . . . . . 0x200/imm32 # subtract from esp
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 : slice
# var word-slice/edx: 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
@ -599,9 +599,9 @@ $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
# . var start/esi : (addr byte) = word-slice->start
# . var start/esi: (addr byte) = word-slice->start
8b/copy 0/mod/indirect 2/rm32/edx . . . 6/r32/esi . . # copy *ecx to esi
# . var c/eax : byte = *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 (c == '#') continue
@ -717,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
#? # }}}
# var segment-slot/eax : (addr handle stream byte) = leaky-get-or-insert-slice(table, segment-name, row-size=8)
# var segment-slot/eax: (addr 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
@ -726,7 +726,7 @@ $read-segments:check-for-segment-header:
e8/call leaky-get-or-insert-slice/disp32
# . . discard args
81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32 # add to esp
# var curr-segment/ebx : (handle stream byte) = *segment-slot
# var curr-segment/ebx: (handle stream byte) = *segment-slot
8b/copy 0/mod/indirect 0/rm32/eax . . . 3/r32/ebx . . # copy *eax to ebx
# if (curr-segment != 0) continue
81 7/subop/compare 3/mod/direct 3/rm32/ebx . . . . . 0/imm32 # compare ebx
@ -843,7 +843,7 @@ $read-segments:end:
5d/pop-to-ebp
c3/return
write-segments: # out : (addr buffered-file), table : (addr stream {string_key, (handle stream byte)})
write-segments: # out: (addr buffered-file), table: (addr stream {string_key, (handle stream byte)})
# pseudocode:
# var curr = table->data
# var max = &table->data[table->write]
@ -862,17 +862,17 @@ write-segments: # out : (addr buffered-file), table : (addr stream {string_key,
56/push-esi
# esi = table
8b/copy 1/mod/*+disp8 5/rm32/ebp . . . 6/r32/esi 0xc/disp8 . # copy *(ebp+12) to esi
# var write/edx : int = table->write
# var write/edx: int = table->write
8b/copy 0/mod/indirect 6/rm32/esi . . . 2/r32/edx . . # copy *esi to edx
# var curr/esi : (addr byte) = table->data
# var curr/esi: (addr byte) = table->data
81 0/subop/add 3/mod/direct 6/rm32/esi . . . . . 0xc/imm32 # add to eax
# var max/edx : (addr byte) = curr + write
# var max/edx: (addr 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-addr>= $write-segments:break/disp8
# var stream/eax : (addr stream byte) = table[i].stream
# var stream/eax: (addr 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

View File

@ -75,11 +75,11 @@ $subx-braces-main:end:
b8/copy-to-eax 1/imm32/exit
cd/syscall 0x80/imm8
subx-braces: # in : (addr buffered-file), out : (addr buffered-file)
subx-braces: # in: (addr buffered-file), out: (addr buffered-file)
# pseudocode:
# var line : (stream byte 512)
# var label-stack : (stack int 32) # at most 32 levels of nesting
# var next-label-id : int = 1
# var line: (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)
# read-line-buffered(in, line)
@ -95,7 +95,7 @@ subx-braces: # in : (addr buffered-file), out : (addr buffered-file)
# print(out, "_break" top ":\n")
# continue
# while true
# var word-slice : (addr slice) = next-word-or-string(line)
# var word-slice: (addr slice) = next-word-or-string(line)
# if slice-empty?(word-slice) # end of line
# break
# if slice-starts-with?(word-slice, "#") # comment
@ -123,20 +123,20 @@ subx-braces: # in : (addr buffered-file), out : (addr buffered-file)
57/push-edi
# esi = in
8b/-> *(ebp+8) 6/r32/esi
# var line/ecx : (stream byte 512)
# var line/ecx: (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: (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
# var next-label-id/ebx : int = 1
# var next-label-id/ebx: int = 1
c7 0/subop/copy %ebx 1/imm32
# var word-slice/edi : slice
# var word-slice/edi: slice
68/push 0/imm32/end
68/push 0/imm32/start
89/<- %edi 4/r32/esp

View File

@ -75,10 +75,10 @@ $subx-calls-main:end:
b8/copy-to-eax 1/imm32/exit
cd/syscall 0x80/imm8
subx-calls: # in : (addr buffered-file), out : (addr buffered-file)
subx-calls: # in: (addr buffered-file), out: (addr buffered-file)
# pseudocode:
# var line : (stream byte 512)
# var words : (stream slice 16) # at most function name and 15 args
# var line: (stream byte 512)
# var words: (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 : (addr buffered-file), out : (addr buffered-file)
51/push-ecx
52/push-edx
56/push-esi
# var line/esi : (stream byte 512)
# var line/esi: (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 : (stream slice 128) # 16 rows * 8 bytes/row
# var words/edx: (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
@ -232,9 +232,9 @@ $subx-calls:end:
5d/pop-to-ebp
c3/return
parse-line: # line : (addr stream byte), words : (addr stream slice)
parse-line: # line: (addr stream byte), words: (addr stream slice)
# pseudocode:
# var word-slice : slice
# var word-slice: slice
# while true
# word-slice = next-word-string-or-expression-without-metadata(line)
# if slice-empty?(word-slice)
@ -247,7 +247,7 @@ parse-line: # line : (addr stream byte), words : (addr stream slice)
89/<- %ebp 4/r32/esp
# . save registers
51/push-ecx
# var word-slice/ecx : slice
# var word-slice/ecx: slice
68/push 0/imm32/end
68/push 0/imm32/start
89/<- %ecx 4/r32/esp
@ -341,7 +341,7 @@ $parse-line:end:
5d/pop-to-ebp
c3/return
emit-call: # out : (addr buffered-file), words : (addr stream slice)
emit-call: # out: (addr buffered-file), words: (addr stream slice)
# pseudocode:
# if (words->write < 8) abort
# curr = &words->data[words->write-8]
@ -382,9 +382,9 @@ emit-call: # out : (addr buffered-file), words : (addr stream slice)
8b/-> *esi 1/r32/ecx
81 5/subop/subtract %ecx 8/imm32
0f 8c/jump-if-< $emit-call:error1/disp32
# var curr/ecx : (addr slice) = &words->data[words->write-8]
# var curr/ecx: (addr slice) = &words->data[words->write-8]
8d/copy-address *(esi+ecx+0xc) 1/r32/ecx
# var min/edx : (addr byte) = words->data
# var min/edx: (addr byte) = words->data
8d/copy-address *(esi+0xc) 2/r32/edx
# - emit pushes
$emit-call:push-loop:
@ -392,9 +392,9 @@ $emit-call:push-loop:
39/compare %ecx 2/r32/edx
0f 8e/jump-if-<= $emit-call:call-instruction/disp32
# if (*curr->start in '%' '*') goto push-rm32
# . var start/eax : (addr byte) = curr->start
# . var start/eax: (addr byte) = curr->start
8b/-> *ecx 0/r32/eax
# . var c/eax : byte = *eax
# . var c/eax: byte = *eax
8b/-> *eax 0/r32/eax
81 4/subop/and %eax 0xff/imm32
# . if (c == '%') goto push-rm32
@ -742,7 +742,7 @@ test-subx-calls-processes-calls:
5d/pop-to-ebp
c3/return
next-word-string-or-expression-without-metadata: # line : (addr stream byte), out : (addr slice)
next-word-string-or-expression-without-metadata: # line: (addr stream byte), out: (addr slice)
# pseudocode:
# skip-chars-matching(line, ' ')
# if line->read >= line->write # end of line
@ -831,7 +831,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
# . var eax : byte = 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
@ -1192,7 +1192,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 : slice
# var slice/ecx: slice
68/push 0/imm32/end
68/push 0/imm32/start
89/<- %ecx 4/r32/esp
@ -1265,7 +1265,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 : slice
# var slice/ecx: slice
68/push 0/imm32/end
68/push 0/imm32/start
89/<- %ecx 4/r32/esp
@ -1338,7 +1338,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 : slice
# var slice/ecx: slice
68/push 0/imm32/end
68/push 0/imm32/start
89/<- %ecx 4/r32/esp
@ -1380,7 +1380,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 : slice
# var slice/ecx: slice
68/push 0/imm32/end
68/push 0/imm32/start
89/<- %ecx 4/r32/esp
@ -1443,7 +1443,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 : slice
# var slice/ecx: slice
68/push 0/imm32/end
68/push 0/imm32/start
89/<- %ecx 4/r32/esp
@ -1506,7 +1506,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 : slice
# var slice/ecx: slice
68/push 0/imm32/end
68/push 0/imm32/start
89/<- %ecx 4/r32/esp
@ -1569,7 +1569,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 : slice
# var slice/ecx: slice
68/push 0/imm32/end
68/push 0/imm32/start
89/<- %ecx 4/r32/esp
@ -1624,7 +1624,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 : slice
# var slice/ecx: slice
68/push 0/imm32/end
68/push 0/imm32/start
89/<- %ecx 4/r32/esp
@ -1679,7 +1679,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 : slice
# var slice/ecx: slice
68/push 0/imm32/end
68/push 0/imm32/start
89/<- %ecx 4/r32/esp
@ -1734,7 +1734,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 : slice
# var slice/ecx: slice
68/push 0/imm32/end
68/push 0/imm32/start
89/<- %ecx 4/r32/esp

View File

@ -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: 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 : (addr buffered-file), out : fd or (addr stream byte), err : fd or (addr stream byte), ed : (addr exit-descriptor)
compile: # in: (addr buffered-file), out: fd or (addr stream byte), err: fd or (addr stream byte), ed: (addr 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 : (addr buffered-file), out : fd or (addr stream byte), 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 : (stream byte 7)
# var num/ecx: (stream byte 7)
# Numbers can be 32 bits or 8 hex bytes long. One of them will be in 'Look', so we need space for 7 bytes.
# 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:
# 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 : (addr buffered-file), out : (addr stream byte), err : fd or (addr stream byte), ed : (addr exit-descriptor)
get-num: # in: (addr buffered-file), out: (addr stream byte), err: fd or (addr stream byte), ed: (addr exit-descriptor)
# pseudocode:
# if (!is-digit?(Look)) expected(ed, err, "integer")
# if out->write >= out->length
@ -339,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: 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)
@ -428,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 : exit-descriptor
# . var ed/eax: 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)
@ -470,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 : (addr exit-descriptor), f : fd or (addr stream byte), s : (addr array byte)
expected: # ed: (addr exit-descriptor), f: fd or (addr stream byte), s: (addr array byte)
# . prologue
55/push-ebp
89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp
@ -512,7 +512,7 @@ $expected:dead-end:
c3/return
# read a byte from 'f', and save it in 'Look'
get-char: # f : (addr buffered-file)
get-char: # f: (addr buffered-file)
# . prologue
55/push-ebp
89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp
@ -535,7 +535,7 @@ $get-char:end:
5d/pop-to-ebp
c3/return
is-digit?: # c : int -> eax : boolean
is-digit?: # c: int -> eax: boolean
# . prologue
55/push-ebp
89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp

View File

@ -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: 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 : (addr buffered-file), out : fd or (addr stream byte), err : fd or (addr stream byte), ed : (addr exit-descriptor)
compile: # in: (addr buffered-file), out: fd or (addr stream byte), err: fd or (addr stream byte), ed: (addr 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 : (addr buffered-file), out : fd or (addr stream byte), 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 : (stream byte 7)
# var num/ecx: (stream byte 7)
# Numbers can be 32 bits or 8 hex bytes long. One of them will be in 'Look', so we need space for 7 bytes.
# 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 : (addr buffered-file), out : (addr stream byte), err : fd or (addr stream byte), ed : (addr exit-descriptor)
get-num: # in: (addr buffered-file), out: (addr stream byte), err: fd or (addr stream byte), ed: (addr exit-descriptor)
# pseudocode:
# if (!is-digit?(Look)) expected(ed, err, "integer")
# do
@ -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: 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 : exit-descriptor
# . var ed/eax: 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 : exit-descriptor
# . var ed/eax: 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 : exit-descriptor
# . var ed/eax: 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 : (addr exit-descriptor), f : fd or (addr stream byte), s : (addr array byte)
expected: # ed: (addr exit-descriptor), f: fd or (addr stream byte), s: (addr array byte)
# . prologue
55/push-ebp
89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp
@ -706,7 +706,7 @@ $expected:dead-end:
c3/return
# read a byte from 'f', and save it in 'Look'
get-char: # f : (addr buffered-file)
get-char: # f: (addr buffered-file)
# . prologue
55/push-ebp
89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp
@ -729,7 +729,7 @@ $get-char:end:
5d/pop-to-ebp
c3/return
is-digit?: # c : int -> eax : boolean
is-digit?: # c: int -> eax: boolean
# . prologue
55/push-ebp
89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp

View File

@ -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: 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()
@ -82,10 +82,10 @@ $subx-dquotes-main:end:
# line = words separated by ' ', maybe followed by comment starting with '#'
# word = datum until '/', then 0 or more metadata separated by '/'
subx-dquotes: # in : (addr buffered-file), out : (addr buffered-file)
subx-dquotes: # in: (addr buffered-file), out: (addr buffered-file)
# pseudocode:
# var line : (stream byte 512)
# var new-data-segment : (handle stream byte) = new-stream(Heap, Segment-size, 1)
# var line: (stream byte 512)
# var new-data-segment: (handle stream byte) = new-stream(Heap, Segment-size, 1)
#
# write(new-data-segment, "== data\n")
# # TODO: When it was originally written dquotes ran before assort, so
@ -125,13 +125,13 @@ subx-dquotes: # in : (addr buffered-file), out : (addr buffered-file)
53/push-ebx
56/push-esi
57/push-edi
# var line/ecx : (stream byte 512)
# var line/ecx: (stream byte 512)
81 5/subop/subtract 3/mod/direct 4/rm32/esp . . . . . 0x200/imm32 # subtract from esp
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 : slice
# var word-slice/edx: 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
@ -198,9 +198,9 @@ $subx-dquotes:check1:
0f 85/jump-if-!= $subx-dquotes:next-line/disp32
$subx-dquotes:check-for-comment:
# if (slice-starts-with?(word-slice, "#")) continue
# . var start/esi : (addr byte) = word-slice->start
# . var start/esi: (addr byte) = word-slice->start
8b/copy 0/mod/indirect 2/rm32/edx . . . 6/r32/esi . . # copy *edx to esi
# . var c/eax : byte = *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 (c == '#') continue
@ -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 : (addr slice), out : (addr buffered-file), out-segment : (addr stream byte)
process-string-literal: # string-literal: (addr slice), out: (addr buffered-file), out-segment: (addr 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 : (addr slice), out : (addr buffered-f
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 byte 10) # number of decimal digits a 32-bit number can have
# var int32-stream/ecx: (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 : (addr stream byte), word : (addr slice)
emit-string-literal-data: # out: (addr stream byte), word: (addr 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 : (addr stream byte), word : (addr slice)
56/push-esi
# esi = word
8b/copy 1/mod/*+disp8 5/rm32/ebp . . . 6/r32/esi 0xc/disp8 . # copy *(ebp+12) to esi
# var idx/ebx : int = 0
# var idx/ebx: int = 0
31/xor 3/mod/direct 3/rm32/ebx . . . 3/r32/ebx . . # clear ebx
# var curr/edx : (addr byte) = word->start
# var curr/edx: (addr byte) = word->start
8b/copy 0/mod/indirect 6/rm32/esi . . . 2/r32/edx . . # copy *esi to edx
# var max/esi : (addr byte) = word->end
# var max/esi: (addr 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:
# var len/eax : int = 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
# var c/ecx : byte = 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,7 +955,7 @@ $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}")
# . var eax : boolean = is-alphanumeric?(CL)
# . var eax: boolean = is-alphanumeric?(CL)
# . . push args
51/push-ecx
# . . call
@ -1021,7 +1021,7 @@ $emit-string-literal-data:end:
5d/pop-to-ebp
c3/return
is-alphanumeric?: # c : int -> eax : boolean
is-alphanumeric?: # c: int -> eax: boolean
# . prologue
55/push-ebp
89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp
@ -1379,9 +1379,9 @@ test-emit-string-literal-data-handles-newline-escape:
c3/return
# emit everything from a word except the initial datum
emit-metadata: # out : (addr buffered-file), word : (addr slice)
emit-metadata: # out: (addr buffered-file), word: (addr slice)
# pseudocode
# var slice : slice = {0, word->end}
# var slice: slice = {0, word->end}
# curr = word->start
# if *curr == '"'
# curr = skip-string-in-slice(curr, word->end)
@ -1406,11 +1406,11 @@ emit-metadata: # out : (addr buffered-file), word : (addr slice)
56/push-esi
# esi = word
8b/copy 1/mod/*+disp8 5/rm32/ebp . . . 6/r32/esi 0xc/disp8 . # copy *(ebp+12) to esi
# var curr/ecx : (addr byte) = word->start
# var curr/ecx: (addr byte) = word->start
8b/copy 0/mod/indirect 6/rm32/esi . . . 1/r32/ecx . . # copy *esi to ecx
# var end/edx : (addr byte) = word->end
# var end/edx: (addr byte) = word->end
8b/copy 1/mod/*+disp8 6/rm32/esi . . . 2/r32/edx 4/disp8 . # copy *(esi+4) to edx
# var slice/ebx : slice = {0, end}
# var slice/ebx: 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
@ -1778,7 +1778,7 @@ test-emit-metadata-in-string-literal:
5d/pop-to-ebp
c3/return
string-length-at-start-of-slice: # curr : (addr byte), end : (addr byte) -> length/eax
string-length-at-start-of-slice: # curr: (addr byte), end: (addr byte) -> length/eax
# . prologue
55/push-ebp
89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp
@ -1790,9 +1790,9 @@ string-length-at-start-of-slice: # curr : (addr byte), end : (addr byte) -> len
8b/copy 1/mod/*+disp8 5/rm32/ebp . . 1/r32/ecx 8/disp8 . # copy *(ebp+8) to ecx
# edx = end
8b/copy 1/mod/*+disp8 5/rm32/ebp . . 2/r32/edx 0xc/disp8 . # copy *(ebp+12) to edx
# var length/eax : int = 0
# var length/eax: int = 0
31/xor 3/mod/direct 0/rm32/eax . . . 0/r32/eax . . # clear eax
# var c/ebx : byte = 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

View File

@ -33,7 +33,7 @@ Entry: # return argv-equal(argv[1], argv[2])
# compare two null-terminated ascii strings
# reason for the name: the only place we should have null-terminated ascii strings is from commandline args
argv-equal: # (s1, s2) : null-terminated ascii strings -> eax : boolean
argv-equal: # (s1, s2): null-terminated ascii strings -> eax: boolean
# initialize s1 (ecx) and s2 (edx)
8b/copy 1/mod/*+disp8 4/rm32/sib 4/base/esp 4/index/none . 1/r32/ecx 4/disp8 . # copy *(esp+4) to ecx
8b/copy 1/mod/*+disp8 4/rm32/sib 4/base/esp 4/index/none . 2/r32/edx 8/disp8 . # copy *(esp+8) to edx

View File

@ -27,7 +27,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: null-terminated ascii string, benchmark: length-prefixed ascii string -> eax: boolean
# pseudocode:
# n = benchmark->length
# s1 = s
@ -258,7 +258,7 @@ test-compare-kernel-string-with-longer-array:
# - helpers
# print msg to stderr if a != b, otherwise print "."
check-ints-equal: # (a : int, b : int, msg : (addr array byte)) -> boolean
check-ints-equal: # (a: int, b: int, msg: (addr array byte)) -> boolean
# . prologue
55/push-ebp
89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp
@ -307,7 +307,7 @@ $check-ints-equal:end:
5d/pop-to-ebp
c3/return
write-stderr: # s : (addr array byte) -> <void>
write-stderr: # s: (addr array byte) -> <void>
# . prologue
55/push-ebp
89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp

View File

@ -34,7 +34,7 @@ Entry:
89/copy 3/mod/direct 3/rm32/ebx . . . 0/r32/eax . . # copy eax to ebx
e8/call syscall_exit/disp32
ascii-length: # s : (addr array byte) -> n/eax
ascii-length: # s: (addr array byte) -> n/eax
# edx = s
8b/copy 1/mod/*+disp8 4/rm32/sib 4/base/esp 4/index/none . 2/r32/edx 4/disp8 . # copy *(esp+4) to edx
# var result/eax = 0

View File

@ -38,7 +38,7 @@ Entry:
89/copy 3/mod/direct 3/rm32/ebx . . . 0/r32/eax . . # copy eax to ebx
e8/call syscall_exit/disp32
ascii-difference: # (s1, s2) : null-terminated ascii strings
ascii-difference: # (s1, s2): null-terminated ascii strings
# a = first letter of s1 (ecx)
8b/copy 1/mod/*+disp8 4/rm32/sib 4/base/esp 4/index/none 0/r32/eax 4/disp8 . # copy *(esp+4) to eax
8b/copy 0/mod/indirect 0/rm32/eax . . . 0/r32/eax . . # copy *eax to eax

View File

@ -68,7 +68,7 @@ $main:end:
b8/copy-to-eax 1/imm32/exit
cd/syscall 0x80/imm8
factorial: # n : int -> int/eax
factorial: # n: int -> int/eax
# . prologue
55/push-ebp
89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp
@ -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
# var ebx : int = 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
# var eax : int = factorial(n-1)
# var eax: int = factorial(n-1)
# . . push args
53/push-ebx
# . . call

View File

@ -68,7 +68,7 @@ $main:end:
b8/copy-to-eax 1/imm32/exit
cd/syscall 0x80/imm8
factorial: # n : int -> int/eax
factorial: # n: int -> int/eax
# . prologue
55/push-ebp
89/<- %ebp 4/r32/esp
@ -77,10 +77,10 @@ factorial: # n : int -> int/eax
b8/copy-to-eax 1/imm32
81 7/subop/compare *(ebp+8) 1/imm32
7e/jump-if-<= $factorial:end/disp8
# var ebx : int = n-1
# var ebx: int = n-1
8b/-> *(ebp+8) 3/r32/ebx
4b/decrement-ebx
# var eax : int = factorial(n-1)
# var eax: int = factorial(n-1)
# . . push args
53/push-ebx
# . . call

View File

@ -49,7 +49,7 @@ $main:end:
b8/copy-to-eax 1/imm32/exit
cd/syscall 0x80/imm8
factorial: # n : int -> int/eax
factorial: # n: int -> int/eax
# . prologue
55/push-ebp
89/<- %ebp 4/r32/esp
@ -59,7 +59,7 @@ factorial: # n : int -> int/eax
b8/copy-to-eax 1/imm32
81 7/subop/compare *(ebp+8) 1/imm32
7e/jump-if-<= $factorial:end/disp8
# var ebx : int = n-1
# var ebx: int = n-1
8b/-> *(ebp+8) 3/r32/ebx
4b/decrement-ebx
#

View File

@ -55,7 +55,7 @@ Entry: # run tests if necessary, compute `factorial(5)` if not
b8/copy-to-eax 1/imm32/exit
cd/syscall 0x80/imm8
factorial: # n : int -> int/eax
factorial: # n: int -> int/eax
# . prologue
55/push-ebp
89/<- %ebp 4/r32/esp
@ -70,7 +70,7 @@ factorial: # n : int -> int/eax
# if (n > 1) return n * factorial(n-1)
{
7e/jump-if-<= break/disp8
# var ebx : int = n-1
# var ebx: int = n-1
8b/-> *(ebp+8) 3/r32/ebx
4b/decrement-ebx
(factorial %ebx) # => eax

View File

@ -44,7 +44,7 @@ $handle-main:end:
b8/copy-to-eax 1/imm32/exit
cd/syscall 0x80/imm8
new: # ad : (addr allocation-descriptor), n : int, out : (handle _)
new: # ad: (addr 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 : (addr allocation-descriptor), n : int, out : (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
# var eax : (handle _) = 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 : allocation-descriptor
# var heap/edx: 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 : handle
# var handle/ecx: 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 : allocation-descriptor = {0x10, 0x10}
# . var ad/eax: 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
@ -221,7 +221,7 @@ _pending-test-new-failure:
5d/pop-to-ebp
c3/return
lookup: # h : (handle T) -> eax : (addr T)
lookup: # h: (handle T) -> eax: (addr T)
# . prologue
55/push-ebp
89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp
@ -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 : allocation-descriptor
# var heap/ebx: 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 : handle
# var handle/ecx: 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 : allocation-descriptor
# var heap/esi: 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 : handle
# var h1/ecx: 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 : handle
# var h2/edx: 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

View File

@ -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: 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()
@ -77,7 +77,7 @@ $subx-hex-main:end:
cd/syscall 0x80/imm8
# the main entry point
subx-hex: # in : (addr buffered-file), out : (addr buffered-file), err : (addr buffered-file), ed : (addr exit-descriptor)
subx-hex: # in: (addr buffered-file), out: (addr buffered-file), err: (addr buffered-file), ed: (addr exit-descriptor)
# pseudocode:
# while true
# eax = convert-next-octet(in, err, ed)
@ -135,7 +135,7 @@ $subx-hex:end:
# raise an error and abort on all other unexpected bytes
# return in eax an _octet_ containing the binary value of the two hex characters
# return Eof on reaching end of file
convert-next-octet: # in : (addr buffered-file), err : (addr buffered-file), ed : (addr exit-descriptor) -> byte-or-Eof/eax
convert-next-octet: # in: (addr buffered-file), err: (addr buffered-file), ed: (addr exit-descriptor) -> byte-or-Eof/eax
# pseudocode:
# eax = scan-next-byte(in, err, ed)
# if (eax == Eof) return
@ -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: 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: 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: 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)
@ -481,7 +481,7 @@ $test-convert-next-octet-aborts-on-single-hex-byte:end:
# return Eof if file ends without finding a hex byte
# on '#' skip all bytes until newline
# abort on any other byte
scan-next-byte: # in : (addr buffered-file), err : (addr buffered-file), ed : (addr exit-descriptor) -> byte-or-Eof/eax
scan-next-byte: # in: (addr buffered-file), err: (addr buffered-file), ed: (addr exit-descriptor) -> byte-or-Eof/eax
# pseudocode:
# while true
# eax = read-byte-buffered(in)
@ -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: 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: 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: 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: 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: 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: 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: 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: 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)
@ -1350,7 +1350,7 @@ $test-scan-next-byte-aborts-on-invalid-byte:end:
5d/pop-to-ebp
c3/return
skip-until-newline: # in : (addr buffered-file)
skip-until-newline: # in: (addr buffered-file)
# pseudocode:
# push eax
# while true

BIN
apps/mu

Binary file not shown.

File diff suppressed because it is too large Load Diff

View File

@ -74,19 +74,19 @@ $main:end:
# data contains a pointer to an array of 8-byte data fields and the common
# tag for them all
repl: # in : (addr buffered-file), out : (addr buffered-file)
repl: # in: (addr buffered-file), out: (addr buffered-file)
# . prologue
55/push-ebp
89/<- %ebp 4/r32/esp
# . save registers
50/push-eax
{
(lisp-read Stdin) # => eax : (handle cell)
(lisp-read Stdin) # => eax: (handle cell)
# if (eax == 0) break
3d/compare-eax-and 0/imm32
74/jump-if-= break/disp8
#
(lisp-eval %eax) # => eax : (handle 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 : (addr buffered-file) -> eax : (handle cell)
lisp-read: # in: (addr 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: (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 : (addr buffered-file) -> (handle cell)
# lisp-read: in: (addr 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 : (addr buffered-file), line : (addr stream byte), result : (addr slice)
next-mulisp-token: # in: (addr buffered-file), line: (addr stream byte), result: (addr 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 : (addr slice) -> eax : (handle cell)
new-int-cell: # in: (addr slice) -> eax: (handle cell)
new-string-cell: # in : (addr slice) -> eax : (handle cell)
new-string-cell: # in: (addr slice) -> eax: (handle cell)
lisp-eval: # in : (addr cell) -> eax : (handle cell)
lisp-eval: # in: (addr cell) -> eax: (handle cell)
# . prologue
55/push-ebp
89/<- %ebp 4/r32/esp
@ -211,7 +211,7 @@ $lisp-eval:end:
5d/pop-to-ebp
c3/return
lisp-print: # out : (addr buffered-file), x : (addr cell)
lisp-print: # out: (addr buffered-file), x: (addr cell)
# . prologue
55/push-ebp
89/<- %ebp 4/r32/esp

View File

@ -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: 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,9 +97,9 @@ $subx-pack-main:end:
# next-token-from-slice(start, end, delim char) -> slice
# slice-equal?(slice, string)
subx-pack: # in : (addr buffered-file), out : (addr buffered-file)
subx-pack: # in: (addr buffered-file), out: (addr buffered-file)
# pseudocode:
# var line : (stream byte 512)
# var line: (stream byte 512)
# var in-code? = false
# while true
# clear-stream(line)
@ -128,17 +128,17 @@ subx-pack: # in : (addr buffered-file), out : (addr buffered-file)
51/push-ecx
52/push-edx
53/push-ebx
# var line/ecx : (stream byte 512)
# var line/ecx: (stream byte 512)
81 5/subop/subtract 3/mod/direct 4/rm32/esp . . . . . 0x200/imm32 # subtract from esp
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 : slice
# var word-slice/edx: 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 : boolean = 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)
@ -909,9 +909,9 @@ test-subx-pack-code-and-data-segments:
5d/pop-to-ebp
c3/return
convert-data: # line : (addr stream byte), out : (addr buffered-file)
convert-data: # line: (addr stream byte), out: (addr buffered-file)
# pseudocode:
# var word-slice : slice
# var word-slice: 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 : (addr stream byte), out : (addr buffered-file)
50/push-eax
51/push-ecx
52/push-edx
# var word-slice/ecx : slice
# var word-slice/ecx: 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
@ -1029,9 +1029,9 @@ $convert-data:check0:
0f 85/jump-if-!= $convert-data:break/disp32
$convert-data:check-for-comment:
# if (slice-starts-with?(word-slice, "#"))
# . var start/edx : (addr byte) = word-slice->start
# . var start/edx: (addr byte) = word-slice->start
8b/copy 0/mod/indirect 1/rm32/ecx . . . 2/r32/edx . . # copy *ecx to edx
# . var c/eax : byte = *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 (c != '#') goto next check
@ -1050,9 +1050,9 @@ $convert-data:comment:
0f 85/jump-if-!= $convert-data:end/disp32
$convert-data:check-for-label:
# if (slice-ends-with?(word-slice, ":"))
# . var end/edx : (addr byte) = word-slice->end
# . var end/edx: (addr byte) = word-slice->end
8b/copy 1/mod/*+disp8 1/rm32/ecx . . . 2/r32/edx 4/disp8 . # copy *(ecx+4) to edx
# . var c/eax : byte = *(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 (c != ':') goto next check
@ -1809,7 +1809,7 @@ test-convert-data-trailing-comment:
# unceremoniously abort on non-numeric operands except disp or imm
# opcodes must be lowercase and zero padded
# opcodes with misleading operand metadata may get duplicated as operands as well. don't rely on this.
convert-instruction: # line : (addr stream byte), out : (addr buffered-file)
convert-instruction: # line: (addr stream byte), out: (addr buffered-file)
# pseudocode:
# # some early exits
# var word-slice = next-word(line)
@ -1837,7 +1837,7 @@ convert-instruction: # line : (addr stream byte), out : (addr buffered-file)
50/push-eax
51/push-ecx
52/push-edx
# var word-slice/ecx : slice
# var word-slice/ecx: 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
@ -1863,9 +1863,9 @@ $convert-instruction:check0:
75/jump-if-!= $convert-instruction:pass-through/disp8
$convert-instruction:check1:
# if (slice-starts-with?(word-slice, "#")) write-stream-data(out, line)
# . var start/edx : (addr byte) = word-slice->start
# . var start/edx: (addr byte) = word-slice->start
8b/copy 0/mod/indirect 1/rm32/ecx . . . 2/r32/edx . . # copy *ecx to edx
# . var c/eax : byte = *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 (c == '#') pass through
@ -1873,9 +1873,9 @@ $convert-instruction:check1:
74/jump-if-= $convert-instruction:pass-through/disp8
$convert-instruction:check2:
# if (slice-ends-with?(word-slice, ":")) write-stream-data(out, line)
# . var end/edx : (addr byte) = word-slice->end
# . var end/edx: (addr byte) = word-slice->end
8b/copy 1/mod/*+disp8 1/rm32/ecx . . . 2/r32/edx 4/disp8 . # copy *(ecx+4) to edx
# . var c/eax : byte = *(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 (c == ':') pass through
@ -1953,7 +1953,7 @@ $convert-instruction:end:
5d/pop-to-ebp
c3/return
emit-opcodes: # line : (addr stream byte), out : (addr buffered-file)
emit-opcodes: # line: (addr stream byte), out: (addr buffered-file)
# opcodes occupy 1-3 bytes:
# xx
# 0f xx
@ -1994,11 +1994,11 @@ emit-opcodes: # line : (addr stream byte), out : (addr buffered-file)
51/push-ecx
52/push-edx
53/push-ebx
# var op1/ecx : slice
# var op1/ecx: 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 : slice
# var op2/edx: 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
@ -2030,9 +2030,9 @@ $emit-opcodes:op1:
3d/compare-eax-and 0/imm32/false
0f 85/jump-if-!= $emit-opcodes:end/disp32
# if (slice-starts-with?(op1, "#")) return
# . var start/ebx : (addr byte) = op1->start
# . var start/ebx: (addr byte) = op1->start
8b/copy 0/mod/indirect 1/rm32/ecx . . . 3/r32/ebx . . # copy *ecx to ebx
# . var c/eax : byte = *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 (c == '#') return
@ -2123,9 +2123,9 @@ $emit-opcodes:op2:
3d/compare-eax-and 0/imm32/false
0f 85/jump-if-!= $emit-opcodes:end/disp32
# if (slice-starts-with?(op2, "#")) return
# . var start/ebx : (addr byte) = op2->start
# . var start/ebx: (addr byte) = op2->start
8b/copy 0/mod/indirect 2/rm32/edx . . . 3/r32/ebx . . # copy *edx to ebx
# . var c/eax : byte = *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 (c == '#') return
@ -2202,9 +2202,9 @@ $emit-opcodes:op3:
3d/compare-eax-and 0/imm32/false
0f 85/jump-if-!= $emit-opcodes:end/disp32
# if (slice-starts-with?(op3, "#")) return
# . var start/ebx : (addr byte) = op2->start
# . var start/ebx: (addr byte) = op2->start
8b/copy 0/mod/indirect 2/rm32/edx . . . 3/r32/ebx . . # copy *edx to ebx
# . var c/eax : byte = *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 (c == '#') return
@ -2249,11 +2249,11 @@ $emit-opcodes:end:
5d/pop-to-ebp
c3/return
emit-modrm: # line : (addr stream byte), out : (addr buffered-file)
emit-modrm: # line: (addr stream byte), out: (addr buffered-file)
# pseudocode:
# rewind-stream(line)
# var has-modrm? = false, mod = 0, rm32 = 0, r32 = 0
# var word-slice : slice
# var word-slice: slice
# while true
# word-slice = next-word(line)
# if (slice-empty?(word-slice)) break
@ -2285,17 +2285,17 @@ emit-modrm: # line : (addr stream byte), out : (addr buffered-file)
53/push-ebx
56/push-esi
57/push-edi
# var word-slice/ecx : slice
# var word-slice/ecx: 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 : boolean = false
# var has-modrm?/edx: boolean = false
31/xor 3/mod/direct 2/rm32/edx . . . 2/r32/edx . . # clear edx
# var mod/ebx : byte = 0
# var mod/ebx: byte = 0
31/xor 3/mod/direct 3/rm32/ebx . . . 3/r32/ebx . . # clear ebx
# var rm32/esi : byte = 0
# var rm32/esi: byte = 0
31/xor 3/mod/direct 6/rm32/esi . . . 6/r32/esi . . # clear esi
# var r32/edi : byte = 0
# var r32/edi: byte = 0
31/xor 3/mod/direct 7/rm32/edi . . . 7/r32/edi . . # clear edi
# rewind-stream(line)
# . . push args
@ -2402,9 +2402,9 @@ $emit-modrm:check1:
# if (slice-starts-with?(word-slice, "#")) break
# . spill edx
52/push-edx
# . var start/edx : (addr byte) = word-slice->start
# . var start/edx: (addr byte) = word-slice->start
8b/copy 0/mod/indirect 1/rm32/ecx . . . 2/r32/edx . . # copy *ecx to edx
# . var c/eax : byte = *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
@ -2529,7 +2529,7 @@ $emit-modrm:break:
81 7/subop/compare 3/mod/direct 2/rm32/edx . . . . . 0/imm32/false # compare edx
74/jump-if-= $emit-modrm:end/disp8
$emit-modrm:calculate:
# var modrm/ebx : byte = 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
@ -2566,10 +2566,10 @@ $emit-modrm:end:
5d/pop-to-ebp
c3/return
emit-sib: # line : (addr stream byte), out : (addr buffered-file)
emit-sib: # line: (addr stream byte), out: (addr buffered-file)
# pseudocode:
# var has-sib? = false, base = 0, index = 0, scale = 0
# var word-slice : slice
# var word-slice: slice
# while true
# word-slice = next-word(line)
# if (slice-empty?(word-slice)) break
@ -2601,17 +2601,17 @@ emit-sib: # line : (addr stream byte), out : (addr buffered-file)
53/push-ebx
56/push-esi
57/push-edi
# var word-slice/ecx : slice
# var word-slice/ecx: 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 : boolean = false
# var has-sib?/edx: boolean = false
31/xor 3/mod/direct 2/rm32/edx . . . 2/r32/edx . . # clear edx
# var scale/ebx : byte = 0
# var scale/ebx: byte = 0
31/xor 3/mod/direct 3/rm32/ebx . . . 3/r32/ebx . . # clear ebx
# var base/esi : byte = 0
# var base/esi: byte = 0
31/xor 3/mod/direct 6/rm32/esi . . . 6/r32/esi . . # clear esi
# var index/edi : byte = 0
# var index/edi: byte = 0
31/xor 3/mod/direct 7/rm32/edi . . . 7/r32/edi . . # clear edi
# rewind-stream(line)
# . . push args
@ -2711,9 +2711,9 @@ $emit-sib:check1:
# if (slice-starts-with?(word-slice, "#")) break
# . spill edx
52/push-edx
# . var start/edx : (addr byte) = word-slice->start
# . var start/edx: (addr byte) = word-slice->start
8b/copy 0/mod/indirect 1/rm32/ecx . . . 2/r32/edx . . # copy *ecx to edx
# . var c/eax : byte = *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
@ -2810,7 +2810,7 @@ $emit-sib:break:
81 7/subop/compare 3/mod/direct 2/rm32/edx . . . . . 0/imm32/false # compare edx
74/jump-if-= $emit-sib:end/disp8
$emit-sib:calculate:
# var sib/ebx : byte = 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
@ -2847,10 +2847,10 @@ $emit-sib:end:
5d/pop-to-ebp
c3/return
emit-disp: # line : (addr stream byte), out : (addr buffered-file)
emit-disp: # line: (addr stream byte), out: (addr buffered-file)
# pseudocode:
# rewind-stream(line)
# var word-slice : slice
# var word-slice: slice
# while true
# word-slice = next-word(line)
# if (slice-empty?(word-slice)) break
@ -2872,7 +2872,7 @@ emit-disp: # line : (addr stream byte), out : (addr buffered-file)
50/push-eax
51/push-ecx
52/push-edx
# var word-slice/ecx : slice
# var word-slice/ecx: 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
@ -2972,9 +2972,9 @@ $emit-disp:check0:
0f 85/jump-if-!= $emit-disp:break/disp32
$emit-disp:check1:
# if (slice-starts-with?(word-slice, "#")) break
# . var start/edx : (addr byte) = word-slice->start
# . var start/edx: (addr byte) = word-slice->start
8b/copy 0/mod/indirect 1/rm32/ecx . . . 2/r32/edx . . # copy *ecx to edx
# . var c/eax : byte = *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 (c == '#') break
@ -3066,10 +3066,10 @@ $emit-disp:break:
5d/pop-to-ebp
c3/return
emit-imm: # line : (addr stream byte), out : (addr buffered-file)
emit-imm: # line: (addr stream byte), out: (addr buffered-file)
# pseudocode:
# rewind-stream(line)
# var word-slice : slice
# var word-slice: slice
# while true
# word-slice = next-word(line)
# if (slice-empty?(word-slice)) break
@ -3091,7 +3091,7 @@ emit-imm: # line : (addr stream byte), out : (addr buffered-file)
50/push-eax
51/push-ecx
52/push-edx
# var word-slice/ecx : slice
# var word-slice/ecx: 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
@ -3191,9 +3191,9 @@ $emit-imm:check0:
0f 85/jump-if-!= $emit-imm:break/disp32
$emit-imm:check1:
# if (slice-starts-with?(word-slice, "#")) break
# . var start/edx : (addr byte) = slice->start
# . var start/edx: (addr byte) = slice->start
8b/copy 0/mod/indirect 1/rm32/ecx . . . 2/r32/edx . . # copy *ecx to edx
# . var c/eax : byte = *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 (c == '#') break
@ -3285,7 +3285,7 @@ $emit-imm:break:
5d/pop-to-ebp
c3/return
emit-line-in-comment: # line : (addr stream byte), out : (addr buffered-file)
emit-line-in-comment: # line: (addr stream byte), out: (addr buffered-file)
# . prologue
55/push-ebp
89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp
@ -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 : (addr slice) -> value/eax : int
parse-datum-of-word: # word: (addr 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 : (addr slice) -> value/eax : int
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 : slice
# var slice/ecx: 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

View File

@ -104,9 +104,9 @@ $subx-sigils-main:end:
# error messages considered:
# *x + 34 -> error: base+disp addressing must be within '()'
subx-sigils: # in : (addr buffered-file), out : (addr buffered-file)
subx-sigils: # in: (addr buffered-file), out: (addr buffered-file)
# pseudocode:
# var line : (stream byte 512)
# var line: (stream byte 512)
# while true
# clear-stream(line)
# read-line-buffered(in, line)
@ -141,13 +141,13 @@ subx-sigils: # in : (addr buffered-file), out : (addr buffered-file)
51/push-ecx
52/push-edx
53/push-ebx
# var line/ecx : (stream byte 512)
# var line/ecx: (stream byte 512)
81 5/subop/subtract 3/mod/direct 4/rm32/esp . . . . . 0x200/imm32 # subtract from esp
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 : slice
# var word-slice/edx: 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
@ -1359,13 +1359,13 @@ test-subx-sigils-indirect-mode-without-register:
5d/pop-to-ebp
c3/return
emit-direct-mode: # out : (addr buffered-file), word-slice : (addr slice)
emit-direct-mode: # out: (addr buffered-file), word-slice: (addr slice)
# . prologue
55/push-ebp
89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp
# . save registers
50/push-eax
# var local-slice/eax : slice = {word-slice->start, word-slice->end}
# var local-slice/eax: 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
@ -1599,7 +1599,7 @@ test-emit-direct-mode-2:
# error messages considered:
# * ... -> error: no space after '*'
# *(... -> error: *(...) expression must be all on a single line
next-word-or-expression: # line : (addr stream byte), out : (addr slice)
next-word-or-expression: # line: (addr stream byte), out: (addr slice)
# pseudocode:
# skip-chars-matching(line, ' ')
# if line->read >= line->write # end of line
@ -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 : slice
# var slice/ecx: 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 : slice
# var slice/ecx: 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 : slice
# var slice/ecx: 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 : slice
# var slice/ecx: 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 : slice
# var slice/ecx: 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 : slice
# var slice/ecx: 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
@ -2207,7 +2207,7 @@ test-next-word-or-expression-returns-whole-expression:
# *(reg1+reg2<<s+disp) -> 2/mod 4/rm32 reg1/base reg2/index s/scale disp/disp32
# Intermediate structure: base, index, scale, disp
# Default values: base: 0, index: 4 (none), scale: 0, disp: 0
parse-effective-address: # word-slice : (addr slice) -> base/eax, index/ecx, scale/edx, disp/ebx
parse-effective-address: # word-slice: (addr slice) -> base/eax, index/ecx, scale/edx, disp/ebx
# pseudocode:
# var local-slice = {word-slice->start, word-slice->end}
# ++local-slice->start to skip '*'
@ -2250,7 +2250,7 @@ parse-effective-address: # word-slice : (addr slice) -> base/eax, index/ecx, sc
# . save registers
56/push-esi
57/push-edi
# var local-slice/esi : slice = {word-slice->start, word-slice->end}
# var local-slice/esi: 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
@ -2670,7 +2670,7 @@ $parse-effective-address:error4:
# assumes 'in' starts with a register name, and returns pointer to its code
# side-effect: modifies 'in' to scan past the initial register name
next-register: # in : (addr slice) -> reg/eax : int
next-register: # in: (addr slice) -> reg/eax: int
# . prologue
55/push-ebp
89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp
@ -2679,7 +2679,7 @@ next-register: # in : (addr 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 : slice = {in->start, in->start + 3}
# var reg-slice/ecx: 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
@ -3149,7 +3149,7 @@ test-parse-effective-address-base-index-scale-displacement:
# if index is none, then mod = 2 and rm32 = base and disp32 = disp
# emit-sib:
# if index is not none, then mod = 2 and rm32 = 4 and base = base and index = index and disp32 = disp
emit-indirect-mode: # out : (addr buffered-file), base : int, index : int, scale : int, disp : int
emit-indirect-mode: # out: (addr buffered-file), base: int, index: int, scale: int, disp: int
# . prologue
55/push-ebp
89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp
@ -3858,14 +3858,14 @@ test-emit-indirect-mode-esp:
5d/pop-to-ebp
c3/return
disp32-mode?: # in : (addr slice) -> reg/eax : boolean
disp32-mode?: # in: (addr slice) -> reg/eax: boolean
# . prologue
55/push-ebp
89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp
# . save registers
56/push-esi
57/push-edi
# var local-slice/esi : slice = {in->start, in->end}
# var local-slice/esi: 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
@ -3917,13 +3917,13 @@ $disp32-mode?:end:
5d/pop-to-ebp
c3/return
emit-indirect-disp32: # out : (addr buffered-file), word-slice : (addr slice)
emit-indirect-disp32: # out: (addr buffered-file), word-slice: (addr slice)
# . prologue
55/push-ebp
89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp
# . save registers
56/push-esi
# var local-slice/esi : slice = {in->start, in->end}
# var local-slice/esi: 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
@ -3967,7 +3967,7 @@ $emit-indirect-disp32:end:
# assumes 'in' starts with optional '+' or '-', optional whitespace, and an unsigned integer
# returns the value of the integer
# side-effect: modifies 'in' to skip past the integer
next-hex-int: # in : (addr slice) -> result/eax
next-hex-int: # in: (addr slice) -> result/eax
# . prologue
55/push-ebp
89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp
@ -4382,7 +4382,7 @@ test-next-hex-int-negative-with-space:
# assumes 'in' starts a positive unsigned integer
# returns the value of the integer
# side-effect: modifies 'in' to skip past the integer
next-positive-hex-int: # in : (addr slice) -> result/eax
next-positive-hex-int: # in: (addr slice) -> result/eax
# . prologue
55/push-ebp
89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp

View File

@ -113,12 +113,12 @@ $subx-survey-main:end:
# labels: (addr stream {string, label-info}) (16 bytes per row)
# these are all inefficient; use sequential scans for lookups
subx-survey: # infile : (addr buffered-file), out : (addr buffered-file)
subx-survey: # infile: (addr buffered-file), out: (addr buffered-file)
# pseudocode
# var in : (stream byte 4096)
# var in: (stream byte 4096)
# slurp(infile, in)
# var segments : (stream segment-info)
# var labels : (stream label-info Max-labels)
# var segments: (stream segment-info)
# var labels: (stream label-info Max-labels)
# compute-offsets(in, segments, labels)
# compute-addresses(segments, labels)
# rewind-stream(in)
@ -131,13 +131,13 @@ subx-survey: # infile : (addr buffered-file), out : (addr buffered-file)
51/push-ecx
52/push-edx
56/push-esi
# var segments/ecx : (stream {string, segment-info} 160) # 10 rows * 16 bytes/row
# var segments/ecx: (stream {string, segment-info} 160) # 10 rows * 16 bytes/row
81 5/subop/subtract 3/mod/direct 4/rm32/esp . . . . . 0xa0/imm32 # subtract from esp
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 label-info Max-labels*16)
# var labels/edx: (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 : (addr buffered-file), out : (addr 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 byte Input-size)
# var in/esi: (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 : (addr stream byte), segments : (addr stream {string, segment-info}), labels : (addr stream {string, label-info})
compute-offsets: # in: (addr stream byte), segments: (addr stream {string, segment-info}), labels: (addr stream {string, label-info})
# skeleton:
# for lines in 'in'
# for words in line
@ -629,8 +629,8 @@ compute-offsets: # in : (addr stream byte), segments : (addr stream {string, se
# default
#
# pseudocode:
# curr-segment-name : (addr string) = 0
# var line : (stream byte 512)
# curr-segment-name: (addr string) = 0
# var line: (stream byte 512)
# while true # line loop
# clear-stream(line)
# read-line(in, line)
@ -661,7 +661,7 @@ compute-offsets: # in : (addr stream byte), segments : (addr stream {string, se
# break (next line)
# else if is-label?(word-slice)
# strip trailing ':' from word-slice
# x : (addr label-info) = get-or-insert(labels, name)
# x: (addr label-info) = get-or-insert(labels, name)
# x->segment-name = curr-segment-name
# trace("label '", word-slice, "' is in segment '", curr-segment-name, "'.")
# x->segment-offset = segment-offset
@ -688,7 +688,7 @@ compute-offsets: # in : (addr stream byte), segments : (addr stream {string, se
c7 0/subop/copy 0/mod/indirect 5/rm32/.disp32 . . . compute-offsets:file-offset/disp32 0/imm32 # copy to *compute-offsets:word-slice
# segment-offset = 0
c7 0/subop/copy 0/mod/indirect 5/rm32/.disp32 . . . compute-offsets:segment-offset/disp32 0/imm32 # copy to *compute-offsets:word-slice
# var line/ecx : (stream byte 512)
# var line/ecx: (stream byte 512)
81 5/subop/subtract 3/mod/direct 4/rm32/esp . . . . . 0x200/imm32 # subtract from esp
68/push 0x200/imm32/length
68/push 0/imm32/read
@ -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 byte 2*16)
# var segments/ecx: (stream byte 2*16)
81 5/subop/subtract 3/mod/direct 4/rm32/esp . . . . . 0x20/imm32 # subtract from esp
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 byte 2*16)
# var labels/edx: (stream byte 2*16)
81 5/subop/subtract 3/mod/direct 4/rm32/esp . . . . . 0x20/imm32 # subtract from esp
68/push 0x20/imm32/length
68/push 0/imm32/read
@ -1378,9 +1378,9 @@ test-compute-offsets:
5d/pop-to-ebp
c3/return
compute-addresses: # segments : (addr stream {string, segment-info}), labels : (addr stream {string, label-info})
compute-addresses: # segments: (addr stream {string, segment-info}), labels: (addr stream {string, label-info})
# pseudocode:
# srow : (addr segment-info) = segments->data
# srow: (addr segment-info) = segments->data
# max = &segments->data[segments->write]
# num-segments = segments->write / 16
# starting-offset = 0x34 + (num-segments * 0x20)
@ -1391,12 +1391,12 @@ compute-addresses: # segments : (addr stream {string, segment-info}), labels :
# s->address += (s->file-offset & 0x00000fff)
# trace-sssns("segment " s->key " starts at address " s->address)
# srow += 16 # row-size
# lrow : (addr label-info) = labels->data
# lrow: (addr label-info) = labels->data
# max = &labels->data[labels->write]
# while true
# if (lrow >= max) break
# seg-name : (addr string) = lrow->segment-name
# label-seg : (addr segment-info) = get(segments, seg-name)
# var seg-name: (addr string) = lrow->segment-name
# var label-seg: (addr segment-info) = get(segments, seg-name)
# lrow->address = label-seg->address + lrow->segment-offset
# trace-sssns("label " lrow->key " is at address " lrow->address)
# lrow += 16 # row-size
@ -1522,7 +1522,7 @@ $compute-addresses:label-loop:
#? # . . discard args
#? 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp
#? # }}}
# seg-name/edx = lrow->segment-name
# var seg-name/edx: (addr array byte) = lrow->segment-name
8b/copy 1/mod/*+disp8 0/rm32/eax . . . 2/r32/edx 4/disp8 . # copy *eax to edx
#? # dump seg-name {{{
#? # . write(2/stderr, "compute-addresses: seg-name: ")
@ -1550,7 +1550,7 @@ $compute-addresses:label-loop:
#? # . . discard args
#? 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp
#? # }}}
# label-seg/edx : (addr segment-info) = get(segments, seg-name, row-size=16, "segment table")
# var label-seg/edx: (addr segment-info) = get(segments, seg-name, row-size=16, "segment table")
# . save eax
50/push-eax
# . eax = get(segments, seg-name, row-size=16)
@ -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 byte 10*16)
# . var segments/ecx: (stream byte 10*16)
81 5/subop/subtract 3/mod/direct 4/rm32/esp . . . . . 0xa0/imm32 # subtract from esp
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 byte 512*16)
# . var labels/edx: (stream byte 512*16)
81 5/subop/subtract 3/mod/direct 4/rm32/esp . . . . . 0x2000/imm32 # subtract from esp
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 byte 10*16)
# . var segments/ecx: (stream byte 10*16)
81 5/subop/subtract 3/mod/direct 4/rm32/esp . . . . . 0xa0/imm32 # subtract from esp
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 byte 512*16)
# . var labels/edx: (stream byte 512*16)
81 5/subop/subtract 3/mod/direct 4/rm32/esp . . . . . 0x2000/imm32 # subtract from esp
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 : (addr stream byte), out : (addr buffered-file), segments : (addr stream {string, segment-info}), labels : (addr stream {string, label-info})
emit-output: # in: (addr stream byte), out: (addr buffered-file), segments: (addr stream {string, segment-info}), labels: (addr stream {string, label-info})
# pseudocode:
# emit-headers(out, segments, labels)
# emit-segments(in, out, segments, labels)
@ -1922,10 +1922,10 @@ $emit-output:end:
5d/pop-to-ebp
c3/return
emit-segments: # in : (addr stream byte), out : (addr buffered-file), segments : (addr stream {string, segment-info}), labels : (addr stream {string, label-info})
emit-segments: # in: (addr stream byte), out: (addr buffered-file), segments: (addr stream {string, segment-info}), labels: (addr stream {string, label-info})
# pseudocode:
# var offset-of-next-instruction = 0
# var line : (stream byte 512)
# var line: (stream byte 512)
# line-loop:
# while true
# clear-stream(line)
@ -1987,17 +1987,17 @@ emit-segments: # in : (addr stream byte), out : (addr buffered-file), segments
53/push-ebx
56/push-esi
57/push-edi
# var line/ecx : (stream byte 512)
# var line/ecx: (stream byte 512)
81 5/subop/subtract 3/mod/direct 4/rm32/esp . . . . . 0x200/imm32 # subtract from esp
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 : slice
# var word-slice/edx: 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 : slice
# var datum/edi: slice
68/push 0/imm32/end
68/push 0/imm32/start
89/copy 3/mod/direct 7/rm32/edi . . . 4/r32/esp . . # copy esp to edi
@ -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 byte 10*16)
# . var segments/ecx: (stream byte 10*16)
81 5/subop/subtract 3/mod/direct 4/rm32/esp . . . . . 0xa0/imm32 # subtract from esp
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 byte 512*16)
# . var labels/edx: (stream byte 512*16)
81 5/subop/subtract 3/mod/direct 4/rm32/esp . . . . . 0x2000/imm32 # subtract from esp
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 byte 10*16)
# . var segments/ecx: (stream byte 10*16)
81 5/subop/subtract 3/mod/direct 4/rm32/esp . . . . . 0xa0/imm32 # subtract from esp
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 byte 512*16)
# . var labels/edx: (stream byte 512*16)
81 5/subop/subtract 3/mod/direct 4/rm32/esp . . . . . 0x2000/imm32 # subtract from esp
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 byte 10*16)
# . var segments/ecx: (stream byte 10*16)
81 5/subop/subtract 3/mod/direct 4/rm32/esp . . . . . 0xa0/imm32 # subtract from esp
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 byte 512*16)
# . var labels/edx: (stream byte 512*16)
81 5/subop/subtract 3/mod/direct 4/rm32/esp . . . . . 0x2000/imm32 # subtract from esp
68/push 0x2000/imm32/length
68/push 0/imm32/read
@ -3173,7 +3173,7 @@ test-emit-segments-code-label-absolute:
5d/pop-to-ebp
c3/return
emit-headers: # out : (addr buffered-file), segments : (addr stream {string, segment-info}), labels : (addr stream {string, label-info})
emit-headers: # out: (addr buffered-file), segments: (addr stream {string, segment-info}), labels: (addr stream {string, label-info})
# pseudocode:
# emit-elf-header(out, segments, labels)
# curr-segment = segments->data
@ -3311,7 +3311,7 @@ $emit-headers:end:
5d/pop-to-ebp
c3/return
emit-elf-header: # out : (addr buffered-file), segments : (addr stream {string, segment-info}), labels : (addr stream {string, label-info})
emit-elf-header: # out: (addr buffered-file), segments: (addr stream {string, segment-info}), labels: (addr stream {string, label-info})
# pseudocode
# *$Elf_e_entry = get(labels, "Entry")->address
# *$Elf_e_phnum = segments->write / 16 # size of a row
@ -3379,7 +3379,7 @@ $emit-elf-header:end:
5d/pop-to-ebp
c3/return
emit-elf-program-header-entry: # out : (addr buffered-file), curr-segment : (addr {string, segment-info})
emit-elf-program-header-entry: # out: (addr buffered-file), curr-segment: (addr {string, segment-info})
# pseudocode:
# *$Elf_p_offset = curr-segment->file-offset
# *$Elf_p_vaddr = curr-segment->address
@ -3468,7 +3468,7 @@ $emit-elf-program-header-entry:end:
# - some helpers for tests
stream-add4: # in : (addr stream byte), key : addr, val1 : addr, val2 : addr, val3 : addr
stream-add4: # in: (addr stream byte), key: addr, val1: addr, val2: addr, val3: addr
# . prologue
55/push-ebp
89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp
@ -3554,7 +3554,7 @@ $stream-add4:abort:
# l: (addr slice)
# one gotcha: 's5' must not be empty
trace-sssns: # s1 : (addr string), s2 : (addr string), s3 : (addr string), n4 : int, s5 : (addr string)
trace-sssns: # s1: (addr string), s2: (addr string), s3: (addr string), n4: int, s5: (addr string)
# . prologue
55/push-ebp
89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp
@ -3661,7 +3661,7 @@ test-trace-sssns:
5d/pop-to-ebp
c3/return
trace-snsns: # s1 : (addr string), n2 : int, s3 : (addr string), n4 : int, s5 : (addr string)
trace-snsns: # s1: (addr string), n2: int, s3: (addr string), n4: int, s5: (addr string)
# . prologue
55/push-ebp
89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp
@ -3768,7 +3768,7 @@ test-trace-snsns:
5d/pop-to-ebp
c3/return
trace-slsls: # s1 : (addr string), l2 : (addr slice), s3 : (addr string), l4 : (addr slice), s5 : (addr string)
trace-slsls: # s1: (addr string), l2: (addr slice), s3: (addr string), l4: (addr slice), s5: (addr string)
# . prologue
55/push-ebp
89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp
@ -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 : slice = {eax, ecx}
# var b/ebx: 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 : slice = {eax, ecx}
# var d/edx: slice = {eax, ecx}
51/push-ecx
50/push-eax
89/copy 3/mod/direct 2/rm32/edx . . . 4/r32/esp . . # copy esp to edx
@ -3893,7 +3893,7 @@ test-trace-slsls:
5d/pop-to-ebp
c3/return
trace-slsns: # s1 : (addr string), l2 : (addr slice), s3 : (addr string), n4 : int, s5 : (addr string)
trace-slsns: # s1: (addr string), l2: (addr slice), s3: (addr string), n4: int, s5: (addr string)
# . prologue
55/push-ebp
89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp
@ -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 : slice = {eax, ecx}
# var b/ebx: slice = {eax, ecx}
51/push-ecx
50/push-eax
89/copy 3/mod/direct 3/rm32/ebx . . . 4/r32/esp . . # copy esp to ebx
@ -4009,7 +4009,7 @@ test-trace-slsns:
5d/pop-to-ebp
c3/return
trace-slsss: # s1 : (addr string), l2 : (addr slice), s3 : (addr string), s4 : (addr string), s5 : (addr string)
trace-slsss: # s1: (addr string), l2: (addr slice), s3: (addr string), s4: (addr string), s5: (addr string)
# . prologue
55/push-ebp
89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp
@ -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 : slice = {eax, ecx}
# var b/ebx: 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 : (addr stream byte) -> eax : int
num-bytes: # line: (addr stream byte) -> eax: int
# pseudocode:
# result = 0
# while true
@ -4150,7 +4150,7 @@ num-bytes: # line : (addr stream byte) -> 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 : slice
# var word-slice/ecx: 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

View File

@ -67,11 +67,11 @@ $subx-tests-main:end:
b8/copy-to-eax 1/imm32/exit
cd/syscall 0x80/imm8
subx-gen-run-tests: # in : (addr buffered-file), out : (addr buffered-file)
subx-gen-run-tests: # in: (addr buffered-file), out: (addr buffered-file)
# pseudocode
# bool tests-found = false
# var line : (stream byte 512)
# var new-code-segment : (handle stream byte) = new-stream(Segment-size, 1)
# var line: (stream byte 512)
# var new-code-segment: (handle stream byte) = new-stream(Segment-size, 1)
# write(new-code-segment, "\n== code\n")
# write(new-code-segment, "run-tests:\n")
# while true
@ -101,13 +101,13 @@ subx-gen-run-tests: # in : (addr buffered-file), out : (addr buffered-file)
52/push-edx
53/push-ebx
57/push-edi
# var line/ecx : (stream byte 512)
# var line/ecx: (stream byte 512)
81 5/subop/subtract 3/mod/direct 4/rm32/esp . . . . . 0x200/imm32 # subtract from esp
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 : slice
# var word-slice/edx: 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

View File

@ -4,7 +4,7 @@
# $ ./translate_subx init.linux 0*.subx mu-init.subx mu-init-test.subx
# $ ./a.elf # should run all tests
main: # args : (address array kernel-string) -> result/ebx : int
main: # args: (address array kernel-string) -> result/ebx: int
# . prologue
55/push-ebp
89/<- %ebp 4/r32/esp

View File

@ -3,9 +3,9 @@
# See translate_mu for how this file is used.
#
# Mu programs start at a function called 'main' with this signature:
# fn main args: (address array kernel-string) -> exit_status/ebx : int
# fn main args: (address array kernel-string) -> exit_status/ebx: int
# If your program doesn't need commandline arguments you can drop it:
# fn main -> exit_status/ebx : int
# fn main -> exit_status/ebx: int
#
# Notice that the output must be in ebx, so that the exit() syscall can pick
# it up.
@ -15,7 +15,7 @@
Entry:
# we don't use ebp in Entry; just initialize it
bd/copy-to-ebp 0/imm32
# var args/eax : (address array kernel-string)
# var args/eax: (address array kernel-string)
89/<- %eax 4/r32/esp
# initialize the heap
(new-segment *Heap-size Heap)