diff options
author | Kartik Agaram <vc@akkartik.com> | 2018-11-30 11:10:44 -0800 |
---|---|---|
committer | Kartik Agaram <vc@akkartik.com> | 2018-11-30 11:13:36 -0800 |
commit | ee9a9237d6324f1de1bb7150083eacf7b9af5f70 (patch) | |
tree | 86180456f2a3cf5503783afc78856280f088a863 | |
parent | 6030d7e2e56d445ca67c6a0e8c9cf33e46bc673c (diff) | |
download | mu-ee9a9237d6324f1de1bb7150083eacf7b9af5f70.tar.gz |
4802
Some automated commenting cleanup. Still needs more careful manual scanning. sed -i 's/^# 1-3/# . 1-3/' *.subx */*.subx sed -i 's/^# op/# . op/' *.subx */*.subx sed -i 's/# vim/# . . vim/' *.subx */*.subx sed -i 's/^ # push args/ # . . push args/' *.subx */*.subx sed -i 's/^ # discard args/ # . . discard args/' *.subx */*.subx sed -i 's/^ # call/ # . . call/' *.subx */*.subx sed -i 's/^ # prolog/ # . prolog/' *.subx */*.subx sed -i 's/^ # epilog/ # . epilog/' *.subx */*.subx sed -i 's/^ # save registers/ # . save registers/' *.subx */*.subx sed -i 's/^ # restore registers/ # . restore registers/' *.subx */*.subx sed -i 's/ operand / register /' *.subx */*.subx
-rw-r--r-- | subx/050_write.subx | 24 | ||||
-rw-r--r-- | subx/051test.subx | 34 | ||||
-rw-r--r-- | subx/052kernel_string_equal.subx | 114 | ||||
-rw-r--r-- | subx/053new_segment.subx | 18 | ||||
-rw-r--r-- | subx/054string_equal.subx | 72 | ||||
-rw-r--r-- | subx/055trace.subx | 118 | ||||
-rw-r--r-- | subx/056write.subx | 82 | ||||
-rw-r--r-- | subx/057stop.subx | 64 | ||||
-rw-r--r-- | subx/058read.subx | 148 | ||||
-rw-r--r-- | subx/059read-byte.subx | 118 | ||||
-rw-r--r-- | subx/060write-stream.subx | 106 | ||||
-rw-r--r-- | subx/apps/crenshaw2-1.subx | 58 | ||||
-rw-r--r-- | subx/apps/crenshaw2-1b.subx | 420 | ||||
-rw-r--r-- | subx/apps/factorial.subx | 44 | ||||
-rw-r--r-- | subx/examples/ex1.subx | 2 | ||||
-rw-r--r-- | subx/examples/ex10.subx | 14 | ||||
-rw-r--r-- | subx/examples/ex11.subx | 142 | ||||
-rw-r--r-- | subx/examples/ex12.subx | 8 | ||||
-rw-r--r-- | subx/examples/ex2.subx | 2 | ||||
-rw-r--r-- | subx/examples/ex3.subx | 8 | ||||
-rw-r--r-- | subx/examples/ex4.subx | 2 | ||||
-rw-r--r-- | subx/examples/ex5.subx | 8 | ||||
-rw-r--r-- | subx/examples/ex6.subx | 8 | ||||
-rw-r--r-- | subx/examples/ex7.subx | 8 | ||||
-rw-r--r-- | subx/examples/ex8.subx | 18 | ||||
-rw-r--r-- | subx/examples/ex9.subx | 16 |
26 files changed, 828 insertions, 828 deletions
diff --git a/subx/050_write.subx b/subx/050_write.subx index 1975f7a3..bb0f20e1 100644 --- a/subx/050_write.subx +++ b/subx/050_write.subx @@ -1,9 +1,9 @@ # _write: write to a file descriptor == code -# instruction effective address operand 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 +# 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 # main: # syscall(exit, 0) -- can't test _write just yet @@ -12,34 +12,34 @@ cd/syscall 0x80/imm8 _write: # fd : int, s : (address array byte) -> <void> - # prolog + # . prolog 55/push-EBP 89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP - # save registers + # . save registers 50/push-EAX 51/push-ECX 52/push-EDX 53/push-EBX # syscall(write, fd, (data) s+4, (size) *s) - # fd : EBX + # . fd : EBX 8b/copy 1/mod/*+disp8 4/rm32/sib 5/base/EBP 4/index/none . 3/r32/EBX 8/disp8 . # copy *(EBP+8) to EBX - # data : ECX = s+4 + # . data : ECX = s+4 8b/copy 1/mod/*+disp8 4/rm32/sib 5/base/EBP 4/index/none . 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 + # . size : EDX = *s 8b/copy 1/mod/*+disp8 4/rm32/sib 5/base/EBP 4/index/none . 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 + # . syscall b8/copy-to-EAX 4/imm32/write cd/syscall 0x80/imm8 - # restore registers + # . restore registers 5b/pop-to-EBX 5a/pop-to-EDX 59/pop-to-ECX 58/pop-to-EAX - # epilog + # . epilog 89/copy 3/mod/direct 4/rm32/ESP . . . 5/r32/EBP . . # copy EBP to ESP 5d/pop-to-EBP c3/return -# vim:nowrap:textwidth=0 +# . . vim:nowrap:textwidth=0 diff --git a/subx/051test.subx b/subx/051test.subx index e665793a..2f93c914 100644 --- a/subx/051test.subx +++ b/subx/051test.subx @@ -1,9 +1,9 @@ # Rudimentary test harness == code -# instruction effective address operand 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 +# 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 # main: (manual test if this is the last file loaded) # check-ints-equal(34, 34) @@ -19,10 +19,10 @@ # print msg to stderr if a != b, otherwise print "." check-ints-equal: # (a : int, b : int, msg : (address array byte)) -> boolean - # prolog + # . prolog 55/push-EBP 89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP - # save registers + # . save registers 51/push-ECX 53/push-EBX # load first 2 args into EAX and EBX @@ -32,41 +32,41 @@ check-ints-equal: # (a : int, b : int, msg : (address array byte)) -> boolean 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(2/stderr, '.') - # push args + # . . push args 68/push "."/imm32 68/push 2/imm32/stderr - # call + # . . call e8/call _write/disp32 - # discard args + # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP # return eb/jump $check-ints-equal:end/disp8 # else: $check-ints-equal:else: # _write(2/stderr, msg) - # push args + # . . push args 8b/copy 1/mod/*+disp8 4/rm32/sib 5/base/EBP 4/index/none . 1/r32/ECX 0x10/disp8 . # copy *(EBP+16) to ECX 51/push-ECX 68/push 2/imm32/stderr - # call + # . . call e8/call _write/disp32 - # discard args + # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP # _write(2/stderr, Newline) - # push args + # . . push args 68/push Newline/imm32 68/push 2/imm32/stderr - # call + # . . call e8/call _write/disp32 - # discard args + # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP # increment Num-test-failures ff 0/subop/increment 0/mod/indirect 5/rm32/.disp32 . . . Num-test-failures/disp32 # increment *Num-test-failures $check-ints-equal:end: - # restore registers + # . restore registers 5b/pop-to-EBX 59/pop-to-ECX - # epilog + # . epilog 89/copy 3/mod/direct 4/rm32/ESP . . . 5/r32/EBP . . # copy EBP to ESP 5d/pop-to-EBP c3/return @@ -82,4 +82,4 @@ Newline: Num-test-failures: 00 00 00 00 -# vim:nowrap:textwidth=0 +# . . vim:nowrap:textwidth=0 diff --git a/subx/052kernel_string_equal.subx b/subx/052kernel_string_equal.subx index 3eb0158c..696f0f8f 100644 --- a/subx/052kernel_string_equal.subx +++ b/subx/052kernel_string_equal.subx @@ -15,9 +15,9 @@ # would cause tests to not run, rather than to fail as we'd like.) == code -# instruction effective address operand 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 +# 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 # main: e8/call run-tests/disp32 # 'run-tests' is a function created automatically by SubX. It calls all functions that start with 'test-'. @@ -29,10 +29,10 @@ # 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 - # prolog + # . prolog 55/push-EBP 89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP - # save registers + # . save registers 51/push-ECX 52/push-EDX 53/push-EBX @@ -98,13 +98,13 @@ $kernel-string-equal:false: b8/copy-to-EAX 0/imm32 $kernel-string-equal:end: - # restore registers + # . restore registers 5f/pop-to-EDI 5e/pop-to-ESI 5b/pop-to-EBX 5a/pop-to-EDX 59/pop-to-ECX - # epilog + # . epilog 89/copy 3/mod/direct 4/rm32/ESP . . . 5/r32/EBP . . # copy EBP to ESP 5d/pop-to-EBP c3/return @@ -113,141 +113,141 @@ $kernel-string-equal:end: test-compare-null-kernel-string-with-empty-array: # EAX = kernel-string-equal(Null-kernel-string, "") - # push args + # . . push args 68/push ""/imm32 68/push Null-kernel-string/imm32 - # call + # . . call e8/call kernel-string-equal/disp32 - # discard args + # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP - # call check-ints-equal(EAX, 1, msg) - # push args + # . . call 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 + # . . call e8/call check-ints-equal/disp32 - # discard args + # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP c3/return test-compare-null-kernel-string-with-non-empty-array: # EAX = kernel-string-equal(Null-kernel-string, "Abc") - # push args + # . . push args 68/push "Abc"/imm32 68/push Null-kernel-string/imm32 - # call + # . . call e8/call kernel-string-equal/disp32 - # discard args + # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP - # call check-ints-equal(EAX, 0, msg) - # push args + # . . call 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 + # . . call e8/call check-ints-equal/disp32 - # discard args + # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP c3/return test-compare-kernel-string-with-equal-array: # EAX = kernel-string-equal(Abc-kernel-string, "Abc") - # push args + # . . push args 68/push "Abc"/imm32 68/push Abc-kernel-string/imm32 - # call + # . . call e8/call kernel-string-equal/disp32 - # discard args + # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP - # call check-ints-equal(EAX, 1, msg) - # push args + # . . call 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 + # . . call e8/call check-ints-equal/disp32 - # discard args + # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP c3/return test-compare-kernel-string-with-inequal-array: # EAX = kernel-string-equal(Abc-kernel-string, "Adc") - # push args + # . . push args 68/push "Adc"/imm32 68/push Abc-kernel-string/imm32 - # call + # . . call e8/call kernel-string-equal/disp32 - # discard args + # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP - # call check-ints-equal(EAX, 0, msg) - # push args + # . . call 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 + # . . call e8/call check-ints-equal/disp32 - # discard args + # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP c3/return test-compare-kernel-string-with-empty-array: # EAX = kernel-string-equal(Abc-kernel-string, "") - # push args + # . . push args 68/push ""/imm32 68/push Abc-kernel-string/imm32 - # call + # . . call e8/call kernel-string-equal/disp32 - # discard args + # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP - # call check-ints-equal(EAX, 0) - # push args + # . . call check-ints-equal(EAX, 0) + # . . push args 68/push "F - test-compare-kernel-string-with-equal-array"/imm32 68/push 0/imm32/false 50/push-EAX - # call + # . . call e8/call check-ints-equal/disp32 - # discard args + # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP c3/return test-compare-kernel-string-with-shorter-array: # EAX = kernel-string-equal(Abc-kernel-string, "Ab") - # push args + # . . push args 68/push "Ab"/imm32 68/push Abc-kernel-string/imm32 - # call + # . . call e8/call kernel-string-equal/disp32 - # discard args + # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP - # call check-ints-equal(EAX, 0) - # push args + # . . call check-ints-equal(EAX, 0) + # . . push args 68/push "F - test-compare-kernel-string-with-shorter-array"/imm32 68/push 0/imm32/false 50/push-EAX - # call + # . . call e8/call check-ints-equal/disp32 - # discard args + # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP c3/return test-compare-kernel-string-with-longer-array: # EAX = kernel-string-equal(Abc-kernel-string, "Abcd") - # push args + # . . push args 68/push "Abcd"/imm32 68/push Abc-kernel-string/imm32 - # call + # . . call e8/call kernel-string-equal/disp32 - # discard args + # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP - # call check-ints-equal(EAX, 0) - # push args + # . . call check-ints-equal(EAX, 0) + # . . push args 68/push "F - test-compare-kernel-string-with-longer-array"/imm32 68/push 0/imm32/false 50/push-EAX - # call + # . . call e8/call check-ints-equal/disp32 - # discard args + # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP c3/return @@ -258,4 +258,4 @@ Null-kernel-string: Abc-kernel-string: 41/A 62/b 63/c 00/null -# vim:nowrap:textwidth=0 +# . . vim:nowrap:textwidth=0 diff --git a/subx/053new_segment.subx b/subx/053new_segment.subx index 69115575..3809eee5 100644 --- a/subx/053new_segment.subx +++ b/subx/053new_segment.subx @@ -1,17 +1,17 @@ # Create a new segment (for data) using mmap(). == code -# instruction effective address operand 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 +# 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 # main: (manual test if this is the last file loaded) # EAX = new-segment(0x1000) - # push args + # . . push args 68/push 0x1000/imm32 - # call + # . . call e8/call new-segment/disp32 - # discard args + # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP # store to *EAX @@ -23,7 +23,7 @@ cd/syscall 0x80/imm8 new-segment: # len : int -> address - # prolog + # . prolog 55/push-EBP 89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP 53/push-EBX @@ -36,7 +36,7 @@ new-segment: # len : int -> address bb/copy-to-EBX mmap-new-segment/imm32 b8/copy-to-EAX 0x5a/imm32/mmap cd/syscall 0x80/imm8 - # epilog + # . epilog 5b/pop-to-EBX 89/copy 3/mod/direct 4/rm32/ESP . . . 5/r32/EBP . . # copy EBP to ESP 5d/pop-to-EBP @@ -59,4 +59,4 @@ mmap-new-segment: # type mmap_arg_struct # offset 00 00 00 00 # 0 since MAP_ANONYMOUS is specified -# vim:nowrap:textwidth=0 +# . . vim:nowrap:textwidth=0 diff --git a/subx/054string_equal.subx b/subx/054string_equal.subx index 2b0d6006..44222e1e 100644 --- a/subx/054string_equal.subx +++ b/subx/054string_equal.subx @@ -1,9 +1,9 @@ # Comparing 'regular' length-prefixed strings. == code -# instruction effective address operand 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 +# 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 # main: e8/call run-tests/disp32 # 'run-tests' is a function created automatically by SubX. It calls all functions that start with 'test-'. @@ -13,10 +13,10 @@ cd/syscall 0x80/imm8 string-equal: # s : string, benchmark : string -> EAX : boolean - # prolog + # . prolog 55/push-EBP 89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP - # save registers + # . save registers 51/push-ECX 52/push-EDX 53/push-EBX @@ -74,12 +74,12 @@ $string-equal:false: # return false b8/copy-to-EAX 0/imm32 $string-equal:end: - # restore registers + # . restore registers 5e/pop-to-ESI 5b/pop-to-EBX 5a/pop-to-EDX 59/pop-to-ECX - # epilog + # . epilog 89/copy 3/mod/direct 4/rm32/ESP . . . 5/r32/EBP . . # copy EBP to ESP 5d/pop-to-EBP c3/return @@ -88,82 +88,82 @@ $string-equal:end: test-compare-empty-with-empty-string: # EAX = string-equal("", "") - # push args + # . . push args 68/push ""/imm32 68/push ""/imm32 - # call + # . . call e8/call string-equal/disp32 - # discard args + # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP - # call check-ints-equal(EAX, 1, msg) - # push args + # . . call check-ints-equal(EAX, 1, msg) + # . . push args 68/push "F - test-compare-empty-with-empty-string"/imm32 68/push 1/imm32/true 50/push-EAX - # call + # . . call e8/call check-ints-equal/disp32 - # discard args + # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP c3/return test-compare-empty-with-non-empty-string: # also checks length-mismatch code path # EAX = string-equal("", "Abc") - # push args + # . . push args 68/push "Abc"/imm32 68/push ""/imm32 - # call + # . . call e8/call string-equal/disp32 - # discard args + # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP - # call check-ints-equal(EAX, 0, msg) - # push args + # . . call check-ints-equal(EAX, 0, msg) + # . . push args 68/push "F - test-compare-empty-with-non-empty-string"/imm32 68/push 0/imm32/false 50/push-EAX - # call + # . . call e8/call check-ints-equal/disp32 - # discard args + # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP c3/return test-compare-equal-strings: # EAX = string-equal("Abc", "Abc") - # push args + # . . push args 68/push "Abc"/imm32 68/push "Abc"/imm32 - # call + # . . call e8/call string-equal/disp32 - # discard args + # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP - # call check-ints-equal(EAX, 1, msg) - # push args + # . . call check-ints-equal(EAX, 1, msg) + # . . push args 68/push "F - test-compare-equal-strings"/imm32 68/push 1/imm32/true 50/push-EAX - # call + # . . call e8/call check-ints-equal/disp32 - # discard args + # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP c3/return test-compare-inequal-strings-equal-lengths: # EAX = string-equal("Abc", "Adc") - # push args + # . . push args 68/push "Adc"/imm32 68/push "Abc"/imm32 - # call + # . . call e8/call string-equal/disp32 - # discard args + # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP - # call check-ints-equal(EAX, 0, msg) - # push args + # . . call check-ints-equal(EAX, 0, msg) + # . . push args 68/push "F - test-compare-inequal-strings-equal-lengths"/imm32 68/push 0/imm32/false 50/push-EAX - # call + # . . call e8/call check-ints-equal/disp32 - # discard args + # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP c3/return -# vim:nowrap:textwidth=0 +# . . vim:nowrap:textwidth=0 diff --git a/subx/055trace.subx b/subx/055trace.subx index 7986cf33..2f281ced 100644 --- a/subx/055trace.subx +++ b/subx/055trace.subx @@ -38,9 +38,9 @@ _test-trace-stream: 00 00 00 00 00 00 00 00 # 8 bytes == code -# instruction effective address operand 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 +# 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 # main: e8/call run-tests/disp32 # 'run-tests' is a function created automatically by SubX. It calls all functions that start with 'test-'. @@ -53,11 +53,11 @@ _test-trace-stream: # The Trace-stream segment will consist of variable-length lines separated by newlines (0x0a) initialize-trace-stream: # EAX = new-segment(0x1000) - # push args + # . . push args 68/push 0x1000/imm32/N - # call + # . . call e8/call new-segment/disp32 - # discard args + # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP # copy EAX to *Trace-stream 89/copy 0/mod/indirect 5/rm32/.disp32 . . 0/r32/EAX Trace-stream/disp32 # copy EAX to *Trace-stream @@ -68,10 +68,10 @@ initialize-trace-stream: # 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: # t : (address trace-stream), line : string - # prolog + # . prolog 55/push-EBP 89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP - # save registers + # . save registers 50/push-EAX 51/push-ECX 52/push-EDX @@ -95,9 +95,9 @@ trace: # t : (address trace-stream), line : string # push &t->data[t->write] 8d/copy-address 1/mod/*+disp8 4/rm32/sib 7/base/EDI 1/index/ECX . 3/r32/EBX 0xc/disp8 . # copy EDI+ECX+12 to EBX 53/push-EBX - # call + # . . call e8/call _append-3/disp32 - # discard args + # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP # if EAX == 0 return 81 7/subop/compare 3/mod/direct 0/rm32/EAX . . . . . 0/imm32 # compare EDX @@ -115,30 +115,30 @@ trace: # t : (address trace-stream), line : string # push &t->data[t->write] 8d/copy-address 1/mod/*+disp8 4/rm32/sib 7/base/EDI 1/index/ECX . 3/r32/EBX 0xc/disp8 . # copy EDI+ECX+12 to EBX 53/push-EBX - # call + # . . call e8/call _append-3/disp32 - # discard args + # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP # t->write += EAX 01/add 0/mod/indirect 7/rm32/EDI . . . 0/r32/EAX . . # add EAX to *EDI $trace:end: - # restore registers + # . restore registers 5f/pop-to-EDI 5e/pop-to-ESI 5b/pop-to-EBX 5a/pop-to-EDX 59/pop-to-ECX 58/pop-to-EAX - # epilog + # . epilog 89/copy 3/mod/direct 4/rm32/ESP . . . 5/r32/EBP . . # copy EBP to ESP 5d/pop-to-EBP c3/return clear-trace-stream: # t : (address trace-stream) - # prolog + # . prolog 55/push-EBP 89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP - # save registers + # . save registers 50/push-EAX 51/push-ECX # EAX = t @@ -164,10 +164,10 @@ $clear-trace-stream:loop: 81 0/subop/add 3/mod/direct 0/rm32/EAX . . . . . 4/imm32 # add to EAX eb/jump $clear-trace-stream:loop/disp8 $clear-trace-stream:end: - # restore registers + # . restore registers 59/pop-to-ECX 58/pop-to-EAX - # epilog + # . epilog 89/copy 3/mod/direct 4/rm32/ESP . . . 5/r32/EBP . . # copy EBP to ESP 5d/pop-to-EBP c3/return @@ -176,98 +176,98 @@ $clear-trace-stream:end: test-trace-single: # clear-trace-stream(_test-trace-stream) - # push args + # . . push args 68/push _test-trace-stream/imm32 - # call + # . . call e8/call clear-trace-stream/disp32 - # discard args + # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP # trace(_test-trace-stream, "Ab") - # push args + # . . push args 68/push "Ab"/imm32 68/push _test-trace-stream/imm32 - # call + # . . call e8/call trace/disp32 - # discard args + # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP # check-ints-equal(*_test-trace-stream.data, 41/A 62/b 0a/newline 00, msg) - # push args + # . . push args 68/push "F - test-trace-single"/imm32 68/push 0x0a6241/imm32/Ab-newline # push *_test-trace-stream.data b8/copy-to-EAX _test-trace-stream/imm32 ff 6/subop/push 1/mod/*+disp8 0/rm32/EAX . . . . 0xc/disp8 . # push *(EAX+12) - # call + # . . call e8/call check-ints-equal/disp32 - # discard args + # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP # end c3/return test-trace-appends: # clear-trace-stream(_test-trace-stream) - # push args + # . . push args 68/push _test-trace-stream/imm32 - # call + # . . call e8/call clear-trace-stream/disp32 - # discard args + # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP # trace(_test-trace-stream, "C") - # push args + # . . push args 68/push "C"/imm32 68/push _test-trace-stream/imm32 - # call + # . . call e8/call trace/disp32 - # discard args + # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP # trace(_test-trace-stream, "D") - # push args + # . . push args 68/push "D"/imm32 68/push _test-trace-stream/imm32 - # call + # . . call e8/call trace/disp32 - # discard args + # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP # check-ints-equal(*_test-trace-stream.data, 43/C 0a/newline 44/D 0a/newline, msg) - # push args + # . . push args 68/push "F - test-trace-appends"/imm32 68/push 0x0a440a43/imm32/C-newline-D-newline # push *_test-trace-stream.data b8/copy-to-EAX _test-trace-stream/imm32 ff 6/subop/push 1/mod/*+disp8 0/rm32/EAX . . . . 0xc/disp8 . # push *(EAX+12) - # call + # . . call e8/call check-ints-equal/disp32 - # discard args + # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP # end c3/return test-trace-empty-line: # clear-trace-stream(_test-trace-stream) - # push args + # . . push args 68/push _test-trace-stream/imm32 - # call + # . . call e8/call clear-trace-stream/disp32 - # discard args + # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP # trace(_test-trace-stream, "") - # push args + # . . push args 68/push ""/imm32 68/push _test-trace-stream/imm32 - # call + # . . call e8/call trace/disp32 - # discard args + # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP # check-ints-equal(*_test-trace-stream.data, 0, msg) - # push args + # . . push args 68/push "F - test-trace-empty-line"/imm32 68/push 0/imm32 # push *_test-trace-stream.data b8/copy-to-EAX _test-trace-stream/imm32 ff 6/subop/push 1/mod/*+disp8 0/rm32/EAX . . . . 0xc/disp8 . # push *(EAX+12) - # call + # . . call e8/call check-ints-equal/disp32 - # discard args + # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP # end c3/return @@ -276,10 +276,10 @@ test-trace-empty-line: # 3-argument variant of _append _append-3: # out : address, outend : address, s : (array byte) -> num_bytes_appended/EAX - # prolog + # . prolog 55/push-EBP 89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP - # save registers + # . save registers 51/push-ECX # _append-4(out, outend, &s.data[0], &s.data[s.length]) -> num_bytes_appended/EAX # push &s.data[s.length] @@ -297,23 +297,23 @@ _append-3: # out : address, outend : address, s : (array byte) -> num_bytes_app ff 6/subop/push 1/mod/*+disp8 4/rm32/sib 5/base/EBP 4/index/none . . 0xc/disp8 . # push *(EBP+12) # push out ff 6/subop/push 1/mod/*+disp8 4/rm32/sib 5/base/EBP 4/index/none . . 0x8/disp8 . # push *(EBP+8) - # call + # . . call e8/call _append-4/disp32 - # discard args + # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0x10/imm32 # add to ESP - # restore registers + # . restore registers 59/pop-to-ECX - # epilog + # . epilog 89/copy 3/mod/direct 4/rm32/ESP . . . 5/r32/EBP . . # copy EBP to ESP 5d/pop-to-EBP c3/return # 4-argument variant of _append _append-4: # out : address, outend : address, in : address, inend : address -> num_bytes_appended/EAX - # prolog + # . prolog 55/push-EBP 89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP - # save registers + # . save registers 51/push-ECX 52/push-EDX 53/push-EBX @@ -345,15 +345,15 @@ $_append-4:loop: 47/increment-EDI eb/jump $_append-4:loop/disp8 $_append-4:end: - # restore registers + # . restore registers 5f/pop-to-EDI 5e/pop-to-ESI 5b/pop-to-EBX 5a/pop-to-EDX 59/pop-to-ECX - # epilog + # . epilog 89/copy 3/mod/direct 4/rm32/ESP . . . 5/r32/EBP . . # copy EBP to ESP 5d/pop-to-EBP c3/return -# vim:nowrap:textwidth=0 +# . . vim:nowrap:textwidth=0 diff --git a/subx/056write.subx b/subx/056write.subx index cf2c3194..6638b174 100644 --- a/subx/056write.subx +++ b/subx/056write.subx @@ -16,9 +16,9 @@ # data: (array byte) # prefixed by length as usual == code -# instruction effective address operand 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 +# 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 # main: e8/call run-tests/disp32 # 'run-tests' is a function created automatically by SubX. It calls all functions that start with 'test-'. @@ -31,23 +31,23 @@ write: # f : fd or (address stream), s : (address array byte) -> bytes_written/ # (If we ever leave the Linux kernel behind, it may be better to return # the number of bytes *not* written. Success would then be signaled by # returning 0.) - # prolog + # . prolog 55/push-EBP 89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP # if (f < 0x08000000) _write(f, s), return # f can't be a user-mode address, so treat it as a kernel file descriptor 81 7/subop/compare 1/mod/*+disp8 4/rm32/sib 5/base/EBP 4/index/none . . 8/disp8 0x08000000/imm32 # compare *(EBP+8) 7d/jump-if-greater-or-equal $write:fake/disp8 - # push args + # . . push args ff 6/subop/push 1/mod/*+disp8 4/rm32/sib 5/base/EBP 4/index/none . . 0xc/disp8 . # push *(EBP+12) ff 6/subop/push 1/mod/*+disp8 4/rm32/sib 5/base/EBP 4/index/none . . 8/disp8 . # push *(EBP+8) - # call + # . . call e8/call _write/disp32 - # discard args + # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP eb/jump $write:end/disp8 $write:fake: # otherwise, treat 'f' as a stream to append to - # save registers + # . save registers 51/push-ECX 52/push-EDX 53/push-EBX @@ -66,27 +66,27 @@ $write:fake: # push &f->data[f->write] 8d/copy-address 1/mod/*+disp8 4/rm32/sib 1/base/ECX 2/index/EDX . 3/r32/EBX 0xc/disp8 . # copy ECX+EDX+12 to EBX 53/push-EBX - # call + # . . call e8/call _append-3/disp32 - # discard args + # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP # f->write += EAX 01/add 0/mod/indirect 1/rm32/ECX . . . 0/r32/EAX . . # add EAX to *ECX - # restore registers + # . restore registers 5b/pop-to-EBX 5a/pop-to-EDX 59/pop-to-ECX $write:end: - # epilog + # . epilog 89/copy 3/mod/direct 4/rm32/ESP . . . 5/r32/EBP . . # copy EBP to ESP 5d/pop-to-EBP c3/return clear-stream: # f : (address stream) -> <void> - # prolog + # . prolog 55/push-EBP 89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP - # save registers + # . save registers 50/push-EAX 51/push-ECX # EAX = f @@ -112,87 +112,87 @@ $clear-stream:loop: 81 0/subop/add 3/mod/direct 0/rm32/EAX . . . . . 4/imm32 # add to EAX eb/jump $clear-stream:loop/disp8 $clear-stream:end: - # restore registers + # . restore registers 59/pop-to-ECX 58/pop-to-EAX - # epilog + # . epilog 89/copy 3/mod/direct 4/rm32/ESP . . . 5/r32/EBP . . # copy EBP to ESP 5d/pop-to-EBP c3/return test-write-single: # clear-stream(_test-stream) - # push args + # . . push args 68/push _test-stream/imm32 - # call + # . . call e8/call clear-stream/disp32 - # discard args + # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP # write(_test-stream, "Ab") - # push args + # . . push args 68/push "Ab"/imm32 68/push _test-stream/imm32 - # call + # . . call e8/call write/disp32 - # discard args + # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP # check-ints-equal(EAX, 2) - # push args + # . . push args 68/push "F - test-read-single: return EAX"/imm32 68/push 2/imm32 50/push-EAX - # call + # . . call e8/call check-ints-equal/disp32 - # discard args + # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP # check-ints-equal(*_test-stream->data, 41/A 62/b 00 00, msg) - # push args + # . . push args 68/push "F - test-write-single"/imm32 68/push 0x006241/imm32/Ab # push *_test-stream->data b8/copy-to-EAX _test-stream/imm32 ff 6/subop/push 1/mod/*+disp8 0/rm32/EAX . . . . 0xc/disp8 . # push *(EAX+12) - # call + # . . call e8/call check-ints-equal/disp32 - # discard args + # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP # end c3/return test-write-appends: # clear-stream(_test-stream) - # push args + # . . push args 68/push _test-stream/imm32 - # call + # . . call e8/call clear-stream/disp32 - # discard args + # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP # write(_test-stream, "C") - # push args + # . . push args 68/push "C"/imm32 68/push _test-stream/imm32 - # call + # . . call e8/call write/disp32 - # discard args + # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP # write(_test-stream, "D") - # push args + # . . push args 68/push "D"/imm32 68/push _test-stream/imm32 - # call + # . . call e8/call write/disp32 - # discard args + # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP # check-ints-equal(*_test-stream->data, 43/C 44/D 00 00, msg) - # push args + # . . push args 68/push "F - test-write-appends"/imm32 68/push 0x00004443/imm32/C-D # push *_test-stream->data b8/copy-to-EAX _test-stream/imm32 ff 6/subop/push 1/mod/*+disp8 0/rm32/EAX . . . . 0xc/disp8 . # push *(EAX+12) - # call + # . . call e8/call check-ints-equal/disp32 - # discard args + # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP # end c3/return @@ -209,4 +209,4 @@ _test-stream: # data 00 00 00 00 00 00 00 00 # 8 bytes -# vim:nowrap:textwidth=0 +# . . vim:nowrap:textwidth=0 diff --git a/subx/057stop.subx b/subx/057stop.subx index 483c9404..b9ef4467 100644 --- a/subx/057stop.subx +++ b/subx/057stop.subx @@ -33,9 +33,9 @@ # Its value is its output, computed during stop and available to the test. == code -# instruction effective address operand 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 +# 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 # main: e8/call run-tests/disp32 # 'run-tests' is a function created automatically by SubX. It calls all functions that start with 'test-'. @@ -49,10 +49,10 @@ # the stack. # Ugly that we need to know the size of args, but so it goes. tailor-exit-descriptor: # ed : (address exit-descriptor), nbytes : int -> <void> - # prolog + # . prolog 55/push-EBP 89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP - # save registers + # . save registers 50/push-EAX 51/push-ECX # EAX = nbytes @@ -65,7 +65,7 @@ tailor-exit-descriptor: # ed : (address exit-descriptor), nbytes : int -> <void # That's the value we need to return: X-nbytes-4 # # However, we also need to account for the perturbance to ESP caused by the - # call to tailor-exit-descriptor. It pushes 8 bytes of args followed by 4 + # . . call to tailor-exit-descriptor. It pushes 8 bytes of args followed by 4 # bytes for the return address and 4 bytes to push EBP above. # So EBP at this point is X-16. # @@ -87,10 +87,10 @@ tailor-exit-descriptor: # ed : (address exit-descriptor), nbytes : int -> <void 89/copy 0/mod/indirect 1/rm32/ECX . . . 0/r32/EAX . . # copy EAX to *ECX # initialize ed->value c7/copy 1/mod/*+disp8 1/rm32/ECX . . . . 4/disp8 0/imm32 # copy to *(ECX+4) - # restore registers + # . restore registers 59/pop-to-ECX 58/pop-to-EAX - # epilog + # . epilog 89/copy 3/mod/direct 4/rm32/ESP . . . 5/r32/EBP . . # copy EBP to ESP 5d/pop-to-EBP c3/return @@ -132,78 +132,78 @@ test-stop-skips-returns-on-exit: 8d/copy-address 0/mod/indirect 4/rm32/sib 4/base/ESP 4/index/none . 0/r32/EAX . . # copy ESP to EAX # Size the exit-descriptor precisely for the next call below, to _test-stop-1. # tailor-exit-descriptor(ed, 4) - # push args + # . . push args 68/push 4/imm32/nbytes-of-args-for-_test-stop-1 50/push-EAX - # call + # . . call e8/call tailor-exit-descriptor/disp32 - # discard args + # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP - # call _test-stop-1(ed) - # push args + # . . call _test-stop-1(ed) + # . . push args 50/push-EAX - # call + # . . call e8/call _test-stop-1/disp32 ## registers except ESP may be clobbered at this point # restore args 58/pop-to-EAX # check that _test-stop-1 tried to call exit(1) # check-ints-equal(ed->value, 2, msg) # i.e. stop was called with value 1 - # push args + # . . push args 68/push "F - test-stop-skips-returns-on-exit"/imm32 68/push 2/imm32 # push ed->value ff 6/subop/push 1/mod/*+disp8 0/rm32/EAX . . . . 4/disp8 . # push *(EAX+4) - # call + # . . call e8/call check-ints-equal/disp32 - # discard args + # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP - # epilog + # . epilog 5d/pop-to-EBP # don't restore ESP from EBP; manually reclaim locals 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP c3/return _test-stop-1: # ed : (address exit-descriptor) - # prolog + # . prolog 55/push-EBP 89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP # _test-stop-2(ed) - # push args + # . . push args ff 6/subop/push 1/mod/*+disp8 4/rm32/sib 5/base/EBP 4/index/none . . 8/disp8 . # push *(EBP+8) - # call + # . . call e8/call _test-stop-2/disp32 ## should never get past this point - # discard args + # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP # signal test failed: check-ints-equal(1, 0, msg) - # push args + # . . push args 68/push "F - test-stop-skips-returns-on-exit"/imm32 68/push 0/imm32 68/push 1/imm32 - # call + # . . call e8/call check-ints-equal/disp32 - # discard args + # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP - # epilog + # . epilog 89/copy 3/mod/direct 4/rm32/ESP . . . 5/r32/EBP . . # copy EBP to ESP 5d/pop-to-EBP c3/return _test-stop-2: # ed : (address exit-descriptor) - # prolog + # . prolog 55/push-EBP 89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP - # call stop(ed, 1) - # push args + # . . call stop(ed, 1) + # . . push args 68/push 1/imm32 ff 6/subop/push 1/mod/*+disp8 4/rm32/sib 5/base/EBP 4/index/none . . 8/disp8 . # push *(EBP+8) - # call + # . . call e8/call stop/disp32 ## should never get past this point - # epilog + # . epilog 89/copy 3/mod/direct 4/rm32/ESP . . . 5/r32/EBP . . # copy EBP to ESP 5d/pop-to-EBP c3/return -# vim:nowrap:textwidth=0 +# . . vim:nowrap:textwidth=0 diff --git a/subx/058read.subx b/subx/058read.subx index 54f83f0f..ccd7e349 100644 --- a/subx/058read.subx +++ b/subx/058read.subx @@ -41,9 +41,9 @@ # data: (array byte) # prefixed by length as usual == code -# instruction effective address operand 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 +# 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 # main: e8/call run-tests/disp32 # 'run-tests' is a function created automatically by SubX. It calls all functions that start with 'test-'. @@ -53,24 +53,24 @@ cd/syscall 0x80/imm8 read: # f : fd or (address stream), s : (address stream) -> num-bytes-read/EAX - # prolog + # . prolog 55/push-EBP 89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP ## if (f < 0x08000000) return _read(f, s) # f can't be a user-mode address, so treat it as a kernel file descriptor 81 7/subop/compare 1/mod/*+disp8 4/rm32/sib 5/base/EBP 4/index/none . . 8/disp8 0x08000000/imm32 # compare *(EBP+8) 7d/jump-if-greater-or-equal $read:fake/disp8 - # push args + # . . push args ff 6/subop/push 1/mod/*+disp8 4/rm32/sib 5/base/EBP 4/index/none . . 0xc/disp8 . # push *(EBP+12) ff 6/subop/push 1/mod/*+disp8 4/rm32/sib 5/base/EBP 4/index/none . . 8/disp8 . # push *(EBP+8) - # call + # . . call e8/call _read/disp32 - # discard args + # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP # return eb/jump $read:end/disp8 $read:fake: ## otherwise, treat 'f' as a stream to scan from - # save registers + # . save registers 56/push-ESI 57/push-EDI # ESI = f @@ -95,19 +95,19 @@ $read:fake: 8b/copy 0/mod/indirect 7/rm32/EDI . . . 0/r32/EAX . . # copy *EDI to EAX 8d/copy-address 1/mod/*+disp8 4/rm32/sib 7/base/EDI 0/index/EAX . 0/r32/EAX 0xc/disp8 . # copy EDI+EAX+12 to EAX 50/push-EAX - # call + # . . call e8/call _append-4/disp32 - # discard args + # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0x10/imm32 # add to ESP # s->write += EAX 01/add 0/mod/indirect 7/rm32/EDI . . . 0/r32/EAX . . # add EAX to *EDI # f.read += EAX 01/add 1/mod/*+disp8 6/rm32/ESI . . . 0/r32/EAX 4/disp8 . # add EAX to *(ESI+4) - # restore registers + # . restore registers 5f/pop-to-EDI 5e/pop-to-ESI $read:end: - # epilog + # . epilog 89/copy 3/mod/direct 4/rm32/ESP . . . 5/r32/EBP . . # copy EBP to ESP 5d/pop-to-EBP c3/return @@ -119,10 +119,10 @@ $read:end: # Maybe a better helper would be 'empty-stream?' _read: # fd : int, s : (address stream) -> num-bytes-read/EAX - # prolog + # . prolog 55/push-EBP 89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP - # save registers + # . save registers 51/push-ECX 52/push-EDX 53/push-EBX @@ -145,12 +145,12 @@ _read: # fd : int, s : (address stream) -> num-bytes-read/EAX cd/syscall 0x80/imm8 # add the result EAX to s->write 01/add 0/mod/indirect 6/rm32/ESI . . . 0/r32/EAX . . # add EAX to *ESI - # restore registers + # . restore registers 5e/pop-to-ESI 5b/pop-to-EBX 5a/pop-to-EDX 59/pop-to-ECX - # epilog + # . epilog 89/copy 3/mod/direct 4/rm32/ESP . . . 5/r32/EBP . . # copy EBP to ESP 5d/pop-to-EBP c3/return @@ -180,54 +180,54 @@ _read: # fd : int, s : (address stream) -> num-bytes-read/EAX test-read-single: # clear-stream(_test-stream) - # push args + # . . push args 68/push _test-stream/imm32 - # call + # . . call e8/call clear-stream/disp32 - # discard args + # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP # clear-stream(_test-stream-buffer) - # push args + # . . push args 68/push _test-stream-buffer/imm32 - # call + # . . call e8/call clear-stream/disp32 - # discard args + # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP # write(_test-stream, "Ab") - # push args + # . . push args 68/push "Ab"/imm32 68/push _test-stream/imm32 - # call + # . . call e8/call write/disp32 - # discard args + # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP # read(_test-stream, _test-stream-buffer) - # push args + # . . push args 68/push _test-stream-buffer/imm32 68/push _test-stream/imm32 - # call + # . . call e8/call read/disp32 - # discard args + # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP # check-ints-equal(EAX, 2) - # push args + # . . push args 68/push "F - test-read-single: return EAX"/imm32 68/push 2/imm32 50/push-EAX - # call + # . . call e8/call check-ints-equal/disp32 - # discard args + # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP # check-ints-equal(*_test-stream-buffer->data, 41/A 62/b 00 00, msg) - # push args + # . . push args 68/push "F - test-read-single"/imm32 68/push 0x006241/imm32/Ab # push *_test-stream-buffer->data b8/copy-to-EAX _test-stream-buffer/imm32 ff 6/subop/push 1/mod/*+disp8 0/rm32/EAX . . . . 0xc/disp8 . # push *(EAX+12) - # call + # . . call e8/call check-ints-equal/disp32 - # discard args + # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP # end c3/return @@ -235,61 +235,61 @@ test-read-single: test-read-is-stateful: ## make two consecutive reads, check that their results are appended # clear-stream(_test-stream) - # push args + # . . push args 68/push _test-stream/imm32 - # call + # . . call e8/call clear-stream/disp32 - # discard args + # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP # clear-stream(_test-stream-buffer) - # push args + # . . push args 68/push _test-stream-buffer/imm32 - # call + # . . call e8/call clear-stream/disp32 - # discard args + # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP # write(_test-stream, "C") - # push args + # . . push args 68/push "C"/imm32 68/push _test-stream/imm32 - # call + # . . call e8/call write/disp32 - # discard args + # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP # read(_test-stream, _test-stream-buffer) - # push args + # . . push args 68/push _test-stream-buffer/imm32 68/push _test-stream/imm32 - # call + # . . call e8/call read/disp32 - # discard args + # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP # write(_test-stream, "D") - # push args + # . . push args 68/push "D"/imm32 68/push _test-stream/imm32 - # call + # . . call e8/call write/disp32 - # discard args + # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP # read(_test-stream, _test-stream-buffer) - # push args + # . . push args 68/push _test-stream-buffer/imm32 68/push _test-stream/imm32 - # call + # . . call e8/call read/disp32 - # discard args + # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP # check-ints-equal(*_test-stream-buffer->data, 43/C 44/D 00 00, msg) - # push args + # . . push args 68/push "F - test-read-is-stateful"/imm32 68/push 0x00004443/imm32/C-D # push *_test-stream-buffer->data b8/copy-to-EAX _test-stream-buffer/imm32 ff 6/subop/push 1/mod/*+disp8 0/rm32/EAX . . . . 0xc/disp8 . # push *(EAX+12) - # call + # . . call e8/call check-ints-equal/disp32 - # discard args + # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP # end c3/return @@ -297,53 +297,53 @@ test-read-is-stateful: test-read-returns-0-on-end-of-file: ## read after hitting end-of-file, check that result is 0 # clear-stream(_test-stream) - # push args + # . . push args 68/push _test-stream/imm32 - # call + # . . call e8/call clear-stream/disp32 - # discard args + # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP # clear-stream(_test-stream-buffer) - # push args + # . . push args 68/push _test-stream-buffer/imm32 - # call + # . . call e8/call clear-stream/disp32 - # discard args + # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP # write(_test-stream, "Ab") - # push args + # . . push args 68/push "Ab"/imm32 68/push _test-stream/imm32 - # call + # . . call e8/call write/disp32 - # discard args + # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP ## first read gets to end-of-file # read(_test-stream, _test-stream-buffer) - # push args + # . . push args 68/push _test-stream-buffer/imm32 68/push _test-stream/imm32 - # call + # . . call e8/call read/disp32 - # discard args + # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP ## second read # read(_test-stream, _test-stream-buffer) - # push args + # . . push args 68/push _test-stream-buffer/imm32 68/push _test-stream/imm32 - # call + # . . call e8/call read/disp32 - # discard args + # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP # check-ints-equal(EAX, 0) - # push args + # . . push args 68/push "F - test-read-returns-0-on-end-of-file"/imm32 68/push 0/imm32 50/push-EAX - # call + # . . call e8/call check-ints-equal/disp32 - # discard args + # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP # end c3/return @@ -360,4 +360,4 @@ _test-stream-buffer: # data 00 00 00 00 00 00 00 00 # 8 bytes -# vim:nowrap:textwidth=0 +# . . vim:nowrap:textwidth=0 diff --git a/subx/059read-byte.subx b/subx/059read-byte.subx index da99eed3..39d818f4 100644 --- a/subx/059read-byte.subx +++ b/subx/059read-byte.subx @@ -27,9 +27,9 @@ Stdin: # TODO: 8 bytes is too small. We'll need to grow the buffer for efficiency. == code -# instruction effective address operand 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 +# 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 # main: e8/call run-tests/disp32 # 'run-tests' is a function created automatically by SubX. It calls all functions that start with 'test-'. @@ -42,10 +42,10 @@ Stdin: # return next byte value in EAX, with top 3 bytes cleared. # On EOF, return 0xffffffff. read-byte: # f : (address buffered-file) -> byte/EAX - # prolog + # . prolog 55/push-EBP 89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP - # save registers + # . save registers 51/push-ECX 56/push-ESI # ESI = f @@ -56,20 +56,20 @@ read-byte: # f : (address buffered-file) -> byte/EAX 3b/compare 1/mod/*+disp8 6/rm32/ESI . . . 1/r32/ECX 4/disp8 . # compare ECX with *(ESI+4) 7c/jump-if-lesser $read-byte:from-stream/disp8 # clear-stream(stream = f+4) - # push args + # . . push args 8d/copy-address 1/mod/*+disp8 6/rm32/ESI . . . 0/r32/EAX 4/disp8 . # copy ESI+4 to EAX 50/push-EAX - # call + # . . call e8/call clear-stream/disp32 - # discard args + # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP # EAX = read(f->fd, stream = f+4) - # push args + # . . push args 50/push-EAX ff 6/subop/push 0/mod/indirect 6/rm32/ESI . . . . . . # push *ESI - # call + # . . call e8/call read/disp32 - # discard args + # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP # if EAX = 0 return 0xffffffff 81 7/subop/compare 3/mod/direct 0/rm32/EAX . . . . . 0/imm32 # compare EAX @@ -83,10 +83,10 @@ $read-byte:from-stream: # ++f->read ff 0/subop/increment 1/mod/*+disp8 6/rm32/ESI . . . . 8/disp8 . # increment *(ESI+8) $read-byte:end: - # restore registers + # . restore registers 5e/pop-to-ESI 59/pop-to-ECX - # epilog + # . epilog 89/copy 3/mod/direct 4/rm32/ESP . . . 5/r32/EBP . . # copy EBP to ESP 5d/pop-to-EBP c3/return @@ -99,44 +99,44 @@ $read-byte:end: test-read-byte-single: ## check that read-byte returns first byte of 'file' # clear-stream(_test-stream) - # push args + # . . push args 68/push _test-stream/imm32 - # call + # . . call e8/call clear-stream/disp32 - # discard args + # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP # clear-stream(_test-buffered-file+4) - # push args + # . . push args b8/copy-to-EAX _test-buffered-file/imm32 05/add-to-EAX 4/imm32 50/push-EAX - # call + # . . call e8/call clear-stream/disp32 - # discard args + # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP # write(_test-stream, "Ab") - # push args + # . . push args 68/push "Ab"/imm32 68/push _test-stream/imm32 - # call + # . . call e8/call write/disp32 - # discard args + # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP # read-byte(_test-buffered-file) - # push args + # . . push args 68/push _test-buffered-file/imm32 - # call + # . . call e8/call read-byte/disp32 - # discard args + # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP # check-ints-equal(EAX, 'A') - # push args + # . . push args 68/push "F - test-read-byte-single"/imm32 68/push 0x41/imm32 50/push-EAX - # call + # . . call e8/call check-ints-equal/disp32 - # discard args + # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP # end c3/return @@ -144,51 +144,51 @@ test-read-byte-single: test-read-byte-multiple: ## call read-byte twice, check that second call returns second byte # clear-stream(_test-stream) - # push args + # . . push args 68/push _test-stream/imm32 - # call + # . . call e8/call clear-stream/disp32 - # discard args + # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP # clear-stream(_test-buffered-file+4) - # push args + # . . push args b8/copy-to-EAX _test-buffered-file/imm32 05/add-to-EAX 4/imm32 50/push-EAX - # call + # . . call e8/call clear-stream/disp32 - # discard args + # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP # write(_test-stream, "Ab") - # push args + # . . push args 68/push "Ab"/imm32 68/push _test-stream/imm32 - # call + # . . call e8/call write/disp32 - # discard args + # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP # read-byte(_test-buffered-file) - # push args + # . . push args 68/push _test-buffered-file/imm32 - # call + # . . call e8/call read-byte/disp32 - # discard args + # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP # read-byte(_test-buffered-file) - # push args + # . . push args 68/push _test-buffered-file/imm32 - # call + # . . call e8/call read-byte/disp32 - # discard args + # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP # check-ints-equal(EAX, 'b') - # push args + # . . push args 68/push "F - test-read-byte-multiple"/imm32 68/push 0x62/imm32 50/push-EAX - # call + # . . call e8/call check-ints-equal/disp32 - # discard args + # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP # end c3/return @@ -196,36 +196,36 @@ test-read-byte-multiple: test-read-byte-end-of-file: ## call read-byte on an empty 'file', check that it returns -1 # clear-stream(_test-stream) - # push args + # . . push args 68/push _test-stream/imm32 - # call + # . . call e8/call clear-stream/disp32 - # discard args + # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP # clear-stream(_test-buffered-file+4) - # push args + # . . push args b8/copy-to-EAX _test-buffered-file/imm32 05/add-to-EAX 4/imm32 50/push-EAX - # call + # . . call e8/call clear-stream/disp32 - # discard args + # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP # read-byte(_test-buffered-file) - # push args + # . . push args 68/push _test-buffered-file/imm32 - # call + # . . call e8/call read-byte/disp32 - # discard args + # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP # check-ints-equal(EAX, -1) - # push args + # . . push args 68/push "F - test-read-byte-end-of-file"/imm32 68/push -1/imm32 50/push-EAX - # call + # . . call e8/call check-ints-equal/disp32 - # discard args + # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP # end c3/return @@ -244,4 +244,4 @@ _test-buffered-file: # data 00 00 00 00 00 00 00 00 # 8 bytes -# vim:nowrap:textwidth=0 +# . . vim:nowrap:textwidth=0 diff --git a/subx/060write-stream.subx b/subx/060write-stream.subx index 75957462..cf178bc1 100644 --- a/subx/060write-stream.subx +++ b/subx/060write-stream.subx @@ -1,9 +1,9 @@ # write-stream: like write, but write streams rather than strings == code -# instruction effective address operand 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 +# 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 # main: # manual test @@ -20,23 +20,23 @@ cd/syscall 0x80/imm8 write-stream: # f : fd or (address stream), s : (address stream) -> <void> - # prolog + # . prolog 55/push-EBP 89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP # if (f < 0x08000000) _write-stream(f, s), return # f can't be a user-mode address, so treat it as a kernel file descriptor 81 7/subop/compare 1/mod/*+disp8 4/rm32/sib 5/base/EBP 4/index/none . . 8/disp8 0x08000000/imm32 # compare *(EBP+8) 7d/jump-if-greater-or-equal $write-stream:fake/disp8 - # push args + # . . push args ff 6/subop/push 1/mod/*+disp8 4/rm32/sib 5/base/EBP 4/index/none . . 0xc/disp8 . # push *(EBP+12) ff 6/subop/push 1/mod/*+disp8 4/rm32/sib 5/base/EBP 4/index/none . . 8/disp8 . # push *(EBP+8) - # call + # . . call e8/call _write-stream/disp32 - # discard args + # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP eb/jump $write-stream:end/disp8 $write-stream:fake: # otherwise, treat 'f' as a stream to append to - # save registers + # . save registers 50/push-EAX 56/push-ESI 57/push-EDI @@ -61,29 +61,29 @@ $write-stream:fake: 8b/copy 0/mod/indirect 6/rm32/ESI . . . 0/r32/EAX . . # copy *ESI to EAX 8d/copy-address 1/mod/*+disp8 4/rm32/sib 6/base/ESI 0/index/EAX . 0/r32/EAX 0xc/disp8 . # copy ESI+EAX+12 to EAX 50/push-EAX - # call + # . . call e8/call _append-4/disp32 - # discard args + # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0x10/imm32 # add to ESP # f->write += EAX 01/add 0/mod/indirect 6/rm32/ESI . . . 0/r32/EAX . . # add EAX to *ESI # s->read += EAX 01/add 1/mod/*+disp8 7/rm32/EDI . . . 0/r32/EAX 4/disp8 . # add EAX to *(EDI+4) - # restore registers + # . restore registers 5f/pop-to-EDI 5e/pop-to-ESI 58/pop-to-EAX $write-stream:end: - # epilog + # . epilog 89/copy 3/mod/direct 4/rm32/ESP . . . 5/r32/EBP . . # copy EBP to ESP 5d/pop-to-EBP c3/return _write-stream: # fd : int, s : (address stream) -> <void> - # prolog + # . prolog 55/push-EBP 89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP - # save registers + # . save registers 50/push-EAX 51/push-ECX 52/push-EDX @@ -106,120 +106,120 @@ _write-stream: # fd : int, s : (address stream) -> <void> # syscall b8/copy-to-EAX 4/imm32/write cd/syscall 0x80/imm8 - # restore registers + # . restore registers 5f/pop-to-EDI 5e/pop-to-ESI 5b/pop-to-EBX 5a/pop-to-EDX 59/pop-to-ECX 58/pop-to-EAX - # epilog + # . epilog 89/copy 3/mod/direct 4/rm32/ESP . . . 5/r32/EBP . . # copy EBP to ESP 5d/pop-to-EBP c3/return test-write-stream-single: # clear-stream(_test-stream) - # push args + # . . push args 68/push _test-stream/imm32 - # call + # . . call e8/call clear-stream/disp32 - # discard args + # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP # clear-stream(_test-stream2) - # push args + # . . push args 68/push _test-stream2/imm32 - # call + # . . call e8/call clear-stream/disp32 - # discard args + # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP # write(_test-stream2, "Ab") - # push args + # . . push args 68/push "Ab"/imm32 68/push _test-stream2/imm32 - # call + # . . call e8/call write/disp32 - # discard args + # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP # write-stream(_test-stream, _test-stream2) - # push args + # . . push args 68/push _test-stream2/imm32 68/push _test-stream/imm32 - # call + # . . call e8/call write-stream/disp32 - # discard args + # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP # check-ints-equal(*_test-stream.data, 41/A 62/b 00 00, msg) - # push args + # . . push args 68/push "F - test-write-stream-single"/imm32 68/push 0x006241/imm32/Ab # push *_test-stream.data b8/copy-to-EAX _test-stream/imm32 ff 6/subop/push 1/mod/*+disp8 0/rm32/EAX . . . . 0xc/disp8 . # push *(EAX+12) - # call + # . . call e8/call check-ints-equal/disp32 - # discard args + # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP # end c3/return test-write-stream-appends: # clear-stream(_test-stream) - # push args + # . . push args 68/push _test-stream/imm32 - # call + # . . call e8/call clear-stream/disp32 - # discard args + # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP # clear-stream(_test-stream2) - # push args + # . . push args 68/push _test-stream2/imm32 - # call + # . . call e8/call clear-stream/disp32 - # discard args + # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP # write(_test-stream2, "C") - # push args + # . . push args 68/push "C"/imm32 68/push _test-stream2/imm32 - # call + # . . call e8/call write/disp32 - # discard args + # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP # write-stream(_test-stream, _test-stream2) - # push args + # . . push args 68/push _test-stream2/imm32 68/push _test-stream/imm32 - # call + # . . call e8/call write-stream/disp32 - # discard args + # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP # write(_test-stream2, "D") - # push args + # . . push args 68/push "D"/imm32 68/push _test-stream2/imm32 - # call + # . . call e8/call write/disp32 - # discard args + # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP # write-stream(_test-stream, _test-stream2) - # push args + # . . push args 68/push _test-stream2/imm32 68/push _test-stream/imm32 - # call + # . . call e8/call write-stream/disp32 - # discard args + # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP # check-ints-equal(*_test-stream.data, 43/C 44/D 00 00, msg) - # push args + # . . push args 68/push "F - test-write-stream-appends"/imm32 68/push 0x00004443/imm32/C-D # push *_test-stream.data b8/copy-to-EAX _test-stream/imm32 ff 6/subop/push 1/mod/*+disp8 0/rm32/EAX . . . . 0xc/disp8 . # push *(EAX+12) - # call + # . . call e8/call check-ints-equal/disp32 - # discard args + # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP # end c3/return @@ -236,4 +236,4 @@ _test-stream2: # data 41 42 43 44 00 00 00 00 # 8 bytes -# vim:nowrap:textwidth=0 +# . . vim:nowrap:textwidth=0 diff --git a/subx/apps/crenshaw2-1.subx b/subx/apps/crenshaw2-1.subx index 94fd8efa..35966a22 100644 --- a/subx/apps/crenshaw2-1.subx +++ b/subx/apps/crenshaw2-1.subx @@ -26,12 +26,12 @@ # naming conventions. == code -# instruction effective address operand 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 +# 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 # main: run tests if necessary, call 'compile' if not - # prolog + # . prolog 89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP # if (argc > 1) 81 7/subop/compare 1/mod/*+disp8 4/rm32/sib 5/base/EBP 4/index/none . . 0/disp8 1/imm32 # compare *EBP @@ -77,10 +77,10 @@ $main:end: # the main entry point compile: # in : fd or (address stream), out : fd or (address stream), err : fd or (address stream), ed : (address exit-descriptor) -> <void> - # prolog + # . prolog 55/push-EBP 89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP - # save registers + # . save registers 50/push-EAX 51/push-ECX # Look = get-char(in) @@ -179,10 +179,10 @@ compile: # in : fd or (address stream), out : fd or (address stream), err : fd e8/call write/disp32 # . discard args 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP - # restore registers + # . restore registers 59/pop-to-ECX 58/pop-to-EAX - # epilog + # . epilog 89/copy 3/mod/direct 4/rm32/ESP . . . 5/r32/EBP . . # copy EBP to ESP 5d/pop-to-EBP c3/return @@ -211,7 +211,7 @@ get-num: # in : (address buffered-file), out : (address stream), err : fd or (a # get-char in each iteration of the loop. (Thereby demonstrating that it's # not the right interface for us. But we'll keep it just to follow Crenshaw.) # - # prolog + # . prolog 55/push-EBP 89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP # EAX = is-digit?(Look) @@ -225,16 +225,16 @@ get-num: # in : (address buffered-file), out : (address stream), err : fd or (a 3d/compare-EAX 0/imm32 75/jump-if-not-equal $get-num:main/disp8 # . expected(ed, err, "integer") - # push args + # . . push args 68/push "integer"/imm32 ff 6/subop/push 1/mod/*+disp8 4/rm32/sib 5/base/EBP 4/index/none . . 0x10/disp8 . # push *(EBP+16) ff 6/subop/push 1/mod/*+disp8 4/rm32/sib 5/base/EBP 4/index/none . . 0x14/disp8 . # push *(EBP+20) - # call + # . . call e8/call expected/disp32 # never returns - # discard args + # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP $get-num:main: - # save registers + # . save registers 50/push-EAX 51/push-ECX 52/push-EDX @@ -254,13 +254,13 @@ $get-num:main: 3b/compare 3/mod/direct 1/rm32/ECX . . . 2/r32/EDX . . # compare EDX with ECX 7d/jump-if-lesser $get-num:stage2/disp8 # error(ed, err, "get-num: too many digits in number") # TODO: show full number - # . push args + # . push args 68/push "get-num: too many digits in number"/imm32 ff 6/subop/push 1/mod/*+disp8 4/rm32/sib 5/base/EBP 4/index/none . . 0x10/disp8 . # push *(EBP+16) ff 6/subop/push 1/mod/*+disp8 4/rm32/sib 5/base/EBP 4/index/none . . 0x14/disp8 . # push *(EBP+20) - # . call + # . call e8/call error/disp32 # never returns - # . discard args + # . discard args 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP $get-num:stage2: # out->data[out->write] = LSB(Look) @@ -279,14 +279,14 @@ $get-num:stage2: $get-num:loop-end: # persist necessary variables from registers 89/copy 0/mod/indirect 7/rm32/EDI . . . 1/r32/ECX . . # copy ECX to *EDI - # restore registers + # . restore registers 5f/pop-to-EDI 5e/pop-to-ESI 5b/pop-to-EBX 5a/pop-to-EDX 59/pop-to-ECX 58/pop-to-EAX - # epilog + # . epilog 89/copy 3/mod/direct 4/rm32/ESP . . . 5/r32/EBP . . # copy EBP to ESP 5d/pop-to-EBP c3/return @@ -475,7 +475,7 @@ test-get-num-aborts-on-non-digit-in-Look: # write(f, "Error: "+s+" expected\n") then stop(ed, 1) expected: # ed : (address exit-descriptor), f : fd or (address stream), s : (address array byte) -> <void> - # prolog + # . prolog 55/push-EBP 89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP # write(f, "Error: ") @@ -517,14 +517,14 @@ expected: # ed : (address exit-descriptor), f : fd or (address stream), s : (ad # . call e8/call stop/disp32 ## should never get past this point - # epilog + # . epilog 89/copy 3/mod/direct 4/rm32/ESP . . . 5/r32/EBP . . # copy EBP to ESP 5d/pop-to-EBP c3/return # write(f, "Error: "+s+"\n") then stop(ed, 1) error: # ed : (address exit-descriptor), f : fd or (address stream), s : (address array byte) -> <void> - # prolog + # . prolog 55/push-EBP 89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP # write(f, "Error: ") @@ -558,17 +558,17 @@ error: # ed : (address exit-descriptor), f : fd or (address stream), s : (addre # . call e8/call stop/disp32 ## should never get past this point - # epilog + # . epilog 89/copy 3/mod/direct 4/rm32/ESP . . . 5/r32/EBP . . # copy EBP to ESP 5d/pop-to-EBP c3/return # read a byte from 'f', and store it in 'Look' get-char: # f : (address buffered-file) -> <void> - # prolog + # . prolog 55/push-EBP 89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP - # save registers + # . save registers 50/push-EAX # read-byte(f) # . push args @@ -579,15 +579,15 @@ get-char: # f : (address buffered-file) -> <void> 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP # save EAX to Look 89/copy 0/mod/indirect 5/rm32/.disp32 . . 0/r32/EAX Look/disp32 . # copy EAX to *Look - # restore registers + # . restore registers 58/pop-to-EAX - # epilog + # . epilog 89/copy 3/mod/direct 4/rm32/ESP . . . 5/r32/EBP . . # copy EBP to ESP 5d/pop-to-EBP c3/return is-digit?: # c : int -> bool/EAX - # prolog + # . prolog 55/push-EBP 89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP # EAX = false @@ -601,7 +601,7 @@ is-digit?: # c : int -> bool/EAX # otherwise return true b8/copy-to-EAX 1/imm32 $is-digit?:end: - # epilog + # . epilog 89/copy 3/mod/direct 4/rm32/ESP . . . 5/r32/EBP . . # copy EBP to ESP 5d/pop-to-EBP c3/return @@ -631,4 +631,4 @@ _test-error-stream: # data 00 00 00 00 00 00 00 00 # 8 bytes -# vim:nowrap:textwidth=0 +# . . vim:nowrap:textwidth=0 diff --git a/subx/apps/crenshaw2-1b.subx b/subx/apps/crenshaw2-1b.subx index 2df45308..49436370 100644 --- a/subx/apps/crenshaw2-1b.subx +++ b/subx/apps/crenshaw2-1b.subx @@ -26,23 +26,23 @@ # naming conventions. == code -# instruction effective address operand 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 +# 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 # main: run tests if necessary, call 'compile' if not - # prolog + # . prolog 89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP # if (argc > 1) 81 7/subop/compare 1/mod/*+disp8 4/rm32/sib 5/base/EBP 4/index/none . . 0/disp8 1/imm32 # compare *EBP 7e/jump-if-lesser-or-equal $run-main/disp8 # and if (argv[1] == "test") - # push args + # . . push args 68/push "test"/imm32 ff 6/subop/push 1/mod/*+disp8 4/rm32/sib 5/base/EBP 4/index/none . . 0x8/disp8 . # push *(EBP+8) - # call + # . . call e8/call kernel-string-equal/disp32 - # discard args + # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP # check result 3d/compare-EAX 1/imm32 @@ -60,14 +60,14 @@ $run-main: # clear ed->target (so we really exit) c7/copy 0/mod/direct 0/rm32/EAX . . . . . 0/imm32 # copy to *EAX # compile(Stdin, 1/stdout, 2/stderr, ed) - # push args + # . . push args 50/push-EAX/ed 68/push 2/imm32/stderr 68/push 1/imm32/stdout 68/push Stdin/imm32 - # call + # . . call e8/call compile/disp32 - # discard args + # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0x10/imm32 # add to ESP # syscall(exit, 0) bb/copy-to-EBX 0/imm32 @@ -77,18 +77,18 @@ $main:end: # the main entry point compile: # in : fd or (address stream), out : fd or (address stream), err : fd or (address stream), ed : (address exit-descriptor) -> <void> - # prolog + # . prolog 55/push-EBP 89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP - # save registers + # . save registers 50/push-EAX 51/push-ECX # Look = get-char(in) - # push args + # . . push args ff 6/subop/push 1/mod/*+disp8 4/rm32/sib 5/base/EBP 4/index/none . . 8/disp8 . # push *(EBP+8) - # call + # . . call e8/call get-char/disp32 - # discard args + # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP # var num/ECX : (address stream) on the stack # Numbers can be 32 bits or 8 hex bytes long. One of them will be in 'Look', so we need space for 7 bytes. @@ -99,90 +99,90 @@ compile: # in : fd or (address stream), out : fd or (address stream), err : fd # num->length = 7 c7/copy 1/mod/*+disp8 1/rm32/ECX . . . . 8/disp8 7/imm32 # copy to *(ECX+8) # clear-stream(num) - # push args + # . . push args 51/push-ECX - # call + # . . call e8/call clear-stream/disp32 - # discard args + # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP # get-num(in, num, err, ed) - # push args + # . . push args ff 6/subop/push 1/mod/*+disp8 4/rm32/sib 5/base/EBP 4/index/none . . 0x14/disp8 . # push *(EBP+20) ff 6/subop/push 1/mod/*+disp8 4/rm32/sib 5/base/EBP 4/index/none . . 0x10/disp8 . # push *(EBP+16) 51/push-ECX/num ff 6/subop/push 1/mod/*+disp8 4/rm32/sib 5/base/EBP 4/index/none . . 8/disp8 . # push *(EBP+8) - # call + # . . call e8/call get-num/disp32 - # discard args + # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0x10/imm32 # add to ESP # EAX = write(_test-stream, "Ab") - # push args + # . . push args 68/push "Ab"/imm32 68/push _test-stream/imm32 - # call + # . . call e8/call write/disp32 - # discard args + # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP # EAX = write(out, "bb/copy-to-EBX ") - # push args + # . . push args 68/push "bb/copy-to-EBX "/imm32 ff 6/subop/push 1/mod/*+disp8 4/rm32/sib 5/base/EBP 4/index/none . . 0xc/disp8 . # push *(EBP+12) - # call + # . . call e8/call write/disp32 - # discard args + # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP # write-stream(out, num) - # push args + # . . push args 51/push-ECX/num ff 6/subop/push 1/mod/*+disp8 4/rm32/sib 5/base/EBP 4/index/none . . 0xc/disp8 . # push *(EBP+12) - # call + # . . call e8/call write-stream/disp32 - # discard args + # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP # write(out, Newline) - # push args + # . . push args 68/push Newline/imm32 ff 6/subop/push 1/mod/*+disp8 4/rm32/sib 5/base/EBP 4/index/none . . 0xc/disp8 . # push *(EBP+12) - # call + # . . call e8/call write/disp32 - # discard args + # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP # EAX = write(out, "b8/copy-to-EAX 1/imm32/exit") - # push args + # . . push args 68/push "b8/copy-to-EAX 1/imm32/exit"/imm32 ff 6/subop/push 1/mod/*+disp8 4/rm32/sib 5/base/EBP 4/index/none . . 0xc/disp8 . # push *(EBP+12) - # call + # . . call e8/call write/disp32 - # discard args + # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP # EAX = write(out, Newline) - # push args + # . . push args 68/push Newline/imm32 ff 6/subop/push 1/mod/*+disp8 4/rm32/sib 5/base/EBP 4/index/none . . 0xc/disp8 . # push *(EBP+12) - # call + # . . call e8/call write/disp32 - # discard args + # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP # EAX = write(out, "cd/syscall 0x80/imm8") - # push args + # . . push args 68/push "cd/syscall 0x80/imm8"/imm32 ff 6/subop/push 1/mod/*+disp8 4/rm32/sib 5/base/EBP 4/index/none . . 0xc/disp8 . # push *(EBP+12) - # call + # . . call e8/call write/disp32 - # discard args + # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP # EAX = write(out, Newline) - # push args + # . . push args 68/push Newline/imm32 ff 6/subop/push 1/mod/*+disp8 4/rm32/sib 5/base/EBP 4/index/none . . 0xc/disp8 . # push *(EBP+12) - # call + # . . call e8/call write/disp32 - # discard args + # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP - # restore registers + # . restore registers 59/pop-to-ECX 58/pop-to-EAX - # epilog + # . epilog 89/copy 3/mod/direct 4/rm32/ESP . . . 5/r32/EBP . . # copy EBP to ESP 5d/pop-to-EBP c3/return @@ -216,30 +216,30 @@ get-num: # in : (address buffered-file), out : (address stream), err : fd or (a # get-char in each iteration of the loop. (Thereby demonstrating that it's # not the right interface for us. But we'll keep it just to follow Crenshaw.) # - # prolog + # . prolog 55/push-EBP 89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP # EAX = is-digit?(Look) - # push args + # . . push args ff 6/subop/push 0/mod/indirect 5/rm32/.disp32 . . . Look/disp32 . # push *Look - # call + # . . call e8/call is-digit?/disp32 - # discard args + # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP # if EAX == 0 error 3d/compare-EAX 0/imm32 75/jump-if-not-equal $get-num:main/disp8 # expected(ed, err, "integer") - # push args + # . . push args 68/push "integer"/imm32 ff 6/subop/push 1/mod/*+disp8 4/rm32/sib 5/base/EBP 4/index/none . . 0x10/disp8 . # push *(EBP+16) ff 6/subop/push 1/mod/*+disp8 4/rm32/sib 5/base/EBP 4/index/none . . 0x14/disp8 . # push *(EBP+20) - # call + # . . call e8/call expected/disp32 # never returns - # discard args + # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP $get-num:main: - # save registers + # . save registers 50/push-EAX 51/push-ECX 52/push-EDX @@ -260,13 +260,13 @@ $get-num:loop: 3b/compare 3/mod/direct 1/rm32/ECX . . . 2/r32/EDX . . # compare EDX with ECX 7d/jump-if-lesser $get-num:loop-stage2/disp8 # error(ed, err, "get-num: too many digits in number") # TODO: show full number - # push args + # . . push args 68/push "get-num: too many digits in number"/imm32 ff 6/subop/push 1/mod/*+disp8 4/rm32/sib 5/base/EBP 4/index/none . . 0x10/disp8 . # push *(EBP+16) ff 6/subop/push 1/mod/*+disp8 4/rm32/sib 5/base/EBP 4/index/none . . 0x14/disp8 . # push *(EBP+20) - # call + # . . call e8/call error/disp32 # never returns - # discard args + # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP $get-num:loop-stage2: # out->data[out->write] = LSB(Look) @@ -276,18 +276,18 @@ $get-num:loop-stage2: # ++out->write 41/increment-ECX # Look = get-char(in) - # push args + # . . push args 56/push-ESI - # call + # . . call e8/call get-char/disp32 - # discard args + # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP # EAX = is-digit?(Look) - # push args + # . . push args ff 6/subop/push 0/mod/indirect 5/rm32/.disp32 . . . Look/disp32 . # push *Look - # call + # . . call e8/call is-digit?/disp32 - # discard args + # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP # if EAX loop 3d/compare-EAX 0/imm32 @@ -295,14 +295,14 @@ $get-num:loop-stage2: $get-num:loop-end: # persist necessary variables from registers 89/copy 0/mod/indirect 7/rm32/EDI . . . 1/r32/ECX . . # copy ECX to *EDI - # restore registers + # . restore registers 5f/pop-to-EDI 5e/pop-to-ESI 5b/pop-to-EBX 5a/pop-to-EDX 59/pop-to-ECX 58/pop-to-EAX - # epilog + # . epilog 89/copy 3/mod/direct 4/rm32/ESP . . . 5/r32/EBP . . # copy EBP to ESP 5d/pop-to-EBP c3/return @@ -314,43 +314,43 @@ test-get-num-reads-single-digit: 89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP ## clear all streams # clear-stream(_test-stream) - # push args + # . . push args 68/push _test-stream/imm32 - # call + # . . call e8/call clear-stream/disp32 - # discard args + # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP # clear-stream(_test-buffered-file+4) - # push args + # . . push args b8/copy-to-EAX _test-buffered-file/imm32 05/add-to-EAX 4/imm32 50/push-EAX - # call + # . . call e8/call clear-stream/disp32 - # discard args + # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP # clear-stream(_test-output-stream) - # push args + # . . push args 68/push _test-output-stream/imm32 - # call + # . . call e8/call clear-stream/disp32 - # discard args + # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP # clear-stream(_test-error-stream) - # push args + # . . push args 68/push _test-error-stream/imm32 - # call + # . . call e8/call clear-stream/disp32 - # discard args + # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP ## initialize 'in' # write(_test-stream, "3") - # push args + # . . push args 68/push "3"/imm32 68/push _test-stream/imm32 - # call + # . . call e8/call write/disp32 - # discard args + # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP ## initialize exit-descriptor 'ed' # allocate on stack @@ -359,41 +359,41 @@ test-get-num-reads-single-digit: 8d/copy-address 0/mod/indirect 4/rm32/sib 4/base/ESP 4/index/none . 0/r32/EAX . . # copy ESP to EAX # size the exit-descriptor for the call to get-num below # tailor-exit-descriptor(ed, 16) - # push args + # . . push args 68/push 0x10/imm32/nbytes-of-args-for-get-num 50/push-EAX/ed - # call + # . . call e8/call tailor-exit-descriptor/disp32 - # discard args + # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP ## prime the pump # get-char(_test-buffered-file) - # push args + # . . push args 68/push _test-buffered-file/imm32 - # call + # . . call e8/call get-char/disp32 - # discard args + # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP ## get-num(in, out, err, ed) - # push args + # . . push args 50/push-EAX/ed 68/push _test-error-stream/imm32 68/push _test-output-stream/imm32 68/push _test-buffered-file/imm32 - # call + # . . call e8/call get-num/disp32 ## registers except ESP may be clobbered at this point - # discard args + # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0x10/imm32 # add to ESP # check-ints-equal(*_test-output-stream.data, '3') - # push args + # . . push args 68/push "F - test-get-num-reads-single-digit"/imm32 68/push 0x33/imm32 b8/copy-to-EAX _test-output-stream/imm32 ff 6/subop/push 1/mod/*+disp8 0/rm32/EAX . . . . 0xc/disp8 . # push *(EAX+12) - # call + # . . call e8/call check-ints-equal/disp32 - # discard args + # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP # reclaim locals 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP @@ -407,43 +407,43 @@ test-get-num-aborts-on-non-digit-in-Look: 89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP ## clear all streams # clear-stream(_test-stream) - # push args + # . . push args 68/push _test-stream/imm32 - # call + # . . call e8/call clear-stream/disp32 - # discard args + # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP # clear-stream(_test-buffered-file+4) - # push args + # . . push args b8/copy-to-EAX _test-buffered-file/imm32 05/add-to-EAX 4/imm32 50/push-EAX - # call + # . . call e8/call clear-stream/disp32 - # discard args + # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP # clear-stream(_test-output-stream) - # push args + # . . push args 68/push _test-output-stream/imm32 - # call + # . . call e8/call clear-stream/disp32 - # discard args + # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP # clear-stream(_test-error-stream) - # push args + # . . push args 68/push _test-error-stream/imm32 - # call + # . . call e8/call clear-stream/disp32 - # discard args + # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP ## initialize 'in' # write(_test-stream, "3") - # push args + # . . push args 68/push "3"/imm32 68/push _test-stream/imm32 - # call + # . . call e8/call write/disp32 - # discard args + # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP ## initialize exit-descriptor 'ed' # allocate on stack @@ -452,35 +452,35 @@ test-get-num-aborts-on-non-digit-in-Look: 8d/copy-address 0/mod/indirect 4/rm32/sib 4/base/ESP 4/index/none . 0/r32/EAX . . # copy ESP to EAX # size the exit-descriptor for the call to get-num below # tailor-exit-descriptor(ed, 16) - # push args + # . . push args 68/push 0x10/imm32/nbytes-of-args-for-get-num 50/push-EAX/ed - # call + # . . call e8/call tailor-exit-descriptor/disp32 - # discard args + # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP ## don't initialize Look ## get-num(in, out, err, ed) - # push args + # . . push args 50/push-EAX/ed 68/push _test-error-stream/imm32 68/push _test-output-stream/imm32 68/push _test-buffered-file/imm32 - # call + # . . call e8/call get-num/disp32 ## registers except ESP may be clobbered at this point - # discard args + # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0x10/imm32 # add to ESP ## check that get-num tried to call exit(1) # check-ints-equal(ed->value, 2, msg) # i.e. stop was called with value 1 - # push args + # . . push args 68/push "F - test-get-num-aborts-on-non-digit-in-Look"/imm32 68/push 2/imm32 # push ed->value ff 6/subop/push 1/mod/*+disp8 0/rm32/EAX . . . . 4/disp8 . # push *(EAX+4) - # call + # . . call e8/call check-ints-equal/disp32 - # discard args + # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP # reclaim locals 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP @@ -494,43 +494,43 @@ test-get-num-reads-multiple-digits: 89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP ## clear all streams # clear-stream(_test-stream) - # push args + # . . push args 68/push _test-stream/imm32 - # call + # . . call e8/call clear-stream/disp32 - # discard args + # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP # clear-stream(_test-buffered-file+4) - # push args + # . . push args b8/copy-to-EAX _test-buffered-file/imm32 05/add-to-EAX 4/imm32 50/push-EAX - # call + # . . call e8/call clear-stream/disp32 - # discard args + # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP # clear-stream(_test-output-stream) - # push args + # . . push args 68/push _test-output-stream/imm32 - # call + # . . call e8/call clear-stream/disp32 - # discard args + # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP # clear-stream(_test-error-stream) - # push args + # . . push args 68/push _test-error-stream/imm32 - # call + # . . call e8/call clear-stream/disp32 - # discard args + # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP ## initialize 'in' # write(_test-stream, "3456 x") - # push args + # . . push args 68/push "3456"/imm32 68/push _test-stream/imm32 - # call + # . . call e8/call write/disp32 - # discard args + # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP ## initialize exit-descriptor 'ed' # allocate on stack @@ -539,41 +539,41 @@ test-get-num-reads-multiple-digits: 8d/copy-address 0/mod/indirect 4/rm32/sib 4/base/ESP 4/index/none . 0/r32/EAX . . # copy ESP to EAX # size the exit-descriptor for the call to get-num below # tailor-exit-descriptor(ed, 16) - # push args + # . . push args 68/push 0x10/imm32/nbytes-of-args-for-get-num 50/push-EAX/ed - # call + # . . call e8/call tailor-exit-descriptor/disp32 - # discard args + # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP ## prime the pump # get-char(_test-buffered-file) - # push args + # . . push args 68/push _test-buffered-file/imm32 - # call + # . . call e8/call get-char/disp32 - # discard args + # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP ## get-num(in, out, err, ed) - # push args + # . . push args 50/push-EAX/ed 68/push _test-error-stream/imm32 68/push _test-output-stream/imm32 68/push _test-buffered-file/imm32 - # call + # . . call e8/call get-num/disp32 ## registers except ESP may be clobbered at this point - # discard args + # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0x10/imm32 # add to ESP # check-ints-equal(*_test-output-stream.data, '3456') - # push args + # . . push args 68/push "F - test-get-num-reads-multiple-digits"/imm32 68/push 0x36353433/imm32 b8/copy-to-EAX _test-output-stream/imm32 ff 6/subop/push 1/mod/*+disp8 0/rm32/EAX . . . . 0xc/disp8 . # push *(EAX+12) - # call + # . . call e8/call check-ints-equal/disp32 - # discard args + # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP # reclaim locals 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP @@ -587,43 +587,43 @@ test-get-num-reads-multiple-digits-followed-by-nondigit: 89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP ## clear all streams # clear-stream(_test-stream) - # push args + # . . push args 68/push _test-stream/imm32 - # call + # . . call e8/call clear-stream/disp32 - # discard args + # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP # clear-stream(_test-buffered-file+4) - # push args + # . . push args b8/copy-to-EAX _test-buffered-file/imm32 05/add-to-EAX 4/imm32 50/push-EAX - # call + # . . call e8/call clear-stream/disp32 - # discard args + # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP # clear-stream(_test-output-stream) - # push args + # . . push args 68/push _test-output-stream/imm32 - # call + # . . call e8/call clear-stream/disp32 - # discard args + # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP # clear-stream(_test-error-stream) - # push args + # . . push args 68/push _test-error-stream/imm32 - # call + # . . call e8/call clear-stream/disp32 - # discard args + # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP ## initialize 'in' # write(_test-stream, "3456 x") - # push args + # . . push args 68/push "3456 x"/imm32 68/push _test-stream/imm32 - # call + # . . call e8/call write/disp32 - # discard args + # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP ## initialize exit-descriptor 'ed' # allocate on stack @@ -632,41 +632,41 @@ test-get-num-reads-multiple-digits-followed-by-nondigit: 8d/copy-address 0/mod/indirect 4/rm32/sib 4/base/ESP 4/index/none . 0/r32/EAX . . # copy ESP to EAX # size the exit-descriptor for the call to get-num below # tailor-exit-descriptor(ed, 16) - # push args + # . . push args 68/push 0x10/imm32/nbytes-of-args-for-get-num 50/push-EAX/ed - # call + # . . call e8/call tailor-exit-descriptor/disp32 - # discard args + # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP ## prime the pump # get-char(_test-buffered-file) - # push args + # . . push args 68/push _test-buffered-file/imm32 - # call + # . . call e8/call get-char/disp32 - # discard args + # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP ## get-num(in, out, err, ed) - # push args + # . . push args 50/push-EAX/ed 68/push _test-error-stream/imm32 68/push _test-output-stream/imm32 68/push _test-buffered-file/imm32 - # call + # . . call e8/call get-num/disp32 ## registers except ESP may be clobbered at this point - # discard args + # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0x10/imm32 # add to ESP # check-ints-equal(*_test-output-stream.data, '3456') - # push args + # . . push args 68/push "F - test-get-num-reads-multiple-digits-followed-by-nondigit"/imm32 68/push 0x36353433/imm32 b8/copy-to-EAX _test-output-stream/imm32 ff 6/subop/push 1/mod/*+disp8 0/rm32/EAX . . . . 0xc/disp8 . # push *(EAX+12) - # call + # . . call e8/call check-ints-equal/disp32 - # discard args + # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP # reclaim locals 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP @@ -677,119 +677,119 @@ test-get-num-reads-multiple-digits-followed-by-nondigit: # write(f, "Error: "+s+" expected\n") then stop(ed, 1) expected: # ed : (address exit-descriptor), f : fd or (address stream), s : (address array byte) -> <void> - # prolog + # . prolog 55/push-EBP 89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP # write(f, "Error: ") - # push args + # . . push args 68/push "Error: "/imm32 ff 6/subop/push 1/mod/*+disp8 4/rm32/sib 5/base/EBP 4/index/none . . 0xc/disp8 . # push *(EBP+12) - # call + # . . call e8/call write/disp32 - # discard args + # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP # write(f, s) - # push args + # . . push args ff 6/subop/push 1/mod/*+disp8 4/rm32/sib 5/base/EBP 4/index/none . . 0x10/disp8 . # push *(EBP+16) ff 6/subop/push 1/mod/*+disp8 4/rm32/sib 5/base/EBP 4/index/none . . 0xc/disp8 . # push *(EBP+12) - # call + # . . call e8/call write/disp32 - # discard args + # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP # write(f, " expected") - # push args + # . . push args 68/push " expected"/imm32 ff 6/subop/push 1/mod/*+disp8 4/rm32/sib 5/base/EBP 4/index/none . . 0xc/disp8 . # push *(EBP+12) - # call + # . . call e8/call write/disp32 - # discard args + # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP # write(f, Newline) - # push args + # . . push args 68/push Newline/imm32 ff 6/subop/push 1/mod/*+disp8 4/rm32/sib 5/base/EBP 4/index/none . . 0xc/disp8 . # push *(EBP+12) - # call + # . . call e8/call write/disp32 - # discard args + # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP # stop(ed, 1) - # push args + # . . push args 68/push 1/imm32 ff 6/subop/push 1/mod/*+disp8 4/rm32/sib 5/base/EBP 4/index/none . . 8/disp8 . # push *(EBP+8) - # call + # . . call e8/call stop/disp32 ## should never get past this point - # epilog + # . epilog 89/copy 3/mod/direct 4/rm32/ESP . . . 5/r32/EBP . . # copy EBP to ESP 5d/pop-to-EBP c3/return # write(f, "Error: "+s+"\n") then stop(ed, 1) error: # ed : (address exit-descriptor), f : fd or (address stream), s : (address array byte) -> <void> - # prolog + # . prolog 55/push-EBP 89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP # write(f, "Error: ") - # push args + # . . push args 68/push "Error: "/imm32 ff 6/subop/push 1/mod/*+disp8 4/rm32/sib 5/base/EBP 4/index/none . . 0xc/disp8 . # push *(EBP+12) - # call + # . . call e8/call write/disp32 - # discard args + # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP # write(f, s) - # push args + # . . push args ff 6/subop/push 1/mod/*+disp8 4/rm32/sib 5/base/EBP 4/index/none . . 0x10/disp8 . # push *(EBP+16) ff 6/subop/push 1/mod/*+disp8 4/rm32/sib 5/base/EBP 4/index/none . . 0xc/disp8 . # push *(EBP+12) - # call + # . . call e8/call write/disp32 - # discard args + # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP # write(f, Newline) - # push args + # . . push args 68/push Newline/imm32 ff 6/subop/push 1/mod/*+disp8 4/rm32/sib 5/base/EBP 4/index/none . . 0xc/disp8 . # push *(EBP+12) - # call + # . . call e8/call write/disp32 - # discard args + # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP # stop(ed, 1) - # push args + # . . push args 68/push 1/imm32 ff 6/subop/push 1/mod/*+disp8 4/rm32/sib 5/base/EBP 4/index/none . . 8/disp8 . # push *(EBP+8) - # call + # . . call e8/call stop/disp32 ## should never get past this point - # epilog + # . epilog 89/copy 3/mod/direct 4/rm32/ESP . . . 5/r32/EBP . . # copy EBP to ESP 5d/pop-to-EBP c3/return # read a byte from 'f', and store it in 'Look' get-char: # f : (address buffered-file) -> <void> - # prolog + # . prolog 55/push-EBP 89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP - # save registers + # . save registers 50/push-EAX # read-byte(f) - # push args + # . . push args ff 6/subop/push 1/mod/*+disp8 4/rm32/sib 5/base/EBP 4/index/none . . 0x8/disp8 . # push *(EBP+8) - # call + # . . call e8/call read-byte/disp32 - # discard args + # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP # save EAX to Look 89/copy 0/mod/indirect 5/rm32/.disp32 . . 0/r32/EAX Look/disp32 . # copy EAX to *Look - # restore registers + # . restore registers 58/pop-to-EAX - # epilog + # . epilog 89/copy 3/mod/direct 4/rm32/ESP . . . 5/r32/EBP . . # copy EBP to ESP 5d/pop-to-EBP c3/return is-digit?: # c : int -> bool/EAX - # prolog + # . prolog 55/push-EBP 89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP # EAX = false @@ -803,7 +803,7 @@ is-digit?: # c : int -> bool/EAX # otherwise return true b8/copy-to-EAX 1/imm32 $is-digit?:end: - # epilog + # . epilog 89/copy 3/mod/direct 4/rm32/ESP . . . 5/r32/EBP . . # copy EBP to ESP 5d/pop-to-EBP c3/return @@ -833,4 +833,4 @@ _test-error-stream: # data 00 00 00 00 00 00 00 00 # 8 bytes -# vim:nowrap:textwidth=0 +# . . vim:nowrap:textwidth=0 diff --git a/subx/apps/factorial.subx b/subx/apps/factorial.subx index 1e0191d1..f7675962 100644 --- a/subx/apps/factorial.subx +++ b/subx/apps/factorial.subx @@ -15,23 +15,23 @@ # When running tests the exit status doesn't mean anything. Yet. == code -# instruction effective address operand 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 +# 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 # main: - # prolog + # . prolog 89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP # if (argc > 1) 81 7/subop/compare 1/mod/*+disp8 4/rm32/sib 5/base/EBP 4/index/none . . 0/disp8 1/imm32 # compare *EBP 7e/jump-if-lesser-or-equal $run-main/disp8 # and if (argv[1] == "test") - # push args + # . . push args 68/push "test"/imm32 ff 6/subop/push 1/mod/*+disp8 4/rm32/sib 5/base/EBP 4/index/none . . 0x8/disp8 . # push *(EBP+8) - # call + # . . call e8/call kernel-string-equal/disp32 - # discard args + # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP # check result 3d/compare-EAX 1/imm32 @@ -42,11 +42,11 @@ eb/jump $main:end/disp8 # where EAX will get copied to EBX # else EAX = factorial(5) $run-main: - # push args + # . . push args 68/push 5/imm32 - # call + # . . call e8/call factorial/disp32 - # discard args + # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP $main:end: # exit(EAX) @@ -56,7 +56,7 @@ $main:end: # factorial(n) factorial: - # prolog + # . prolog 55/push-EBP 89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP 53/push-EBX @@ -69,17 +69,17 @@ factorial: 8b/copy 1/mod/*+disp8 4/rm32/sib 5/base/EBP 4/index/none 3/r32/EBX 8/disp8 . # copy *(EBP+8) to EBX 81 5/subop/subtract 3/mod/direct 3/rm32/EBX . . . . . 1/imm32 # subtract from EBX # EAX = factorial(n-1) - # push args + # . . push args 53/push-EBX - # call + # . . call e8/call factorial/disp32 - # discard args + # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP # return n * factorial(n-1) f7 4/subop/multiply 1/mod/*+disp8 4/rm32/sib 5/base/EBP 4/index/none 8/disp8 . # multiply *(EBP+8) into EAX # TODO: check for overflow $factorial:end: - # epilog + # . epilog 5b/pop-to-EBX 89/copy 3/mod/direct 4/rm32/ESP . . . 5/r32/EBP . . # copy EBP to ESP 5d/pop-to-EBP @@ -87,22 +87,22 @@ $factorial:end: test-factorial: # factorial(5) - # push args + # . . push args 68/push 5/imm32 - # call + # . . call e8/call factorial/disp32 - # discard args + # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP # check-ints-equal(EAX, 120, failure message) - # push args + # . . push args 68/push "F - test-factorial"/imm32 68/push 0x78/imm32/expected-120 50/push-EAX - # call + # . . call e8/call check-ints-equal/disp32 - # discard args + # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP # end c3/return -# vim:nowrap:textwidth=0 +# . . vim:nowrap:textwidth=0 diff --git a/subx/examples/ex1.subx b/subx/examples/ex1.subx index 8bef59e7..3371cd75 100644 --- a/subx/examples/ex1.subx +++ b/subx/examples/ex1.subx @@ -15,4 +15,4 @@ bb/copy-to-EBX 2a/imm32 # 42 in hex b8/copy-to-EAX 1/imm32/exit cd/syscall 0x80/imm8 -# vim:nowrap:textwidth=0 +# . . vim:nowrap:textwidth=0 diff --git a/subx/examples/ex10.subx b/subx/examples/ex10.subx index 4da713ae..936edb08 100644 --- a/subx/examples/ex10.subx +++ b/subx/examples/ex10.subx @@ -8,9 +8,9 @@ # 0 # false == code -# instruction effective address operand 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 +# 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 # main: return argv-equal(argv[1], argv[2]) # At the start of a SubX program: @@ -18,14 +18,14 @@ # argv[0]: *(ESP+4) # argv[1]: *(ESP+8) # ... - # prolog + # . prolog 89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP - # call argv-equal(argv[1], argv[2]) + # . . call argv-equal(argv[1], argv[2]) # push argv[2] ff 6/subop/push 1/mod/*+disp8 4/rm32/sib 5/base/EBP 4/index/none . . 0xc/disp8 . # push *(EBP+12) # push argv[1] ff 6/subop/push 1/mod/*+disp8 4/rm32/sib 5/base/EBP 4/index/none . . 0x8/disp8 . # push *(EBP+8) - # call + # . . call e8/call argv-equal/disp32 # exit(EAX) $exit: @@ -69,4 +69,4 @@ $argv-equal:false: b8/copy-to-EAX 0/imm32 c3/return -# vim:nowrap:textwidth=0 +# . . vim:nowrap:textwidth=0 diff --git a/subx/examples/ex11.subx b/subx/examples/ex11.subx index 247a0076..253b91ab 100644 --- a/subx/examples/ex11.subx +++ b/subx/examples/ex11.subx @@ -15,9 +15,9 @@ # would cause tests to not run, rather than to fail as we'd like.) == code -# instruction effective address operand 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 +# 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 # main: e8/call run-tests/disp32 # 'run-tests' is a function created automatically by SubX. It calls all functions that start with 'test-'. @@ -29,10 +29,10 @@ # 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 - # prolog + # . prolog 55/push-EBP 89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP - # save registers + # . save registers 51/push-ECX 52/push-EDX 53/push-EBX @@ -97,7 +97,7 @@ $kernel-string-equal:false: b8/copy-to-EAX 0/imm32 $kernel-string-equal:end: - # restore registers + # . restore registers 5f/pop-to-EDI 5e/pop-to-ESI 5b/pop-to-EBX @@ -112,141 +112,141 @@ $kernel-string-equal:end: test-compare-null-kernel-string-with-empty-array: # EAX = kernel-string-equal(Null-kernel-string, "") - # push args + # . . push args 68/push ""/imm32 68/push Null-kernel-string/imm32 - # call + # . . call e8/call kernel-string-equal/disp32 - # discard args + # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP - # call check-ints-equal(EAX, 1, msg) - # push args + # . . call 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 + # . . call e8/call check-ints-equal/disp32 - # discard args + # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP c3/return test-compare-null-kernel-string-with-non-empty-array: # EAX = kernel-string-equal(Null-kernel-string, "Abc") - # push args + # . . push args 68/push "Abc"/imm32 68/push Null-kernel-string/imm32 - # call + # . . call e8/call kernel-string-equal/disp32 - # discard args + # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP - # call check-ints-equal(EAX, 0, msg) - # push args + # . . call 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 + # . . call e8/call check-ints-equal/disp32 - # discard args + # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP c3/return test-compare-kernel-string-with-equal-array: # EAX = kernel-string-equal(Abc-kernel-string, "Abc") - # push args + # . . push args 68/push "Abc"/imm32 68/push Abc-kernel-string/imm32 - # call + # . . call e8/call kernel-string-equal/disp32 - # discard args + # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP - # call check-ints-equal(EAX, 1, msg) - # push args + # . . call 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 + # . . call e8/call check-ints-equal/disp32 - # discard args + # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP c3/return test-compare-kernel-string-with-inequal-array: # EAX = kernel-string-equal(Abc-kernel-string, "Adc") - # push args + # . . push args 68/push "Adc"/imm32 68/push Abc-kernel-string/imm32 - # call + # . . call e8/call kernel-string-equal/disp32 - # discard args + # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP - # call check-ints-equal(EAX, 0, msg) - # push args + # . . call 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 + # . . call e8/call check-ints-equal/disp32 - # discard args + # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP c3/return test-compare-kernel-string-with-empty-array: # EAX = kernel-string-equal(Abc-kernel-string, "") - # push args + # . . push args 68/push ""/imm32 68/push Abc-kernel-string/imm32 - # call + # . . call e8/call kernel-string-equal/disp32 - # discard args + # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP - # call check-ints-equal(EAX, 0) - # push args + # . . call check-ints-equal(EAX, 0) + # . . push args 68/push "F - test-compare-kernel-string-with-equal-array"/imm32 68/push 0/imm32/false 50/push-EAX - # call + # . . call e8/call check-ints-equal/disp32 - # discard args + # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP c3/return test-compare-kernel-string-with-shorter-array: # EAX = kernel-string-equal(Abc-kernel-string, "Ab") - # push args + # . . push args 68/push "Ab"/imm32 68/push Abc-kernel-string/imm32 - # call + # . . call e8/call kernel-string-equal/disp32 - # discard args + # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP - # call check-ints-equal(EAX, 0) - # push args + # . . call check-ints-equal(EAX, 0) + # . . push args 68/push "F - test-compare-kernel-string-with-shorter-array"/imm32 68/push 0/imm32/false 50/push-EAX - # call + # . . call e8/call check-ints-equal/disp32 - # discard args + # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP c3/return test-compare-kernel-string-with-longer-array: # EAX = kernel-string-equal(Abc-kernel-string, "Abcd") - # push args + # . . push args 68/push "Abcd"/imm32 68/push Abc-kernel-string/imm32 - # call + # . . call e8/call kernel-string-equal/disp32 - # discard args + # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP - # call check-ints-equal(EAX, 0) - # push args + # . . call check-ints-equal(EAX, 0) + # . . push args 68/push "F - test-compare-kernel-string-with-longer-array"/imm32 68/push 0/imm32/false 50/push-EAX - # call + # . . call e8/call check-ints-equal/disp32 - # discard args + # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP c3/return @@ -254,10 +254,10 @@ test-compare-kernel-string-with-longer-array: # print msg to stderr if a != b, otherwise print "." check-ints-equal: # (a : int, b : int, msg : (address array byte)) -> boolean - # prolog + # . prolog 55/push-EBP 89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP - # save registers + # . save registers 51/push-ECX 53/push-EBX # load args into EAX, EBX and ECX @@ -267,11 +267,11 @@ check-ints-equal: # (a : int, b : int, msg : (address array byte)) -> boolean 39/compare 3/mod/direct 0/rm32/EAX . . . 3/r32/EBX . . # compare EAX and EBX 75/jump-if-unequal $check-ints-equal:else/disp8 # print('.') - # push args + # . . push args 68/push "."/imm32 - # call + # . . call e8/call write-stderr/disp32 - # discard args + # . . 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 @@ -280,21 +280,21 @@ $check-ints-equal:else: # copy msg into ECX 8b/copy 1/mod/*+disp8 4/rm32/sib 5/base/EBP 4/index/none . 1/r32/ECX 0x10/disp8 . # copy *(EBP+16) to ECX # print(ECX) - # push args + # . . push args 51/push-ECX - # call + # . . call e8/call write-stderr/disp32 - # discard args + # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP # print newline - # push args + # . . push args 68/push Newline/imm32 - # call + # . . call e8/call write-stderr/disp32 - # discard args + # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP $check-ints-equal:end: - # restore registers + # . restore registers 5b/pop-to-EBX 59/pop-to-ECX # end @@ -303,10 +303,10 @@ $check-ints-equal:end: c3/return write-stderr: # s : (address array byte) -> <void> - # prolog + # . prolog 55/push-EBP 89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP - # save registers + # . save registers 50/push-EAX 51/push-ECX 52/push-EDX @@ -323,7 +323,7 @@ write-stderr: # s : (address array byte) -> <void> # syscall b8/copy-to-EAX 4/imm32/write cd/syscall 0x80/imm8 - # restore registers + # . restore registers 5b/pop-to-EBX 5a/pop-to-EDX 59/pop-to-ECX @@ -347,4 +347,4 @@ Null-kernel-string: Abc-kernel-string: 41/A 62/b 63/c 00/null -# vim:nowrap:textwidth=0 +# . . vim:nowrap:textwidth=0 diff --git a/subx/examples/ex12.subx b/subx/examples/ex12.subx index 73d78d96..565c8d50 100644 --- a/subx/examples/ex12.subx +++ b/subx/examples/ex12.subx @@ -7,9 +7,9 @@ # You shouldn't get a segmentation fault. == code -# instruction effective address operand 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 +# 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 # syscall(mmap, 0x1000) bb/copy-to-EBX Mmap-new-segment/imm32 @@ -41,4 +41,4 @@ Mmap-new-segment: # type mmap_arg_struct # offset 00 00 00 00 # 0 since MAP_ANONYMOUS is specified -# vim:nowrap:textwidth=0 +# . . vim:nowrap:textwidth=0 diff --git a/subx/examples/ex2.subx b/subx/examples/ex2.subx index 09fe4414..f7be9b65 100644 --- a/subx/examples/ex2.subx +++ b/subx/examples/ex2.subx @@ -15,4 +15,4 @@ bb/copy-to-EBX 1/imm32 b8/copy-to-EAX 1/imm32 cd/syscall 0x80/imm8 -# vim:nowrap:textwidth=0 +# . . vim:nowrap:textwidth=0 diff --git a/subx/examples/ex3.subx b/subx/examples/ex3.subx index b3f7d6fe..b6e21698 100644 --- a/subx/examples/ex3.subx +++ b/subx/examples/ex3.subx @@ -8,9 +8,9 @@ # 55 == code -# instruction effective address operand 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 +# 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 # result: EBX = 0 bb/copy-to-EBX 0/imm32 @@ -33,4 +33,4 @@ $exit: b8/copy-to-EAX 1/imm32 cd/syscall 0x80/imm8 -# vim:nowrap:textwidth=0 +# . . vim:nowrap:textwidth=0 diff --git a/subx/examples/ex4.subx b/subx/examples/ex4.subx index 445f7d1b..2fd15cd7 100644 --- a/subx/examples/ex4.subx +++ b/subx/examples/ex4.subx @@ -37,4 +37,4 @@ cd/syscall 0x80/imm8 X: 00 00 00 00 # space for read() to write to -# vim:nowrap:textwidth=0 +# . . vim:nowrap:textwidth=0 diff --git a/subx/examples/ex5.subx b/subx/examples/ex5.subx index 44291b35..136c177b 100644 --- a/subx/examples/ex5.subx +++ b/subx/examples/ex5.subx @@ -5,9 +5,9 @@ # $ subx run examples/ex5 == code -# instruction effective address operand 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 +# 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 # main: # allocate x on the stack @@ -39,4 +39,4 @@ b8/copy-to-EAX 1/imm32/exit cd/syscall 0x80/imm8 -# vim:nowrap:textwidth=0 +# . . vim:nowrap:textwidth=0 diff --git a/subx/examples/ex6.subx b/subx/examples/ex6.subx index 10331808..fc266a3a 100644 --- a/subx/examples/ex6.subx +++ b/subx/examples/ex6.subx @@ -6,9 +6,9 @@ # Hello, world! == code -# instruction effective address operand 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 +# 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 # syscall(write, stdout, X, size) # fd = 1 (stdout) @@ -33,4 +33,4 @@ 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 +# . . vim:nowrap:textwidth=0 diff --git a/subx/examples/ex7.subx b/subx/examples/ex7.subx index 93b568f9..3650817d 100644 --- a/subx/examples/ex7.subx +++ b/subx/examples/ex7.subx @@ -11,9 +11,9 @@ # 97 == code -# instruction effective address operand 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 +# 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 # syscall(creat, Filename) bb/copy-to-EBX Filename/imm32 @@ -101,4 +101,4 @@ B: Filename: 2e 66 6f 6f 00 00 00 00 -# vim:nowrap:textwidth=0 +# . . vim:nowrap:textwidth=0 diff --git a/subx/examples/ex8.subx b/subx/examples/ex8.subx index fd7929f4..410dfe08 100644 --- a/subx/examples/ex8.subx +++ b/subx/examples/ex8.subx @@ -15,18 +15,18 @@ # Locals start from ESP-4 downwards. == code -# instruction effective address operand 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 +# 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 - # prolog + # . prolog 89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP - # call ascii-length(argv[1]) - # push args + # . . call ascii-length(argv[1]) + # . . push args ff 6/subop/push 1/mod/*+disp8 4/rm32/sib 5/base/EBP 4/index/none . . 0x8/disp8 . # push *(EBP+8) - # call + # . . call e8/call ascii-length/disp32 - # discard args + # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP # exit(EAX) @@ -55,4 +55,4 @@ $ascii-length-ret: # return (result in EAX) c3/return -# vim:nowrap:textwidth=0 +# . . vim:nowrap:textwidth=0 diff --git a/subx/examples/ex9.subx b/subx/examples/ex9.subx index 00f2d661..964151a2 100644 --- a/subx/examples/ex9.subx +++ b/subx/examples/ex9.subx @@ -17,20 +17,20 @@ # Locals start from ESP-4 downwards. == code -# instruction effective address operand 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 +# 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 - # prolog + # . prolog 89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP - # call ascii-difference(argv[1], argv[2]) + # . . call ascii-difference(argv[1], argv[2]) # push argv[2] ff 6/subop/push 1/mod/*+disp8 4/rm32/sib 5/base/EBP 4/index/none . . 0xc/disp8 . # push *(EBP+12) # push argv[1] ff 6/subop/push 1/mod/*+disp8 4/rm32/sib 5/base/EBP 4/index/none . . 0x8/disp8 . # push *(EBP+8) - # call + # . . call e8/call ascii-difference/disp32 - # discard args + # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP # exit(EAX) 89/copy 3/mod/direct 3/rm32/EBX . . . 0/r32/EAX . . # copy EAX to EBX @@ -48,4 +48,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 -# vim:nowrap:textwidth=0 +# . . vim:nowrap:textwidth=0 |