5647 - experimental support for swapping OS
This commit is contained in:
parent
4d53de8afa
commit
ecfbbfb5b5
|
@ -0,0 +1,68 @@
|
|||
# Some OS-specific preliminaries for Linux.
|
||||
|
||||
# Memory layout
|
||||
#
|
||||
# 0 - 0x08047ffff - reserved for the kernel
|
||||
# 0x08048000 - 0xbffffffff - available for user programs
|
||||
# 0xc0000000 - 0xfffffffff - reserved for the kernel
|
||||
== code 0x09000000
|
||||
== data 0x0a000000
|
||||
|
||||
# Syscalls
|
||||
#
|
||||
# We don't have libc, so we need to know Linux's precise syscall layout.
|
||||
== code
|
||||
|
||||
# http://man7.org/linux/man-pages/man2/exit.2.html
|
||||
syscall_exit: # status/ebx : int
|
||||
b8/copy-to-eax 1/imm32
|
||||
cd/syscall 0x80/imm8
|
||||
|
||||
# http://man7.org/linux/man-pages/man2/read.2.html
|
||||
syscall_read: # fd/ebx : int, buf/ecx : address, size/edx : int -> nbytes-or-error/eax : int
|
||||
b8/copy-to-eax 3/imm32
|
||||
cd/syscall 0x80/imm8
|
||||
c3/return
|
||||
|
||||
# http://man7.org/linux/man-pages/man2/write.2.html
|
||||
syscall_write: # fd/ebx : int, buf/ecx : address, size/edx : int -> nbytes-or-error/eax : int
|
||||
b8/copy-to-eax 4/imm32
|
||||
cd/syscall 0x80/imm8
|
||||
c3/return
|
||||
|
||||
# http://man7.org/linux/man-pages/man2/open.2.html
|
||||
syscall_open: # filename/ebx : (address null-terminated-string), flags/ecx : int -> fd-or-error/eax : int
|
||||
b8/copy-to-eax 5/imm32
|
||||
cd/syscall 0x80/imm8
|
||||
c3/return
|
||||
|
||||
# http://man7.org/linux/man-pages/man2/close.2.html
|
||||
syscall_close: # fd/ebx : int -> status/eax
|
||||
b8/copy-to-eax 6/imm32
|
||||
cd/syscall 0x80/imm8
|
||||
c3/return
|
||||
|
||||
# http://man7.org/linux/man-pages/man2/creat.2.html
|
||||
syscall_creat: # filename/ebx : (address null-terminated-string) -> fd-or-error/eax : int
|
||||
b8/copy-to-eax 8/imm32
|
||||
cd/syscall 0x80/imm8
|
||||
c3/return
|
||||
|
||||
# http://man7.org/linux/man-pages/man2/unlink.2.html
|
||||
syscall_unlink: # filename/ebx : (address null-terminated-string) -> status/eax : int
|
||||
b8/copy-to-eax 0xa/imm32
|
||||
cd/syscall 0x80/imm8
|
||||
c3/return
|
||||
|
||||
# http://man7.org/linux/man-pages/man2/rename.2.html
|
||||
syscall_rename: # source/ebx : (address null-terminated-string), dest/ecx : (address null-terminated-string) -> status/eax : int
|
||||
b8/copy-to-eax 0x26/imm32
|
||||
cd/syscall 0x80/imm8
|
||||
c3/return
|
||||
|
||||
# https://github.com/torvalds/linux/blob/fa121bb3fed6313b1f0af23952301e06cf6d32ed/mm/nommu.c#L1352
|
||||
syscall_mmap: # arg/ebx : (address mmap_arg_struct) -> status/eax : int
|
||||
# the important thing: ebx+4 contains the 32-bit size to be allocated
|
||||
b8/copy-to-eax 0x5a/imm32
|
||||
cd/syscall 0x80/imm8
|
||||
c3/return
|
|
@ -1,8 +0,0 @@
|
|||
# Segment addresses aren't really the concern of any other layer, so we'll
|
||||
# define them separately. They're approximate due to fidgety ELF alignment
|
||||
# requirements, so don't get clever assuming variables are at specific
|
||||
# addresses.
|
||||
|
||||
== code 0x09000000
|
||||
|
||||
== data 0x0a000000
|
BIN
apps/assort
BIN
apps/assort
Binary file not shown.
BIN
apps/calls
BIN
apps/calls
Binary file not shown.
BIN
apps/crenshaw2-1
BIN
apps/crenshaw2-1
Binary file not shown.
Binary file not shown.
BIN
apps/dquotes
BIN
apps/dquotes
Binary file not shown.
BIN
apps/factorial
BIN
apps/factorial
Binary file not shown.
BIN
apps/handle
BIN
apps/handle
Binary file not shown.
BIN
apps/sigils
BIN
apps/sigils
Binary file not shown.
BIN
apps/survey
BIN
apps/survey
Binary file not shown.
BIN
apps/tests
BIN
apps/tests
Binary file not shown.
8
build
8
build
|
@ -119,7 +119,7 @@ then
|
|||
for n in `seq 1 12`
|
||||
do
|
||||
older_than examples/ex$n examples/ex$n.subx && {
|
||||
./subx_bin translate examples/ex$n.subx -o examples/ex$n
|
||||
./subx_bin translate 049init.linux examples/ex$n.subx -o examples/ex$n
|
||||
}
|
||||
done
|
||||
|
||||
|
@ -127,7 +127,7 @@ then
|
|||
for app in factorial crenshaw2-1 crenshaw2-1b handle
|
||||
do
|
||||
older_than apps/$app apps/$app.subx [0-9]*.subx && {
|
||||
./subx_bin translate [0-9]*.subx apps/$app.subx -o apps/$app
|
||||
./subx_bin translate 049init.linux [0-9]*.subx apps/$app.subx -o apps/$app
|
||||
}
|
||||
done
|
||||
|
||||
|
@ -135,7 +135,7 @@ then
|
|||
for phase in hex survey pack assort dquotes tests
|
||||
do
|
||||
older_than apps/$phase apps/$phase.subx apps/subx-common.subx [0-9]*.subx && {
|
||||
./subx_bin translate [0-9]*.subx apps/subx-common.subx apps/$phase.subx -o apps/$phase
|
||||
./subx_bin translate 049init.linux [0-9]*.subx apps/subx-common.subx apps/$phase.subx -o apps/$phase
|
||||
}
|
||||
done
|
||||
|
||||
|
@ -143,7 +143,7 @@ then
|
|||
for phase in sigils
|
||||
do
|
||||
older_than apps/$phase apps/$phase.subx apps/subx-common.subx [0-9]*.subx && {
|
||||
./subx_bin translate [0-9]*.subx apps/subx-common.subx apps/$phase.subx -o apps/$phase
|
||||
./subx_bin translate 049init.linux [0-9]*.subx apps/subx-common.subx apps/$phase.subx -o apps/$phase
|
||||
}
|
||||
done
|
||||
|
||||
|
|
BIN
examples/ex1
BIN
examples/ex1
Binary file not shown.
|
@ -8,14 +8,11 @@
|
|||
# $ echo $?
|
||||
# 42
|
||||
|
||||
== code 0x09000000
|
||||
== code
|
||||
|
||||
Entry:
|
||||
# syscall(exit, 42)
|
||||
# exit(42)
|
||||
bb/copy-to-ebx 2a/imm32 # 42 in hex
|
||||
b8/copy-to-eax 1/imm32/exit
|
||||
cd/syscall 0x80/imm8
|
||||
|
||||
== data 0x0a000000
|
||||
e8/call syscall_exit/disp32
|
||||
|
||||
# . . vim:nowrap:textwidth=0
|
||||
|
|
BIN
examples/ex10
BIN
examples/ex10
Binary file not shown.
|
@ -7,7 +7,7 @@
|
|||
# $ echo $?
|
||||
# 0 # false
|
||||
|
||||
== code 0x09000000
|
||||
== code
|
||||
# instruction effective address register displacement immediate
|
||||
# . op subop mod rm32 base index scale r32
|
||||
# . 1-3 bytes 3 bits 2 bits 3 bits 3 bits 3 bits 2 bits 2 bits 0/1/2/4 bytes 0/1/2/4 bytes
|
||||
|
@ -27,10 +27,9 @@ Entry: # return argv-equal(argv[1], argv[2])
|
|||
ff 6/subop/push 1/mod/*+disp8 5/rm32/ebp . . . . 8/disp8 . # push *(ebp+8)
|
||||
# . . call
|
||||
e8/call argv-equal/disp32
|
||||
# syscall(exit, eax)
|
||||
# exit(eax)
|
||||
89/copy 3/mod/direct 3/rm32/ebx . . . 0/r32/eax . . # copy eax to ebx
|
||||
b8/copy-to-eax 1/imm32/exit
|
||||
cd/syscall 0x80/imm8
|
||||
e8/call syscall_exit/disp32
|
||||
|
||||
# compare two null-terminated ascii strings
|
||||
# reason for the name: the only place we should have null-terminated ascii strings is from commandline args
|
||||
|
@ -67,6 +66,4 @@ $argv-equal:false:
|
|||
b8/copy-to-eax 0/imm32
|
||||
c3/return
|
||||
|
||||
== data 0x0a000000
|
||||
|
||||
# . . vim:nowrap:textwidth=0
|
||||
|
|
BIN
examples/ex11
BIN
examples/ex11
Binary file not shown.
|
@ -14,17 +14,16 @@
|
|||
# because checking for it would require the function being tested! Breakage
|
||||
# would cause tests to not run, rather than to fail as we'd like.)
|
||||
|
||||
== code 0x09000000
|
||||
== code
|
||||
# instruction effective address register displacement immediate
|
||||
# . op subop mod rm32 base index scale r32
|
||||
# . 1-3 bytes 3 bits 2 bits 3 bits 3 bits 3 bits 2 bits 2 bits 0/1/2/4 bytes 0/1/2/4 bytes
|
||||
|
||||
Entry: # run all tests
|
||||
e8/call run-tests/disp32 # 'run-tests' is a function created automatically by SubX. It calls all functions that start with 'test-'.
|
||||
# syscall(exit, eax)
|
||||
# exit(eax)
|
||||
89/copy 3/mod/direct 3/rm32/ebx . . . 0/r32/eax . . # copy eax to ebx
|
||||
b8/copy-to-eax 1/imm32/exit
|
||||
cd/syscall 0x80/imm8
|
||||
e8/call syscall_exit/disp32
|
||||
|
||||
# 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
|
||||
|
@ -327,8 +326,7 @@ write-stderr: # s : (address array byte) -> <void>
|
|||
8b/copy 1/mod/*+disp8 5/rm32/ebp . . . 2/r32/edx 8/disp8 . # copy *(ebp+8) to edx
|
||||
8b/copy 0/mod/indirect 2/rm32/edx . . . 2/r32/edx . . # copy *edx to edx
|
||||
# . . syscall
|
||||
b8/copy-to-eax 4/imm32/write
|
||||
cd/syscall 0x80/imm8
|
||||
e8/call syscall_write/disp32
|
||||
# . restore registers
|
||||
5b/pop-to-ebx
|
||||
5a/pop-to-edx
|
||||
|
@ -339,7 +337,7 @@ write-stderr: # s : (address array byte) -> <void>
|
|||
5d/pop-to-ebp
|
||||
c3/return
|
||||
|
||||
== data 0x0a000000
|
||||
== data
|
||||
|
||||
Newline:
|
||||
# size
|
||||
|
|
BIN
examples/ex12
BIN
examples/ex12
Binary file not shown.
|
@ -6,26 +6,24 @@
|
|||
# $ ./subx run examples/ex12
|
||||
# You shouldn't get a segmentation fault.
|
||||
|
||||
== code 0x09000000
|
||||
== code
|
||||
# instruction effective address register displacement immediate
|
||||
# . op subop mod rm32 base index scale r32
|
||||
# . 1-3 bytes 3 bits 2 bits 3 bits 3 bits 3 bits 2 bits 2 bits 0/1/2/4 bytes 0/1/2/4 bytes
|
||||
|
||||
Entry:
|
||||
# syscall(mmap, 0x1000)
|
||||
# mmap(Mmap-new-segment->len)
|
||||
bb/copy-to-ebx Mmap-new-segment/imm32
|
||||
b8/copy-to-eax 0x5a/imm32/mmap
|
||||
cd/syscall 0x80/imm8
|
||||
e8/call syscall_mmap/disp32
|
||||
|
||||
# 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
|
||||
|
||||
# syscall(exit, eax)
|
||||
# exit(eax)
|
||||
89/copy 3/mod/direct 3/rm32/ebx . . . 0/r32/eax . . # copy eax to ebx
|
||||
b8/copy-to-eax 1/imm32/exit
|
||||
cd/syscall 0x80/imm8
|
||||
e8/call syscall_exit/disp32
|
||||
|
||||
== data 0x0a000000
|
||||
== data
|
||||
|
||||
# various constants used here were found in the Linux sources (search for file mman-common.h)
|
||||
Mmap-new-segment: # type mmap_arg_struct
|
||||
|
|
BIN
examples/ex2
BIN
examples/ex2
Binary file not shown.
|
@ -7,17 +7,14 @@
|
|||
# $ echo $?
|
||||
# 2
|
||||
|
||||
== code 0x09000000
|
||||
== code
|
||||
|
||||
Entry:
|
||||
# ebx = 1
|
||||
bb/copy-to-ebx 1/imm32
|
||||
# increment ebx
|
||||
43/increment-ebx
|
||||
# syscall(exit, ebx)
|
||||
b8/copy-to-eax 1/imm32/exit
|
||||
cd/syscall 0x80/imm8
|
||||
|
||||
== data 0x0a000000
|
||||
# exit(ebx)
|
||||
e8/call syscall_exit/disp32
|
||||
|
||||
# . . vim:nowrap:textwidth=0
|
||||
|
|
BIN
examples/ex3
BIN
examples/ex3
Binary file not shown.
|
@ -7,7 +7,7 @@
|
|||
# $ echo $?
|
||||
# 55
|
||||
|
||||
== code 0x09000000
|
||||
== code
|
||||
# instruction effective address register displacement immediate
|
||||
# . op subop mod rm32 base index scale r32
|
||||
# . 1-3 bytes 3 bits 2 bits 3 bits 3 bits 3 bits 2 bits 2 bits 0/1/2/4 bytes 0/1/2/4 bytes
|
||||
|
@ -30,10 +30,7 @@ $loop:
|
|||
eb/jump $loop/disp8
|
||||
|
||||
$exit:
|
||||
# syscall(exit, ebx)
|
||||
b8/copy-to-eax 1/imm32/exit
|
||||
cd/syscall 0x80/imm8
|
||||
|
||||
== data 0x0a000000
|
||||
# exit(ebx)
|
||||
e8/call syscall_exit/disp32
|
||||
|
||||
# . . vim:nowrap:textwidth=0
|
||||
|
|
BIN
examples/ex4
BIN
examples/ex4
Binary file not shown.
|
@ -4,16 +4,16 @@
|
|||
# $ ./subx translate examples/ex4.subx -o examples/ex4
|
||||
# $ ./subx run examples/ex4
|
||||
|
||||
== data 0x0a000000
|
||||
== data
|
||||
|
||||
# the global variable we save to
|
||||
X:
|
||||
0/imm32 # space for read() to write to
|
||||
|
||||
== code 0x09000000
|
||||
== code
|
||||
|
||||
Entry:
|
||||
# syscall(read, stdin, X, 1)
|
||||
# read(stdin, X, 1)
|
||||
# . fd = 0 (stdin)
|
||||
bb/copy-to-ebx 0/imm32
|
||||
# . data = X (location to write result to)
|
||||
|
@ -21,10 +21,9 @@ b9/copy-to-ecx X/imm32
|
|||
# . size = 1 character
|
||||
ba/copy-to-edx 1/imm32
|
||||
# . syscall
|
||||
b8/copy-to-eax 3/imm32/read
|
||||
cd/syscall 0x80/imm8
|
||||
e8/call syscall_read/disp32
|
||||
|
||||
# syscall(write, stdout, X, 1)
|
||||
# write(stdout, X, 1)
|
||||
# . fd = 1 (stdout)
|
||||
bb/copy-to-ebx 1/imm32
|
||||
# . initialize X (location to read from)
|
||||
|
@ -32,11 +31,9 @@ b9/copy-to-ecx X/imm32
|
|||
# . size = 1 character
|
||||
ba/copy-to-edx 1/imm32
|
||||
# . syscall
|
||||
b8/copy-to-eax 4/imm32/write
|
||||
cd/syscall 0x80/imm8
|
||||
e8/call syscall_write/disp32
|
||||
|
||||
# syscall(exit, ebx)
|
||||
b8/copy-to-eax 1/imm32/exit
|
||||
cd/syscall 0x80/imm8
|
||||
# exit(ebx)
|
||||
e8/call syscall_exit/disp32
|
||||
|
||||
# . . vim:nowrap:textwidth=0
|
||||
|
|
BIN
examples/ex5
BIN
examples/ex5
Binary file not shown.
|
@ -4,7 +4,7 @@
|
|||
# $ ./subx translate examples/ex5.subx -o examples/ex5
|
||||
# $ ./subx run examples/ex5
|
||||
|
||||
== code 0x09000000
|
||||
== code
|
||||
# instruction effective address register displacement immediate
|
||||
# . op subop mod rm32 base index scale r32
|
||||
# . 1-3 bytes 3 bits 2 bits 3 bits 3 bits 3 bits 2 bits 2 bits 0/1/2/4 bytes 0/1/2/4 bytes
|
||||
|
@ -14,7 +14,7 @@ Entry:
|
|||
# allocate x on the stack
|
||||
81 5/subop/subtract 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # subtract from esp
|
||||
|
||||
# syscall(read, stdin, x, 1)
|
||||
# read(stdin, x, 1)
|
||||
# . fd = 0 (stdin)
|
||||
bb/copy-to-ebx 0/imm32
|
||||
# . data = x (location to write result to)
|
||||
|
@ -22,8 +22,7 @@ Entry:
|
|||
# . size = 1 character
|
||||
ba/copy-to-edx 1/imm32
|
||||
# . syscall
|
||||
b8/copy-to-eax 3/imm32/read
|
||||
cd/syscall 0x80/imm8
|
||||
e8/call syscall_read/disp32
|
||||
|
||||
# syscall(write, stdout, x, 1)
|
||||
# . fd = 1 (stdout)
|
||||
|
@ -36,10 +35,7 @@ Entry:
|
|||
b8/copy-to-eax 4/imm32/write
|
||||
cd/syscall 0x80/imm8
|
||||
|
||||
# syscall(exit, ebx)
|
||||
b8/copy-to-eax 1/imm32/exit
|
||||
cd/syscall 0x80/imm8
|
||||
|
||||
== data 0x0a000000
|
||||
# exit(ebx)
|
||||
e8/call syscall_exit/disp32
|
||||
|
||||
# . . vim:nowrap:textwidth=0
|
||||
|
|
BIN
examples/ex6
BIN
examples/ex6
Binary file not shown.
|
@ -5,13 +5,13 @@
|
|||
# $ ./subx run examples/ex6
|
||||
# Hello, world!
|
||||
|
||||
== code 0x09000000
|
||||
# instruction effective address register displacement immediate
|
||||
== code
|
||||
|
||||
# . 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
|
||||
|
||||
Entry:
|
||||
# syscall(write, stdout, X, Size)
|
||||
# write(stdout, X, Size)
|
||||
# . fd = 1 (stdout)
|
||||
bb/copy-to-ebx 1/imm32
|
||||
# . initialize X (location to write result to)
|
||||
|
@ -19,14 +19,12 @@ Entry:
|
|||
# . initialize Size
|
||||
8b/copy 0/mod/indirect 5/rm32/.disp32 . . 2/r32/edx Size/disp32 . # copy *Size to edx
|
||||
# . syscall
|
||||
b8/copy-to-eax 4/imm32/write
|
||||
cd/syscall 0x80/imm8
|
||||
e8/call syscall_write/disp32
|
||||
|
||||
# syscall(exit, ebx)
|
||||
b8/copy-to-eax 1/imm32/exit
|
||||
cd/syscall 0x80/imm8
|
||||
# exit(ebx)
|
||||
e8/call syscall_exit/disp32
|
||||
|
||||
== data 0x0a000000
|
||||
== data
|
||||
|
||||
Size: # size of string
|
||||
0x0e/imm32 # 14
|
||||
|
|
BIN
examples/ex7
BIN
examples/ex7
Binary file not shown.
|
@ -11,88 +11,79 @@
|
|||
# $ echo $?
|
||||
# 97
|
||||
|
||||
== code 0x09000000
|
||||
== code
|
||||
# instruction effective address register displacement immediate
|
||||
# . op subop mod rm32 base index scale r32
|
||||
# . 1-3 bytes 3 bits 2 bits 3 bits 3 bits 3 bits 2 bits 2 bits 0/1/2/4 bytes 0/1/2/4 bytes
|
||||
|
||||
Entry:
|
||||
# syscall(creat, Filename)
|
||||
# creat(Filename)
|
||||
bb/copy-to-ebx Filename/imm32
|
||||
b9/copy-to-ecx 0x180/imm32/fixed-perms
|
||||
b8/copy-to-eax 8/imm32/creat
|
||||
cd/syscall 0x80/imm8
|
||||
e8/call syscall_creat/disp32
|
||||
|
||||
# stream = syscall(open, Filename, O_WRONLY, 0) # we can't use 'fd' because it looks like a hex byte
|
||||
# stream = open(Filename, O_WRONLY, 0) # we can't use 'fd' because it looks like a hex byte
|
||||
bb/copy-to-ebx Filename/imm32
|
||||
b9/copy-to-ecx 1/imm32/wronly
|
||||
ba/copy-to-edx 0x180/imm32/fixed-perms
|
||||
b8/copy-to-eax 5/imm32/open
|
||||
cd/syscall 0x80/imm8
|
||||
e8/call syscall_open/disp32
|
||||
# save stream
|
||||
bb/copy-to-ebx Stream/imm32
|
||||
89/copy 0/mod/indirect 3/rm32/ebx . . . 0/r32/eax . . # copy eax to *ebx
|
||||
|
||||
# syscall(write, Stream, "a", 1)
|
||||
# write(Stream, "a", 1)
|
||||
# . load stream
|
||||
bb/copy-to-ebx Stream/imm32
|
||||
8b/copy 0/mod/indirect 3/rm32/ebx . . . 3/r32/ebx . . # copy *ebx to ebx
|
||||
# .
|
||||
b9/copy-to-ecx A/imm32
|
||||
ba/copy-to-edx 1/imm32/size
|
||||
b8/copy-to-eax 4/imm32/write
|
||||
cd/syscall 0x80/imm8
|
||||
e8/call syscall_write/disp32
|
||||
|
||||
# syscall(close, Stream)
|
||||
# close(Stream)
|
||||
# . load stream
|
||||
bb/copy-to-ebx Stream/imm32
|
||||
8b/copy 0/mod/indirect 3/rm32/ebx . . . 3/r32/ebx . . # copy *ebx to ebx
|
||||
# .
|
||||
b8/copy-to-eax 6/imm32/close
|
||||
cd/syscall 0x80/imm8
|
||||
e8/call syscall_close/disp32
|
||||
|
||||
# stream = syscall(open, Filename, O_RDONLY, 0)
|
||||
# stream = open(Filename, O_RDONLY, 0)
|
||||
bb/copy-to-ebx Filename/imm32
|
||||
b9/copy-to-ecx 0/imm32/rdonly
|
||||
ba/copy-to-edx 0x180/imm32/fixed-perms
|
||||
b8/copy-to-eax 5/imm32/open
|
||||
cd/syscall 0x80/imm8
|
||||
e8/call syscall_open/disp32
|
||||
# . save Stream
|
||||
bb/copy-to-ebx Stream/imm32
|
||||
89/copy 0/mod/indirect 3/rm32/ebx . . . 0/r32/eax . . # copy eax to *ebx
|
||||
|
||||
# syscall(read, Stream, B, 1)
|
||||
# read(Stream, B, 1)
|
||||
# . load stream
|
||||
bb/copy-to-ebx Stream/imm32
|
||||
8b/copy 0/mod/indirect 3/rm32/ebx . . . 3/r32/ebx . . # copy *ebx to ebx
|
||||
# .
|
||||
b9/copy-to-ecx B/imm32
|
||||
ba/copy-to-edx 1/imm32/size
|
||||
b8/copy-to-eax 3/imm32/read
|
||||
cd/syscall 0x80/imm8
|
||||
e8/call syscall_read/disp32
|
||||
|
||||
# syscall(close, Stream)
|
||||
# close(Stream)
|
||||
# . load stream
|
||||
bb/copy-to-ebx Stream/imm32
|
||||
8b/copy 0/mod/indirect 3/rm32/ebx . . . 3/r32/ebx . . # copy *ebx to ebx
|
||||
#
|
||||
b8/copy-to-eax 6/imm32/close
|
||||
cd/syscall 0x80/imm8
|
||||
e8/call syscall_close/disp32
|
||||
|
||||
# syscall(unlink, filename)
|
||||
# unlink(filename)
|
||||
bb/copy-to-ebx Filename/imm32
|
||||
b8/copy-to-eax 0xa/imm32/unlink
|
||||
cd/syscall 0x80/imm8
|
||||
e8/call syscall_unlink/disp32
|
||||
|
||||
# syscall(exit, b)
|
||||
# exit(b)
|
||||
# . load b
|
||||
bb/copy-to-ebx B/imm32
|
||||
8b/copy 0/mod/indirect 3/rm32/ebx . . . 3/r32/ebx . . # copy *ebx to ebx
|
||||
#
|
||||
b8/copy-to-eax 1/imm32/exit
|
||||
cd/syscall 0x80/imm8
|
||||
e8/call syscall_exit/disp32
|
||||
|
||||
== data 0x0a000000
|
||||
== data
|
||||
|
||||
Stream:
|
||||
0/imm32
|
||||
|
|
BIN
examples/ex8
BIN
examples/ex8
Binary file not shown.
|
@ -14,7 +14,7 @@
|
|||
# ...
|
||||
# Locals start from esp-4 downwards.
|
||||
|
||||
== code 0x09000000
|
||||
== code
|
||||
# instruction effective address register displacement immediate
|
||||
# . op subop mod rm32 base index scale r32
|
||||
# . 1-3 bytes 3 bits 2 bits 3 bits 3 bits 3 bits 2 bits 2 bits 0/1/2/4 bytes 0/1/2/4 bytes
|
||||
|
@ -32,8 +32,7 @@ Entry:
|
|||
|
||||
# exit(eax)
|
||||
89/copy 3/mod/direct 3/rm32/ebx . . . 0/r32/eax . . # copy eax to ebx
|
||||
b8/copy-to-eax 1/imm32/exit
|
||||
cd/syscall 0x80/imm8
|
||||
e8/call syscall_exit/disp32
|
||||
|
||||
ascii-length: # s : (address array byte) -> n/eax
|
||||
# edx = s
|
||||
|
@ -56,6 +55,6 @@ $ascii-length:end:
|
|||
# return eax
|
||||
c3/return
|
||||
|
||||
== data 0x0a000000
|
||||
== data
|
||||
|
||||
# . . vim:nowrap:textwidth=0
|
||||
|
|
BIN
examples/ex9
BIN
examples/ex9
Binary file not shown.
|
@ -17,7 +17,7 @@
|
|||
# ...
|
||||
# Locals start from esp-4 downwards.
|
||||
|
||||
== code 0x09000000
|
||||
== code
|
||||
# instruction effective address register displacement immediate
|
||||
# . op subop mod rm32 base index scale r32
|
||||
# . 1-3 bytes 3 bits 2 bits 3 bits 3 bits 3 bits 2 bits 2 bits 0/1/2/4 bytes 0/1/2/4 bytes
|
||||
|
@ -34,10 +34,9 @@ Entry:
|
|||
e8/call ascii-difference/disp32
|
||||
# . . discard args
|
||||
81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp
|
||||
# syscall(exit, eax)
|
||||
# exit(eax)
|
||||
89/copy 3/mod/direct 3/rm32/ebx . . . 0/r32/eax . . # copy eax to ebx
|
||||
b8/copy-to-eax 1/imm32/exit
|
||||
cd/syscall 0x80/imm8
|
||||
e8/call syscall_exit/disp32
|
||||
|
||||
ascii-difference: # (s1, s2) : null-terminated ascii strings
|
||||
# a = first letter of s1 (ecx)
|
||||
|
@ -50,6 +49,4 @@ ascii-difference: # (s1, s2) : null-terminated ascii strings
|
|||
29/subtract 3/mod/direct 0/rm32/eax . . . 1/r32/ecx . . # subtract ecx from eax
|
||||
c3/return
|
||||
|
||||
== data 0x0a000000
|
||||
|
||||
# . . vim:nowrap:textwidth=0
|
||||
|
|
54
test_apps
54
test_apps
|
@ -26,7 +26,7 @@ echo "== translating and running using C++"
|
|||
# example programs
|
||||
|
||||
echo ex1
|
||||
./subx translate examples/ex1.subx -o examples/ex1
|
||||
./subx translate 049init.linux examples/ex1.subx -o examples/ex1
|
||||
test "$1" = 'record' || git diff --exit-code examples/ex1
|
||||
test $EMULATED && {
|
||||
./subx run examples/ex1 || ret=$?
|
||||
|
@ -38,7 +38,7 @@ test $NATIVE && {
|
|||
}
|
||||
|
||||
echo ex2
|
||||
./subx translate examples/ex2.subx -o examples/ex2
|
||||
./subx translate 049init.linux examples/ex2.subx -o examples/ex2
|
||||
test "$1" = 'record' || git diff --exit-code examples/ex2
|
||||
test $EMULATED && {
|
||||
./subx run examples/ex2 || ret=$?
|
||||
|
@ -50,7 +50,7 @@ test $NATIVE && {
|
|||
}
|
||||
|
||||
echo ex3
|
||||
./subx translate examples/ex3.subx -o examples/ex3
|
||||
./subx translate 049init.linux examples/ex3.subx -o examples/ex3
|
||||
test "$1" = 'record' || git diff --exit-code examples/ex3
|
||||
test $EMULATED && {
|
||||
./subx run examples/ex3 || ret=$?
|
||||
|
@ -62,7 +62,7 @@ test $NATIVE && {
|
|||
}
|
||||
|
||||
echo ex4
|
||||
./subx translate examples/ex4.subx -o examples/ex4
|
||||
./subx translate 049init.linux examples/ex4.subx -o examples/ex4
|
||||
test "$1" = 'record' || git diff --exit-code examples/ex4
|
||||
test $EMULATED && {
|
||||
echo a | ./subx run examples/ex4 >ex4.out || true
|
||||
|
@ -74,7 +74,7 @@ test $NATIVE && {
|
|||
}
|
||||
|
||||
echo ex5
|
||||
./subx translate examples/ex5.subx -o examples/ex5
|
||||
./subx translate 049init.linux examples/ex5.subx -o examples/ex5
|
||||
test "$1" = 'record' || git diff --exit-code examples/ex5
|
||||
test $EMULATED && {
|
||||
echo a | ./subx run examples/ex5 >ex5.out || true
|
||||
|
@ -86,7 +86,7 @@ test $NATIVE && {
|
|||
}
|
||||
|
||||
echo ex6
|
||||
./subx translate examples/ex6.subx -o examples/ex6
|
||||
./subx translate 049init.linux examples/ex6.subx -o examples/ex6
|
||||
test "$1" = 'record' || git diff --exit-code examples/ex6
|
||||
test $EMULATED && {
|
||||
./subx run examples/ex6 >ex6.out || true
|
||||
|
@ -98,7 +98,7 @@ test $NATIVE && {
|
|||
}
|
||||
|
||||
echo ex7
|
||||
./subx translate examples/ex7.subx -o examples/ex7
|
||||
./subx translate 049init.linux examples/ex7.subx -o examples/ex7
|
||||
test "$1" = 'record' || git diff --exit-code examples/ex7
|
||||
test $EMULATED && {
|
||||
./subx run examples/ex7 || ret=$?
|
||||
|
@ -110,7 +110,7 @@ test $NATIVE && {
|
|||
}
|
||||
|
||||
echo ex8
|
||||
./subx translate examples/ex8.subx -o examples/ex8
|
||||
./subx translate 049init.linux examples/ex8.subx -o examples/ex8
|
||||
test "$1" = 'record' || git diff --exit-code examples/ex8
|
||||
test $EMULATED && {
|
||||
./subx run examples/ex8 abcd || ret=$?
|
||||
|
@ -122,7 +122,7 @@ test $NATIVE && {
|
|||
}
|
||||
|
||||
echo ex9
|
||||
./subx translate examples/ex9.subx -o examples/ex9
|
||||
./subx translate 049init.linux examples/ex9.subx -o examples/ex9
|
||||
test "$1" = 'record' || git diff --exit-code examples/ex9
|
||||
test $EMULATED && {
|
||||
./subx run examples/ex9 z x || ret=$?
|
||||
|
@ -134,7 +134,7 @@ test $NATIVE && {
|
|||
}
|
||||
|
||||
echo ex10
|
||||
./subx translate examples/ex10.subx -o examples/ex10
|
||||
./subx translate 049init.linux examples/ex10.subx -o examples/ex10
|
||||
test "$1" = 'record' || git diff --exit-code examples/ex10
|
||||
test $EMULATED && {
|
||||
./subx run examples/ex10 abc abc || ret=$?
|
||||
|
@ -148,7 +148,7 @@ test $NATIVE && {
|
|||
}
|
||||
|
||||
echo ex11
|
||||
./subx translate examples/ex11.subx -o examples/ex11
|
||||
./subx translate 049init.linux examples/ex11.subx -o examples/ex11
|
||||
test "$1" = 'record' || git diff --exit-code examples/ex11
|
||||
test $EMULATED && {
|
||||
./subx run examples/ex11
|
||||
|
@ -160,7 +160,7 @@ test $NATIVE && {
|
|||
}
|
||||
|
||||
echo ex12
|
||||
./subx translate examples/ex12.subx -o examples/ex12
|
||||
./subx translate 049init.linux examples/ex12.subx -o examples/ex12
|
||||
test "$1" = 'record' || git diff --exit-code examples/ex12
|
||||
test $EMULATED && ./subx run examples/ex12 # final byte of mmap'd address is well-nigh guaranteed to be 0
|
||||
test $NATIVE && examples/ex12
|
||||
|
@ -168,7 +168,7 @@ test $NATIVE && examples/ex12
|
|||
# Larger apps that use the standard library.
|
||||
|
||||
echo factorial
|
||||
./subx translate 0*.subx apps/factorial.subx -o apps/factorial
|
||||
./subx translate 049init.linux 0*.subx apps/factorial.subx -o apps/factorial
|
||||
test "$1" = 'record' || git diff --exit-code apps/factorial
|
||||
test $EMULATED && {
|
||||
./subx run apps/factorial || ret=$?
|
||||
|
@ -184,7 +184,7 @@ test $NATIVE && {
|
|||
}
|
||||
|
||||
echo crenshaw2-1
|
||||
./subx translate 0*.subx apps/crenshaw2-1.subx -o apps/crenshaw2-1
|
||||
./subx translate 049init.linux 0*.subx apps/crenshaw2-1.subx -o apps/crenshaw2-1
|
||||
test "$1" = 'record' || git diff --exit-code apps/crenshaw2-1
|
||||
test $EMULATED && {
|
||||
./subx run apps/crenshaw2-1 test
|
||||
|
@ -196,7 +196,7 @@ test $NATIVE && {
|
|||
}
|
||||
|
||||
echo crenshaw2-1b
|
||||
./subx translate 0*.subx apps/crenshaw2-1b.subx -o apps/crenshaw2-1b
|
||||
./subx translate 049init.linux 0*.subx apps/crenshaw2-1b.subx -o apps/crenshaw2-1b
|
||||
test "$1" = 'record' || git diff --exit-code apps/crenshaw2-1b
|
||||
test $EMULATED && {
|
||||
./subx run apps/crenshaw2-1b test
|
||||
|
@ -208,7 +208,7 @@ test $NATIVE && {
|
|||
}
|
||||
|
||||
echo handle
|
||||
./subx translate 0*.subx apps/handle.subx -o apps/handle
|
||||
./subx translate 049init.linux 0*.subx apps/handle.subx -o apps/handle
|
||||
test "$1" = 'record' || git diff --exit-code apps/handle
|
||||
test $EMULATED && {
|
||||
./subx run apps/handle > handle.out 2>&1 || true
|
||||
|
@ -224,7 +224,7 @@ test $NATIVE && {
|
|||
# Phases of the self-hosted SubX translator.
|
||||
|
||||
echo hex
|
||||
./subx translate 0*.subx apps/subx-common.subx apps/hex.subx -o apps/hex
|
||||
./subx translate 049init.linux 0*.subx apps/subx-common.subx apps/hex.subx -o apps/hex
|
||||
test "$1" = 'record' || git diff --exit-code apps/hex
|
||||
test $EMULATED && {
|
||||
./subx run apps/hex test
|
||||
|
@ -236,7 +236,7 @@ test $NATIVE && {
|
|||
}
|
||||
|
||||
echo survey
|
||||
./subx translate 0*.subx apps/subx-common.subx apps/survey.subx -o apps/survey
|
||||
./subx translate 049init.linux 0*.subx apps/subx-common.subx apps/survey.subx -o apps/survey
|
||||
test "$1" = 'record' || git diff --exit-code apps/survey
|
||||
test $EMULATED && {
|
||||
./subx run apps/survey test
|
||||
|
@ -248,7 +248,7 @@ test $NATIVE && {
|
|||
}
|
||||
|
||||
echo pack
|
||||
./subx translate 0*.subx apps/subx-common.subx apps/pack.subx -o apps/pack
|
||||
./subx translate 049init.linux 0*.subx apps/subx-common.subx apps/pack.subx -o apps/pack
|
||||
test "$1" = 'record' || git diff --exit-code apps/pack
|
||||
test $EMULATED && {
|
||||
./subx run apps/pack test
|
||||
|
@ -260,7 +260,7 @@ test $NATIVE && {
|
|||
}
|
||||
|
||||
echo assort
|
||||
./subx translate 0*.subx apps/subx-common.subx apps/assort.subx -o apps/assort
|
||||
./subx translate 049init.linux 0*.subx apps/subx-common.subx apps/assort.subx -o apps/assort
|
||||
test "$1" = 'record' || git diff --exit-code apps/assort
|
||||
test $EMULATED && {
|
||||
./subx run apps/assort test
|
||||
|
@ -272,7 +272,7 @@ test $NATIVE && {
|
|||
}
|
||||
|
||||
echo dquotes
|
||||
./subx translate 0*.subx apps/subx-common.subx apps/dquotes.subx -o apps/dquotes
|
||||
./subx translate 049init.linux 0*.subx apps/subx-common.subx apps/dquotes.subx -o apps/dquotes
|
||||
test "$1" = 'record' || git diff --exit-code apps/dquotes
|
||||
test $EMULATED && {
|
||||
./subx run apps/dquotes test
|
||||
|
@ -284,7 +284,7 @@ test $NATIVE && {
|
|||
}
|
||||
|
||||
echo tests
|
||||
./subx translate 0*.subx apps/subx-common.subx apps/tests.subx -o apps/tests
|
||||
./subx translate 049init.linux 0*.subx apps/subx-common.subx apps/tests.subx -o apps/tests
|
||||
test "$1" = 'record' || git diff --exit-code apps/tests
|
||||
test $EMULATED && {
|
||||
./subx run apps/tests test
|
||||
|
@ -298,7 +298,7 @@ test $NATIVE && {
|
|||
# Higher-level syntax.
|
||||
|
||||
echo sigils
|
||||
./subx translate 0*.subx apps/subx-common.subx apps/sigils.subx -o apps/sigils
|
||||
./subx translate 049init.linux 0*.subx apps/subx-common.subx apps/sigils.subx -o apps/sigils
|
||||
[ "$1" != record ] && git diff --exit-code apps/sigils
|
||||
./subx run apps/sigils test
|
||||
echo
|
||||
|
@ -313,7 +313,7 @@ test $NATIVE || exit 0
|
|||
|
||||
echo calls
|
||||
cat 0*.subx apps/subx-common.subx apps/calls.subx | apps/sigils > a.sigils
|
||||
./subx translate a.sigils -o apps/calls
|
||||
./subx translate 049init.linux a.sigils -o apps/calls
|
||||
[ "$1" != record ] && git diff --exit-code apps/calls
|
||||
./subx run apps/calls test
|
||||
echo
|
||||
|
@ -329,7 +329,7 @@ echo "== translating using SubX"
|
|||
for n in `seq 1 12`
|
||||
do
|
||||
echo ex$n
|
||||
./ntranslate examples/ex$n.subx
|
||||
./ntranslate 049init.linux examples/ex$n.subx
|
||||
diff examples/ex$n a.elf
|
||||
done
|
||||
|
||||
|
@ -338,7 +338,7 @@ done
|
|||
for app in factorial crenshaw2-1 crenshaw2-1b handle
|
||||
do
|
||||
echo $app
|
||||
./ntranslate 0*.subx apps/$app.subx
|
||||
./ntranslate 049init.linux 0*.subx apps/$app.subx
|
||||
diff apps/$app a.elf
|
||||
done
|
||||
|
||||
|
@ -347,7 +347,7 @@ done
|
|||
for app in hex survey pack assort dquotes tests sigils calls
|
||||
do
|
||||
echo $app
|
||||
./ntranslate 0*.subx apps/subx-common.subx apps/$app.subx
|
||||
./ntranslate 049init.linux 0*.subx apps/subx-common.subx apps/$app.subx
|
||||
diff apps/$app a.elf
|
||||
done
|
||||
|
||||
|
|
Loading…
Reference in New Issue