diff options
author | Kartik Agaram <vc@akkartik.com> | 2019-07-27 16:01:55 -0700 |
---|---|---|
committer | Kartik Agaram <vc@akkartik.com> | 2019-07-27 17:47:59 -0700 |
commit | 6e1eeeebfb453fa7c871869c19375ce60fbd7413 (patch) | |
tree | 539c4a3fdf1756ae79770d5c4aaf6366f1d1525e /subx/examples | |
parent | 8846a7f85cc04b77b2fe8a67b6d317723437b00c (diff) | |
download | mu-6e1eeeebfb453fa7c871869c19375ce60fbd7413.tar.gz |
5485 - promote SubX to top-level
Diffstat (limited to 'subx/examples')
-rw-r--r-- | subx/examples/Readme.md | 6 | ||||
-rwxr-xr-x | subx/examples/ex1 | bin | 128 -> 0 bytes | |||
-rw-r--r-- | subx/examples/ex1.subx | 21 | ||||
-rwxr-xr-x | subx/examples/ex10 | bin | 195 -> 0 bytes | |||
-rw-r--r-- | subx/examples/ex10.subx | 72 | ||||
-rwxr-xr-x | subx/examples/ex11 | bin | 1111 -> 0 bytes | |||
-rw-r--r-- | subx/examples/ex11.subx | 357 | ||||
-rwxr-xr-x | subx/examples/ex12 | bin | 167 -> 0 bytes | |||
-rw-r--r-- | subx/examples/ex12.subx | 45 | ||||
-rwxr-xr-x | subx/examples/ex2 | bin | 129 -> 0 bytes | |||
-rw-r--r-- | subx/examples/ex2.subx | 23 | ||||
-rwxr-xr-x | subx/examples/ex3 | bin | 146 -> 0 bytes | |||
-rw-r--r-- | subx/examples/ex3.subx | 39 | ||||
-rwxr-xr-x | subx/examples/ex4 | bin | 171 -> 0 bytes | |||
-rw-r--r-- | subx/examples/ex4.subx | 42 | ||||
-rwxr-xr-x | subx/examples/ex5 | bin | 171 -> 0 bytes | |||
-rw-r--r-- | subx/examples/ex5.subx | 45 | ||||
-rwxr-xr-x | subx/examples/ex6 | bin | 165 -> 0 bytes | |||
-rw-r--r-- | subx/examples/ex6.subx | 37 | ||||
-rwxr-xr-x | subx/examples/ex7 | bin | 313 -> 0 bytes | |||
-rw-r--r-- | subx/examples/ex7.subx | 107 | ||||
-rwxr-xr-x | subx/examples/ex8 | bin | 165 -> 0 bytes | |||
-rw-r--r-- | subx/examples/ex8.subx | 61 | ||||
-rwxr-xr-x | subx/examples/ex9 | bin | 159 -> 0 bytes | |||
-rw-r--r-- | subx/examples/ex9.subx | 55 |
25 files changed, 0 insertions, 910 deletions
diff --git a/subx/examples/Readme.md b/subx/examples/Readme.md deleted file mode 100644 index d4bb1ff5..00000000 --- a/subx/examples/Readme.md +++ /dev/null @@ -1,6 +0,0 @@ -Small example programs, each with a simple pedagogical goal. - -They also help to validate SubX instruction semantics against native x86 -hardware. For example, loading a single byte to a register would for some time -clear the rest of the register. This behavior was internally consistent with -unit tests. It took running an example binary natively to catch the discrepancy. diff --git a/subx/examples/ex1 b/subx/examples/ex1 deleted file mode 100755 index aeb62302..00000000 --- a/subx/examples/ex1 +++ /dev/null Binary files differdiff --git a/subx/examples/ex1.subx b/subx/examples/ex1.subx deleted file mode 100644 index 0aca40f8..00000000 --- a/subx/examples/ex1.subx +++ /dev/null @@ -1,21 +0,0 @@ -# First program: same as https://www.muppetlabs.com/~breadbox/software/tiny/teensy.html -# Just return 42. -# -# To run (from the subx directory): -# $ ./subx translate examples/ex1.2.subx -o examples/ex1 -# $ ./subx run examples/ex1 -# Expected result: -# $ echo $? -# 42 - -== code 0x09000000 - -Entry: -# syscall(exit, 42) -bb/copy-to-EBX 2a/imm32 # 42 in hex -b8/copy-to-EAX 1/imm32/exit -cd/syscall 0x80/imm8 - -== data 0x0a000000 - -# . . vim:nowrap:textwidth=0 diff --git a/subx/examples/ex10 b/subx/examples/ex10 deleted file mode 100755 index d8ad528e..00000000 --- a/subx/examples/ex10 +++ /dev/null Binary files differdiff --git a/subx/examples/ex10.subx b/subx/examples/ex10.subx deleted file mode 100644 index 51cc0a8c..00000000 --- a/subx/examples/ex10.subx +++ /dev/null @@ -1,72 +0,0 @@ -# String comparison: return 1 iff the two args passed in at the commandline are equal. -# -# To run (from the subx directory): -# $ ./subx translate examples/ex10.subx -o examples/ex10 -# $ ./subx run examples/ex10 abc abd -# Expected result: -# $ echo $? -# 0 # false - -== code 0x09000000 -# 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: # return argv-equal(argv[1], argv[2]) -# At the start of a SubX program: -# argc: *ESP -# argv[0]: *(ESP+4) -# argv[1]: *(ESP+8) -# ... - # . prolog - 89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP - # argv-equal(argv[1], argv[2]) - # . . push argv[2] - ff 6/subop/push 1/mod/*+disp8 5/rm32/EBP . . . . 0xc/disp8 . # push *(EBP+12) - # . . push argv[1] - ff 6/subop/push 1/mod/*+disp8 5/rm32/EBP . . . . 8/disp8 . # push *(EBP+8) - # . . call - e8/call argv-equal/disp32 - # syscall(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 - -# 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 - # 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 -$argv-equal:loop: - # c1/EAX, c2/EBX = *s1, *s2 - b8/copy-to-EAX 0/imm32 - 8a/copy-byte 0/mod/indirect 1/rm32/ECX . . . 0/r32/AL . . # copy byte at *ECX to AL - bb/copy-to-EBX 0/imm32 - 8a/copy-byte 0/mod/indirect 2/rm32/EDX . . . 3/r32/BL . . # copy byte at *EDX to BL - # if (c1 == 0) break - 3d/compare-EAX-and 0/imm32 - 74/jump-if-equal $argv-equal:break/disp8 - # if (c1 != c2) return false - 39/compare 3/mod/direct 0/rm32/EAX . . . 3/r32/EBX . . # compare EAX and EBX - 75/jump-if-not-equal $argv-equal:false/disp8 - # ++s1, ++s2 - 41/increment-ECX - 42/increment-EDX - # end while - eb/jump $argv-equal:loop/disp8 -$argv-equal:break: - # if (c2 == 0) return true - 81 7/subop/compare 3/mod/direct 3/rm32/EBX . . . . . 0/imm32 # compare EBX - 75/jump-if-not-equal $argv-equal:false/disp8 -$argv-equal:success: - b8/copy-to-EAX 1/imm32 - c3/return - # return false -$argv-equal:false: - b8/copy-to-EAX 0/imm32 - c3/return - -== data 0x0a000000 - -# . . vim:nowrap:textwidth=0 diff --git a/subx/examples/ex11 b/subx/examples/ex11 deleted file mode 100755 index 0ffafb6f..00000000 --- a/subx/examples/ex11 +++ /dev/null Binary files differdiff --git a/subx/examples/ex11.subx b/subx/examples/ex11.subx deleted file mode 100644 index ba75c1d3..00000000 --- a/subx/examples/ex11.subx +++ /dev/null @@ -1,357 +0,0 @@ -# Null-terminated vs length-prefixed ascii strings. -# -# By default we create strings with a 4-byte length prefix rather than a null suffix. -# However we still need null-prefixed strings when interacting with the Linux -# kernel in a few places. This layer implements a function for comparing -# a null-terminated 'kernel string' with a length-prefixed 'SubX string'. -# -# To run (from the subx directory): -# $ ./subx translate examples/ex11.subx -o examples/ex11 -# $ ./subx run examples/ex11 # runs a series of tests -# ...... # all tests pass -# -# (We can't yet run the tests when given a "test" commandline argument, -# 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 -# 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) - 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 - -# 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 - # pseudocode: - # n = benchmark->length - # s1 = s - # s2 = benchmark->data - # i = 0 - # while i < n - # c1 = *s1 - # c2 = *s2 - # if (c1 == 0) return false - # if (c1 != c2) return false - # ++s1, ++s2, ++i - # return *s1 == 0 - # - # registers: - # i: ECX - # n: EDX - # s1: EDI - # s2: ESI - # c1: EAX - # c2: EBX - # - # . prolog - 55/push-EBP - 89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP - # . save registers - 51/push-ECX - 52/push-EDX - 53/push-EBX - 56/push-ESI - 57/push-EDI - # s1/EDI = s - 8b/copy 1/mod/*+disp8 5/rm32/EBP . . . 7/r32/EDI 8/disp8 . # copy *(EBP+8) to EDI - # n/EDX = benchmark->length - 8b/copy 1/mod/*+disp8 5/rm32/EBP . . . 2/r32/EDX 0xc/disp8 . # copy *(EBP+12) to EDX - 8b/copy 0/mod/indirect 2/rm32/EDX . . . 2/r32/EDX . . # copy *EDX to EDX - # s2/ESI = benchmark->data - 8b/copy 1/mod/*+disp8 5/rm32/EBP . . . 6/r32/ESI 0xc/disp8 . # copy *(EBP+12) to ESI - 81 0/subop/add 3/mod/direct 6/rm32/ESI . . . . . 4/imm32 # add to ESI - # i/ECX = c1/EAX = c2/EBX = 0 - b9/copy-to-ECX 0/imm32/exit - b8/copy-to-EAX 0/imm32 - bb/copy-to-EBX 0/imm32 -$kernel-string-equal?:loop: - # if (i >= n) break - 39/compare 3/mod/direct 1/rm32/ECX . . . 2/r32/EDX . . # compare ECX with EDX - 7d/jump-if-greater-or-equal $kernel-string-equal?:break/disp8 - # c1 = *s1 - 8a/copy-byte 0/mod/indirect 7/rm32/EDI . . . 0/r32/AL . . # copy byte at *EDI to AL - # c2 = *s2 - 8a/copy-byte 0/mod/indirect 6/rm32/ESI . . . 3/r32/BL . . # copy byte at *ESI to BL - # if (c1 == 0) return false - 3d/compare-EAX-and 0/imm32 - 74/jump-if-equal $kernel-string-equal?:false/disp8 - # if (c1 != c2) return false - 39/compare 3/mod/direct 0/rm32/EAX . . . 3/r32/EBX . . # compare EAX and EBX - 75/jump-if-not-equal $kernel-string-equal?:false/disp8 - # ++i - 41/increment-ECX - # ++s1 - 47/increment-EDI - # ++s2 - 46/increment-ESI - eb/jump $kernel-string-equal?:loop/disp8 -$kernel-string-equal?:break: - # return *s1 == 0 - 8a/copy-byte 0/mod/indirect 7/rm32/EDI . . . 0/r32/AL . . # copy byte at *EDI to AL - 3d/compare-EAX-and 0/imm32 - 75/jump-if-not-equal $kernel-string-equal?:false/disp8 -$kernel-string-equal?:true: - b8/copy-to-EAX 1/imm32 - eb/jump $kernel-string-equal?:end/disp8 -$kernel-string-equal?:false: - b8/copy-to-EAX 0/imm32 -$kernel-string-equal?:end: - # . restore registers - 5f/pop-to-EDI - 5e/pop-to-ESI - 5b/pop-to-EBX - 5a/pop-to-EDX - 59/pop-to-ECX - # . epilog - 89/copy 3/mod/direct 4/rm32/ESP . . . 5/r32/EBP . . # copy EBP to ESP - 5d/pop-to-EBP - c3/return - -# - tests - -test-compare-null-kernel-string-with-empty-array: - # EAX = kernel-string-equal?(Null-kernel-string, "") - # . . push args - 68/push ""/imm32 - 68/push Null-kernel-string/imm32 - # . . call - e8/call kernel-string-equal?/disp32 - # . . discard args - 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP - # check-ints-equal(EAX, 1, msg) - # . . push args - 68/push "F - test-compare-null-kernel-string-with-empty-array"/imm32 - 68/push 1/imm32/true - 50/push-EAX - # . . call - e8/call check-ints-equal/disp32 - # . . discard args - 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP - c3/return - -test-compare-null-kernel-string-with-non-empty-array: - # EAX = kernel-string-equal?(Null-kernel-string, "Abc") - # . . push args - 68/push "Abc"/imm32 - 68/push Null-kernel-string/imm32 - # . . call - e8/call kernel-string-equal?/disp32 - # . . discard args - 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP - # check-ints-equal(EAX, 0, msg) - # . . push args - 68/push "F - test-compare-null-kernel-string-with-non-empty-array"/imm32 - 68/push 0/imm32/false - 50/push-EAX - # . . call - e8/call check-ints-equal/disp32 - # . . discard args - 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP - c3/return - -test-compare-kernel-string-with-equal-array: - # EAX = kernel-string-equal?(_test-Abc-kernel-string, "Abc") - # . . push args - 68/push "Abc"/imm32 - 68/push _test-Abc-kernel-string/imm32 - # . . call - e8/call kernel-string-equal?/disp32 - # . . discard args - 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP - # check-ints-equal(EAX, 1, msg) - # . . push args - 68/push "F - test-compare-kernel-string-with-equal-array"/imm32 - 68/push 1/imm32/true - 50/push-EAX - # . . call - e8/call check-ints-equal/disp32 - # . . discard args - 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP - c3/return - -test-compare-kernel-string-with-inequal-array: - # EAX = kernel-string-equal?(_test-Abc-kernel-string, "Adc") - # . . push args - 68/push "Adc"/imm32 - 68/push _test-Abc-kernel-string/imm32 - # . . call - e8/call kernel-string-equal?/disp32 - # . . discard args - 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP - # check-ints-equal(EAX, 0, msg) - # . . push args - 68/push "F - test-compare-kernel-string-with-equal-array"/imm32 - 68/push 0/imm32/false - 50/push-EAX - # . . call - e8/call check-ints-equal/disp32 - # . . discard args - 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP - c3/return - -test-compare-kernel-string-with-empty-array: - # EAX = kernel-string-equal?(_test-Abc-kernel-string, "") - # . . push args - 68/push ""/imm32 - 68/push _test-Abc-kernel-string/imm32 - # . . call - e8/call kernel-string-equal?/disp32 - # . . discard args - 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP - # check-ints-equal(EAX, 0, msg) - # . . push args - 68/push "F - test-compare-kernel-string-with-equal-array"/imm32 - 68/push 0/imm32/false - 50/push-EAX - # . . call - e8/call check-ints-equal/disp32 - # . . discard args - 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP - c3/return - -test-compare-kernel-string-with-shorter-array: - # EAX = kernel-string-equal?(_test-Abc-kernel-string, "Ab") - # . . push args - 68/push "Ab"/imm32 - 68/push _test-Abc-kernel-string/imm32 - # . . call - e8/call kernel-string-equal?/disp32 - # . . discard args - 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP - # check-ints-equal(EAX, 0, msg) - # . . push args - 68/push "F - test-compare-kernel-string-with-shorter-array"/imm32 - 68/push 0/imm32/false - 50/push-EAX - # . . call - e8/call check-ints-equal/disp32 - # . . discard args - 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP - c3/return - -test-compare-kernel-string-with-longer-array: - # EAX = kernel-string-equal?(_test-Abc-kernel-string, "Abcd") - # . . push args - 68/push "Abcd"/imm32 - 68/push _test-Abc-kernel-string/imm32 - # . . call - e8/call kernel-string-equal?/disp32 - # . . discard args - 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP - # check-ints-equal(EAX, 0, msg) - # . . push args - 68/push "F - test-compare-kernel-string-with-longer-array"/imm32 - 68/push 0/imm32/false - 50/push-EAX - # . . call - e8/call check-ints-equal/disp32 - # . . discard args - 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP - c3/return - -# - helpers - -# print msg to stderr if a != b, otherwise print "." -check-ints-equal: # (a : int, b : int, msg : (address array byte)) -> boolean - # . prolog - 55/push-EBP - 89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP - # . save registers - 51/push-ECX - 53/push-EBX - # load args into EAX, EBX and ECX - 8b/copy 1/mod/*+disp8 5/rm32/EBP . . . 0/r32/EAX 8/disp8 . # copy *(EBP+8) to EAX - 8b/copy 1/mod/*+disp8 5/rm32/EBP . . . 3/r32/EBX 0xc/disp8 . # copy *(EBP+12) to EBX - # if (EAX == b/EBX) print('.') and return - 39/compare 3/mod/direct 0/rm32/EAX . . . 3/r32/EBX . . # compare EAX and EBX - 75/jump-if-unequal $check-ints-equal:else/disp8 - # . write-stderr('.') - # . . push args - 68/push "."/imm32 - # . . call - e8/call write-stderr/disp32 - # . . discard args - 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP - # . return - eb/jump $check-ints-equal:end/disp8 - # otherwise print(msg) -$check-ints-equal:else: - # copy msg into ECX - 8b/copy 1/mod/*+disp8 5/rm32/EBP . . . 1/r32/ECX 0x10/disp8 . # copy *(EBP+16) to ECX - # print(ECX) - # . . push args - 51/push-ECX - # . . call - e8/call write-stderr/disp32 - # . . discard args - 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP - # print newline - # . . push args - 68/push Newline/imm32 - # . . call - e8/call write-stderr/disp32 - # . . discard args - 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP -$check-ints-equal:end: - # . restore registers - 5b/pop-to-EBX - 59/pop-to-ECX - # end - 89/copy 3/mod/direct 4/rm32/ESP . . . 5/r32/EBP . . # copy EBP to ESP - 5d/pop-to-EBP - c3/return - -write-stderr: # s : (address array byte) -> <void> - # . prolog - 55/push-EBP - 89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP - # . save registers - 50/push-EAX - 51/push-ECX - 52/push-EDX - 53/push-EBX - # syscall(write, 2/stderr, (data) s+4, (size) *s) - # . . fd = 2 (stderr) - bb/copy-to-EBX 2/imm32 - # . . x = s+4 - 8b/copy 1/mod/*+disp8 5/rm32/EBP . . . 1/r32/ECX 8/disp8 . # copy *(EBP+8) to ECX - 81 0/subop/add 3/mod/direct 1/rm32/ECX . . . . . 4/imm32 # add to ECX - # . . size = *s - 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 - # . restore registers - 5b/pop-to-EBX - 5a/pop-to-EDX - 59/pop-to-ECX - 58/pop-to-EAX - # . end - 89/copy 3/mod/direct 4/rm32/ESP . . . 5/r32/EBP . . # copy EBP to ESP - 5d/pop-to-EBP - c3/return - -== data 0x0a000000 - -Newline: - # size - 1/imm32 - # data - 0a/newline - -# for kernel-string-equal tests -Null-kernel-string: - 00/null - -_test-Abc-kernel-string: - 41/A 62/b 63/c 00/null - -# . . vim:nowrap:textwidth=0 diff --git a/subx/examples/ex12 b/subx/examples/ex12 deleted file mode 100755 index c13a86ed..00000000 --- a/subx/examples/ex12 +++ /dev/null Binary files differdiff --git a/subx/examples/ex12.subx b/subx/examples/ex12.subx deleted file mode 100644 index 358da1d3..00000000 --- a/subx/examples/ex12.subx +++ /dev/null @@ -1,45 +0,0 @@ -# Example showing mmap syscall. -# Create a new segment using mmap, save the address, write to it. -# -# To run (from the subx directory): -# $ ./subx translate examples/ex12.subx -o examples/ex12 -# $ ./subx run examples/ex12 -# You shouldn't get a segmentation fault. - -== code 0x09000000 -# 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) - bb/copy-to-EBX Mmap-new-segment/imm32 - b8/copy-to-EAX 0x5a/imm32/mmap - cd/syscall 0x80/imm8 - - # 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) - 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 - -== data 0x0a000000 - -# various constants used here were found in the Linux sources (search for file mman-common.h) -Mmap-new-segment: # type mmap_arg_struct - # addr - 0/imm32 - # len - 0x100/imm32 - # protection flags - 3/imm32 # PROT_READ | PROT_WRITE - # sharing flags - 0x22/imm32 # MAP_PRIVATE | MAP_ANONYMOUS - # fd - -1/imm32 # since MAP_ANONYMOUS is specified - # offset - 0/imm32 # since MAP_ANONYMOUS is specified - -# . . vim:nowrap:textwidth=0 diff --git a/subx/examples/ex2 b/subx/examples/ex2 deleted file mode 100755 index 55a87a3f..00000000 --- a/subx/examples/ex2 +++ /dev/null Binary files differdiff --git a/subx/examples/ex2.subx b/subx/examples/ex2.subx deleted file mode 100644 index 025eb0fa..00000000 --- a/subx/examples/ex2.subx +++ /dev/null @@ -1,23 +0,0 @@ -# Add 1 and 1, and return the result in the exit code. -# -# To run (from the subx directory): -# $ ./subx translate examples/ex2.subx -o examples/ex2 -# $ ./subx run examples/ex2 -# Expected result: -# $ echo $? -# 2 - -== code 0x09000000 - -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 - -# . . vim:nowrap:textwidth=0 diff --git a/subx/examples/ex3 b/subx/examples/ex3 deleted file mode 100755 index d85aba8e..00000000 --- a/subx/examples/ex3 +++ /dev/null Binary files differdiff --git a/subx/examples/ex3.subx b/subx/examples/ex3.subx deleted file mode 100644 index 1d52e87f..00000000 --- a/subx/examples/ex3.subx +++ /dev/null @@ -1,39 +0,0 @@ -# Add the first 10 numbers, and return the result in the exit code. -# -# To run (from the subx directory): -# $ ./subx translate examples/ex3.subx -o examples/ex3 -# $ ./subx run examples/ex3 -# Expected result: -# $ echo $? -# 55 - -== code 0x09000000 -# 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: - # result: EBX = 0 - bb/copy-to-EBX 0/imm32 - # counter: ECX = 1 - b9/copy-to-ECX 1/imm32 - -$loop: - # if (counter > 10) break - 81 7/subop/compare 3/mod/direct 1/rm32/ECX . . . . . 0xa/imm32 # compare ECX - 7f/jump-if-greater $exit/disp8 - # result += counter - 01/add 3/mod/direct 3/rm32/EBX . . . 1/r32/ECX . . # add ECX to EBX - # ++counter - 41/increment-ECX - # loop - eb/jump $loop/disp8 - -$exit: - # syscall(exit, EBX) - b8/copy-to-EAX 1/imm32/exit - cd/syscall 0x80/imm8 - -== data 0x0a000000 - -# . . vim:nowrap:textwidth=0 diff --git a/subx/examples/ex4 b/subx/examples/ex4 deleted file mode 100755 index 66fb61e6..00000000 --- a/subx/examples/ex4 +++ /dev/null Binary files differdiff --git a/subx/examples/ex4.subx b/subx/examples/ex4.subx deleted file mode 100644 index 31c1c10c..00000000 --- a/subx/examples/ex4.subx +++ /dev/null @@ -1,42 +0,0 @@ -# Read a character from stdin, save it to a global, write it to stdout. -# -# To run (from the subx directory): -# $ ./subx translate examples/ex4.subx -o examples/ex4 -# $ ./subx run examples/ex4 - -== data 0x0a000000 - -# the global variable we save to -X: - 0/imm32 # space for read() to write to - -== code 0x09000000 - -Entry: -# syscall(read, stdin, X, 1) -# . fd = 0 (stdin) -bb/copy-to-EBX 0/imm32 -# . data = X (location to write result to) -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 - -# syscall(write, stdout, X, 1) -# . fd = 1 (stdout) -bb/copy-to-EBX 1/imm32 -# . initialize X (location to read from) -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 - -# syscall(exit, EBX) -b8/copy-to-EAX 1/imm32/exit -cd/syscall 0x80/imm8 - -# . . vim:nowrap:textwidth=0 diff --git a/subx/examples/ex5 b/subx/examples/ex5 deleted file mode 100755 index 37689c98..00000000 --- a/subx/examples/ex5 +++ /dev/null Binary files differdiff --git a/subx/examples/ex5.subx b/subx/examples/ex5.subx deleted file mode 100644 index 6f5b1d90..00000000 --- a/subx/examples/ex5.subx +++ /dev/null @@ -1,45 +0,0 @@ -# Read a character from stdin, save it to a local on the stack, write it to stdout. -# -# To run (from the subx directory): -# $ ./subx translate examples/ex5.subx -o examples/ex5 -# $ ./subx run examples/ex5 - -== code 0x09000000 -# 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: - - # 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) - # . fd = 0 (stdin) - bb/copy-to-EBX 0/imm32 - # . data = x (location to write result to) - 8d/copy-address 1/mod/*+disp8 4/rm32/sib 4/base/ESP 4/index/none 1/r32/ECX 4/disp8 . # copy ESP+4 to ECX - # . size = 1 character - ba/copy-to-EDX 1/imm32 - # . syscall - b8/copy-to-EAX 3/imm32/read - cd/syscall 0x80/imm8 - - # syscall(write, stdout, x, 1) - # . fd = 1 (stdout) - bb/copy-to-EBX 1/imm32 - # . data = x (location to read from) - 8d/copy-address 1/mod/*+disp8 4/rm32/sib 4/base/ESP 4/index/none 1/r32/ECX 4/disp8 . # copy ESP+4 to ECX - # . size = 1 character - ba/copy-to-EDX 1/imm32 - # . syscall - 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 - -# . . vim:nowrap:textwidth=0 diff --git a/subx/examples/ex6 b/subx/examples/ex6 deleted file mode 100755 index aa84591c..00000000 --- a/subx/examples/ex6 +++ /dev/null Binary files differdiff --git a/subx/examples/ex6.subx b/subx/examples/ex6.subx deleted file mode 100644 index a90f11df..00000000 --- a/subx/examples/ex6.subx +++ /dev/null @@ -1,37 +0,0 @@ -# Print out a (global variable) string to stdout. -# -# To run (from the subx directory): -# $ ./subx translate examples/ex6.subx -o examples/ex6 -# $ ./subx run examples/ex6 -# Hello, world! - -== code 0x09000000 -# 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(write, stdout, X, Size) - # . fd = 1 (stdout) - bb/copy-to-EBX 1/imm32 - # . initialize X (location to write result to) - b9/copy-to-ECX X/imm32 - # . 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 - - # syscall(exit, EBX) - b8/copy-to-EAX 1/imm32/exit - cd/syscall 0x80/imm8 - -== data 0x0a000000 - -Size: # size of string - 0x0e/imm32 # 14 -X: # string to print - 48 65 6c 6c 6f 2c 20 77 6f 72 6c 64 21 0a 00 -# H e l l o , ␣ w o r l d ! newline null - -# . . vim:nowrap:textwidth=0 diff --git a/subx/examples/ex7 b/subx/examples/ex7 deleted file mode 100755 index 28c5bda9..00000000 --- a/subx/examples/ex7 +++ /dev/null Binary files differdiff --git a/subx/examples/ex7.subx b/subx/examples/ex7.subx deleted file mode 100644 index d3b33f23..00000000 --- a/subx/examples/ex7.subx +++ /dev/null @@ -1,107 +0,0 @@ -# Example showing file syscalls. -# -# Create a file, open it for writing, write a character to it, close it, open -# it for reading, read a character from it, close it, delete it, and return -# the character read. -# -# To run (from the subx directory): -# $ ./subx translate examples/ex7.subx -o examples/ex7 -# $ ./subx run examples/ex7 -# Expected result: -# $ echo $? -# 97 - -== code 0x09000000 -# 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) - 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 - - # stream = syscall(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 - # 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) - # . 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 - - # syscall(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 - - # stream = syscall(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 - # . 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) - # . 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 - - # syscall(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 - - # syscall(unlink, filename) - bb/copy-to-EBX Filename/imm32 - b8/copy-to-EAX 0xa/imm32/unlink - cd/syscall 0x80/imm8 - - # syscall(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 - -== data 0x0a000000 - -Stream: - 0/imm32 -A: - 61/imm32/A -B: - 0/imm32 -Filename: - 2e 66 6f 6f 00 00 00 00 -# . f o o null - -# . . vim:nowrap:textwidth=0 diff --git a/subx/examples/ex8 b/subx/examples/ex8 deleted file mode 100755 index 5be0e1e6..00000000 --- a/subx/examples/ex8 +++ /dev/null Binary files differdiff --git a/subx/examples/ex8.subx b/subx/examples/ex8.subx deleted file mode 100644 index 9d7255e1..00000000 --- a/subx/examples/ex8.subx +++ /dev/null @@ -1,61 +0,0 @@ -# Example reading commandline arguments: compute length of first arg. -# -# To run (from the subx directory): -# $ ./subx translate examples/ex8.subx -o examples/ex8 -# $ ./subx run examples/ex8 abc de fghi -# Expected result: -# $ echo $? -# 3 # length of 'abc' -# -# At the start of a SubX program: -# argc: *ESP -# argv[0]: *(ESP+4) -# argv[1]: *(ESP+8) -# ... -# Locals start from ESP-4 downwards. - -== code 0x09000000 -# 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: - # . prolog - 89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP - # EAX = ascii-length(argv[1]) - # . . push args - ff 6/subop/push 1/mod/*+disp8 5/rm32/EBP . . . . 8/disp8 . # push *(EBP+8) - # . . call - e8/call ascii-length/disp32 - # . . discard args - 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP - - # 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 - -ascii-length: # s : (address 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 - b8/copy-to-EAX 0/imm32 -$ascii-length:loop: - # var c/ECX = *s - 8a/copy-byte 0/mod/* 2/rm32/EDX . . . 1/r32/CL . . # copy byte at *EDX to CL - # if (c == '\0') break - 81 7/subop/compare 3/mod/direct 1/rm32/ECX . . . . . 0/imm32 # compare ECX - 74/jump-if-equal $ascii-length:end/disp8 - # ++s - 42/increment-EDX - # ++result - 40/increment-EAX - # loop - eb/jump $ascii-length:loop/disp8 -$ascii-length:end: - # return EAX - c3/return - -== data 0x0a000000 - -# . . vim:nowrap:textwidth=0 diff --git a/subx/examples/ex9 b/subx/examples/ex9 deleted file mode 100755 index fce7629c..00000000 --- a/subx/examples/ex9 +++ /dev/null Binary files differdiff --git a/subx/examples/ex9.subx b/subx/examples/ex9.subx deleted file mode 100644 index e3318b05..00000000 --- a/subx/examples/ex9.subx +++ /dev/null @@ -1,55 +0,0 @@ -# Example showing arg order on the stack. -# -# Show difference between ascii codes of first letter of first arg and first -# letter of second arg. -# -# To run (from the subx directory): -# $ ./subx translate examples/ex9.subx -o examples/ex9 -# $ ./subx run examples/ex9 z x -# Expected result: -# $ echo $? -# 2 -# -# At the start of a SubX program: -# argc: *ESP -# argv[0]: *(ESP+4) -# argv[1]: *(ESP+8) -# ... -# Locals start from ESP-4 downwards. - -== code 0x09000000 -# 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: - # . prolog - 89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP - # ascii-difference(argv[1], argv[2]) - # . . push argv[2] - ff 6/subop/push 1/mod/*+disp8 5/rm32/EBP . . . . 0xc/disp8 . # push *(EBP+12) - # . . push argv[1] - ff 6/subop/push 1/mod/*+disp8 5/rm32/EBP . . . . 8/disp8 . # push *(EBP+8) - # . . call - 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) - 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 - -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 - # b = first letter of s2 (EDX) - 8b/copy 1/mod/*+disp8 4/rm32/sib 4/base/ESP 4/index/none 1/r32/ECX 8/disp8 # copy *(ESP+8) to ECX - 8b/copy 0/mod/indirect 1/rm32/ECX . . . 1/r32/ECX . . # copy *ECX to ECX - # a-b - 29/subtract 3/mod/direct 0/rm32/EAX . . . 1/r32/ECX . . # subtract ECX from EAX - c3/return - -== data 0x0a000000 - -# . . vim:nowrap:textwidth=0 |