Standardize on hyphens in all names.
And we'll use colons for namespacing labels in functions.
This commit is contained in:
Kartik Agaram 2018-10-05 19:49:47 -07:00
parent 7163541bf2
commit 03d50cc83c
17 changed files with 251 additions and 246 deletions

View File

@ -11,34 +11,34 @@ Transform.push_back(create_test_function);
% Reg[ESP].u = 0x100;
== 0x1
main:
e8/call run_tests/disp32 # 5 bytes
e8/call run-tests/disp32 # 5 bytes
f4/halt # 1 byte
test_foo: # offset 7
test-foo: # offset 7
01 d8 # just some unique instruction: add EBX to EAX
c3/return
# check that code in test_foo ran (implicitly called by run_tests)
# check that code in test_foo ran (implicitly called by run-tests)
+run: inst: 0x00000007
:(code)
void create_test_function(program& p) {
if (p.segments.empty()) return;
segment& code = p.segments.at(0);
trace(99, "transform") << "-- create 'run_tests'" << end();
trace(99, "transform") << "-- create 'run-tests'" << end();
vector<line> new_insts;
for (int i = 0; i < SIZE(code.lines); ++i) {
line& inst = code.lines.at(i);
for (int j = 0; j < SIZE(inst.words); ++j) {
const word& curr = inst.words.at(j);
if (*curr.data.rbegin() != ':') continue; // not a label
if (!starts_with(curr.data, "test_")) continue;
if (!starts_with(curr.data, "test-")) continue;
string fn = drop_last(curr.data);
new_insts.push_back(call(fn));
}
}
if (new_insts.empty()) return; // no tests found
code.lines.push_back(label("run_tests"));
code.lines.push_back(label("run-tests"));
code.lines.insert(code.lines.end(), new_insts.begin(), new_insts.end());
code.lines.push_back(ret());
}

View File

@ -4,7 +4,7 @@
# op subop mod rm32 base index scale r32
# 1-3 bytes 3 bits 2 bits 3 bits 3 bits 3 bits 2 bits 2 bits 0/1/2/4 bytes 0/1/2/4 bytes
write_stderr: # s : (address array byte) -> <void>
write-stderr: # s : (address array byte) -> <void>
# prolog
55/push-EBP
89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP

View File

@ -5,7 +5,7 @@
# 1-3 bytes 3 bits 2 bits 3 bits 3 bits 3 bits 2 bits 2 bits 0/1/2/4 bytes 0/1/2/4 bytes
# print msg to stderr if a != b, otherwise print "."
check_ints_equal: # (a : int, b : int, msg : (address array byte)) -> boolean
check-ints-equal: # (a : int, b : int, msg : (address array byte)) -> boolean
# prolog
55/push-EBP
89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP
@ -17,37 +17,37 @@ check_ints_equal: # (a : int, b : int, msg : (address array byte)) -> boolean
8b/copy 1/mod/*+disp8 4/rm32/sib 5/base/EBP 4/index/none . 3/r32/EBX 0xc/disp8 . # copy *(EBP+12) to EBX
# if EAX == b/EBX
39/compare 3/mod/direct 0/rm32/EAX . . . 3/r32/EBX . . # compare EAX and EBX
75/jump-if-unequal $check_ints_equal:else/disp8
75/jump-if-unequal $check-ints-equal:else/disp8
# print('.')
# push args
68/push "."/imm32
# call
e8/call write_stderr/disp32
e8/call write-stderr/disp32
# discard arg
81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP
# return
eb/jump $check_ints_equal:end/disp8
eb/jump $check-ints-equal:end/disp8
# else:
$check_ints_equal:else:
$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
51/push-ECX
# call
e8/call write_stderr/disp32
e8/call write-stderr/disp32
# discard arg
81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP
# print newline
# push args
68/push Newline/imm32
# call
e8/call write_stderr/disp32
e8/call write-stderr/disp32
# discard arg
81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/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:
# 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
5b/pop-to-EBX
59/pop-to-ECX
@ -64,7 +64,7 @@ Newline:
# data
0a/newline
Num_test_failures:
Num-test-failures:
00 00 00 00
# vim:nowrap:textwidth=0

View File

@ -21,15 +21,15 @@
# 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)
e8/call run_tests/disp32 # 'run_tests' is a function created automatically by SubX. It calls all functions that start with 'test_'.
# exit(Num_test_failures)
8b/copy 0/mod/indirect 5/rm32/.disp32 . . 3/r32/EBX Num_test_failures/disp32 # copy *Num_test_failures to EBX
e8/call run-tests/disp32 # 'run-tests' is a function created automatically by SubX. It calls all functions that start with 'test-'.
# exit(Num-test-failures)
8b/copy 0/mod/indirect 5/rm32/.disp32 . . 3/r32/EBX Num-test-failures/disp32 # copy *Num-test-failures to EBX
b8/copy . . . . . . . 1/imm32 # copy to EAX
cd/syscall 0x80/imm8
# compare a null-terminated ascii string with a more idiomatic length-prefixed byte array
# reason for the name: the only place we should have null-terminated ascii strings is from commandline args
kernel_string_equal: # s : null-terminated ascii string, benchmark : length-prefixed ascii string -> EAX : boolean
kernel-string-equal: # s : null-terminated ascii string, benchmark : length-prefixed ascii string -> EAX : boolean
# prolog
55/push-EBP
89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP
@ -65,9 +65,9 @@ kernel_string_equal: # s : null-terminated ascii string, benchmark : length-pre
# initialize loop counter i into ECX
b9/copy . . . . . . . 0/imm32/exit # copy to ECX
# while (i/ECX < n/EDX)
$kernel_string_loop:
$kernel-string-equal:loop:
39/compare 3/mod/direct 1/rm32/ECX . . . 2/r32/EDX . . # compare ECX with EDX
74/jump-if-equal $kernel_string_break/disp8
74/jump-if-equal $kernel-string-equal:break/disp8
# c1/EAX, c2/EBX = *s, *benchmark
b8/copy 0/imm32 # clear EAX
8a/copy 0/mod/indirect 7/rm32/EDI . . . 0/r32/EAX . . # copy byte at *EDI to lower byte of EAX
@ -75,29 +75,30 @@ $kernel_string_loop:
8a/copy 0/mod/indirect 6/rm32/ESI . . . 3/r32/EBX . . # copy byte at *ESI to lower byte of EBX
# if (c1 == 0) return false
3d/compare-EAX 0/imm32
74/jump-if-equal $kernel_string_fail/disp8
74/jump-if-equal $kernel-string-equal:false/disp8
# if (c1 != c2) return false
39/compare 3/mod/direct 0/rm32/EAX . . . 3/r32/EBX . . # compare EAX with EBX
75/jump-if-not-equal $kernel_string_fail/disp8
75/jump-if-not-equal $kernel-string-equal:false/disp8
# ++s1, ++s2, ++i
41/inc-ECX
46/inc-ESI
47/inc-EDI
# end while
eb/jump $kernel_string_loop/disp8
$kernel_string_break:
eb/jump $kernel-string-equal:loop/disp8
$kernel-string-equal:break:
# if (*s/EDI == 0) return true
b8/copy 0/imm32 # clear EAX
8a/copy 0/mod/indirect 7/rm32/EDI . . . 0/r32/EAX . . # copy byte at *EDI to lower byte of EAX
3d/compare-EAX 0/imm32
75/jump-if-not-equal $kernel_string_fail/disp8
75/jump-if-not-equal $kernel-string-equal:false/disp8
$kernel-string-equal:true:
b8/copy . . . . . . . 1/imm32 # copy to EAX
eb/jump $kernel_string_end/disp8
eb/jump $kernel-string-equal:end/disp8
# return false
$kernel_string_fail:
$kernel-string-equal:false:
b8/copy . . . . . . . 0/imm32 # copy to EAX
$kernel_string_end:
$kernel-string-equal:end:
# restore registers
5f/pop-to-EDI
5e/pop-to-ESI
@ -111,151 +112,151 @@ $kernel_string_end:
## tests
test_compare_null_kernel_string_with_empty_array:
# EAX = kernel_string_equal(Null_kernel_string, "")
test-compare-null-kernel-string-with-empty-array:
# EAX = kernel-string-equal(Null-kernel-string, "")
# push args
68/push ""/imm32
68/push Null_kernel_string/imm32
68/push Null-kernel-string/imm32
# call
e8/call kernel_string_equal/disp32
e8/call kernel-string-equal/disp32
# discard args
81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP
# call check_ints_equal(EAX, 1, msg)
# call check-ints-equal(EAX, 1, msg)
# push args
68/push "F - test_compare_null_kernel_string_with_empty_array"/imm32
68/push "F - test-compare-null-kernel-string-with-empty-array"/imm32
68/push 1/imm32/true
50/push-EAX
# call
e8/call check_ints_equal/disp32
e8/call check-ints-equal/disp32
# discard args
81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP
c3/return
test_compare_null_kernel_string_with_non_empty_array:
# EAX = kernel_string_equal(Null_kernel_string, "Abc")
test-compare-null-kernel-string-with-non-empty-array:
# EAX = kernel-string-equal(Null-kernel-string, "Abc")
# push args
68/push "Abc"/imm32
68/push Null_kernel_string/imm32
68/push Null-kernel-string/imm32
# call
e8/call kernel_string_equal/disp32
e8/call kernel-string-equal/disp32
# discard args
81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP
# call check_ints_equal(EAX, 0, msg)
# call check-ints-equal(EAX, 0, msg)
# push args
68/push "F - test_compare_null_kernel_string_with_non_empty_array"/imm32
68/push "F - test-compare-null-kernel-string-with-non-empty-array"/imm32
68/push 0/imm32/false
50/push-EAX
# call
e8/call check_ints_equal/disp32
e8/call check-ints-equal/disp32
# discard args
81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP
c3/return
test_compare_kernel_string_with_equal_array:
# EAX = kernel_string_equal(Abc_kernel_string, "Abc")
test-compare-kernel-string-with-equal-array:
# EAX = kernel-string-equal(Abc-kernel-string, "Abc")
# push args
68/push "Abc"/imm32
68/push Abc_kernel_string/imm32
68/push Abc-kernel-string/imm32
# call
e8/call kernel_string_equal/disp32
e8/call kernel-string-equal/disp32
# discard args
81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP
# call check_ints_equal(EAX, 1, msg)
# call check-ints-equal(EAX, 1, msg)
# push args
68/push "F - test_compare_kernel_string_with_equal_array"/imm32
68/push "F - test-compare-kernel-string-with-equal-array"/imm32
68/push 1/imm32/true
50/push-EAX
# call
e8/call check_ints_equal/disp32
e8/call check-ints-equal/disp32
# discard args
81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP
c3/return
test_compare_kernel_string_with_inequal_array:
# EAX = kernel_string_equal(Abc_kernel_string, "Adc")
test-compare-kernel-string-with-inequal-array:
# EAX = kernel-string-equal(Abc-kernel-string, "Adc")
# push args
68/push "Adc"/imm32
68/push Abc_kernel_string/imm32
68/push Abc-kernel-string/imm32
# call
e8/call kernel_string_equal/disp32
e8/call kernel-string-equal/disp32
# discard args
81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP
# call check_ints_equal(EAX, 0, msg)
# call check-ints-equal(EAX, 0, msg)
# push args
68/push "F - test_compare_kernel_string_with_equal_array"/imm32
68/push "F - test-compare-kernel-string-with-equal-array"/imm32
68/push 0/imm32/false
50/push-EAX
# call
e8/call check_ints_equal/disp32
e8/call check-ints-equal/disp32
# discard args
81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP
c3/return
test_compare_kernel_string_with_empty_array:
# EAX = kernel_string_equal(Abc_kernel_string, "")
test-compare-kernel-string-with-empty-array:
# EAX = kernel-string-equal(Abc-kernel-string, "")
# push args
68/push ""/imm32
68/push Abc_kernel_string/imm32
68/push Abc-kernel-string/imm32
# call
e8/call kernel_string_equal/disp32
e8/call kernel-string-equal/disp32
# discard args
81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP
# call check_ints_equal(EAX, 0)
# call check-ints-equal(EAX, 0)
# push args
68/push "F - test_compare_kernel_string_with_equal_array"/imm32
68/push "F - test-compare-kernel-string-with-equal-array"/imm32
68/push 0/imm32/false
50/push-EAX
# call
e8/call check_ints_equal/disp32
e8/call check-ints-equal/disp32
# discard args
81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP
c3/return
test_compare_kernel_string_with_shorter_array:
# EAX = kernel_string_equal(Abc_kernel_string, "Ab")
test-compare-kernel-string-with-shorter-array:
# EAX = kernel-string-equal(Abc-kernel-string, "Ab")
# push args
68/push "Ab"/imm32
68/push Abc_kernel_string/imm32
68/push Abc-kernel-string/imm32
# call
e8/call kernel_string_equal/disp32
e8/call kernel-string-equal/disp32
# discard args
81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP
# call check_ints_equal(EAX, 0)
# call check-ints-equal(EAX, 0)
# push args
68/push "F - test_compare_kernel_string_with_shorter_array"/imm32
68/push "F - test-compare-kernel-string-with-shorter-array"/imm32
68/push 0/imm32/false
50/push-EAX
# call
e8/call check_ints_equal/disp32
e8/call check-ints-equal/disp32
# discard args
81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP
c3/return
test_compare_kernel_string_with_longer_array:
# EAX = kernel_string_equal(Abc_kernel_string, "Abcd")
test-compare-kernel-string-with-longer-array:
# EAX = kernel-string-equal(Abc-kernel-string, "Abcd")
# push args
68/push "Abcd"/imm32
68/push Abc_kernel_string/imm32
68/push Abc-kernel-string/imm32
# call
e8/call kernel_string_equal/disp32
e8/call kernel-string-equal/disp32
# discard args
81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP
# call check_ints_equal(EAX, 0)
# call check-ints-equal(EAX, 0)
# push args
68/push "F - test_compare_kernel_string_with_longer_array"/imm32
68/push "F - test-compare-kernel-string-with-longer-array"/imm32
68/push 0/imm32/false
50/push-EAX
# call
e8/call check_ints_equal/disp32
e8/call check-ints-equal/disp32
# discard args
81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP
c3/return
== data
Null_kernel_string:
Null-kernel-string:
00/null
Abc_kernel_string:
Abc-kernel-string:
41/A 62/b 63/c 00/null
# vim:nowrap:textwidth=0

View File

@ -7,11 +7,11 @@
# 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)
# EAX = new-segment(0x1000)
# push arg
68/push 0x1000/imm32
# call
e8/call new_segment/disp32
e8/call new-segment/disp32
# discard arg
81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP
@ -23,18 +23,18 @@
b8/copy . . . . . . . 1/imm32/exit # copy to EAX
cd/syscall 0x80/imm8
new_segment: # len : int -> address
new-segment: # len : int -> address
# prolog
55/push-EBP
89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP
53/push-EBX
# copy len to mmap_new_segment.len
# TODO: compute mmap_new_segment+4 before runtime
# copy len to mmap-new-segment.len
# TODO: compute mmap-new-segment+4 before runtime
8b/copy 1/mod/*+disp8 4/rm32/sib 5/base/EBP 4/index/none . 0/r32/EAX 8/disp8 . # copy *(EBP+8) to EAX
bb/copy . . . . . . . mmap_new_segment/imm32 # copy to EBX
bb/copy . . . . . . . mmap-new-segment/imm32 # copy to EBX
89/copy 1/mod/*+disp8 3/rm32/EBX . . . 0/r32/EAX 4/disp8 . # copy EAX to *(EBX+4)
# mmap(mmap_new_segment)
bb/copy . . . . . . . mmap_new_segment/imm32 # copy to EBX
# mmap(mmap-new-segment)
bb/copy . . . . . . . mmap-new-segment/imm32 # copy to EBX
b8/copy . . . . . . . 0x5a/imm32/mmap # copy to EAX
cd/syscall 0x80/imm8
# epilog
@ -45,7 +45,7 @@ new_segment: # len : int -> address
== data
# various constants used here were found in the Linux sources (search for file mman-common.h)
mmap_new_segment: # type mmap_arg_struct
mmap-new-segment: # type mmap_arg_struct
# addr
00 00 00 00 # null
# len

View File

@ -7,13 +7,13 @@
# 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)
e8/call run_tests/disp32 # 'run_tests' is a function created automatically by SubX. It calls all functions that start with 'test_'.
# exit(Num_test_failures)
8b/copy 0/mod/indirect 5/rm32/.disp32 . . 3/r32/EBX Num_test_failures/disp32 # copy *Num_test_failures to EBX
e8/call run-tests/disp32 # 'run-tests' is a function created automatically by SubX. It calls all functions that start with 'test-'.
# exit(Num-test-failures)
8b/copy 0/mod/indirect 5/rm32/.disp32 . . 3/r32/EBX Num-test-failures/disp32 # copy *Num-test-failures to EBX
b8/copy . . . . . . . 1/imm32 # copy to EAX
cd/syscall 0x80/imm8
string_equal: # s : string, benchmark : string -> EAX : boolean
string-equal: # s : string, benchmark : string -> EAX : boolean
# prolog
55/push-EBP
89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP
@ -43,38 +43,38 @@ string_equal: # s : string, benchmark : string -> EAX : boolean
8b/copy 0/mod/indirect 0/rm32/EAX . . . 2/r32/EDX . . # copy *EAX to EDX
# compare s.length and b.length
39/compare 0/mod/indirect 3/rm32/EBX . . . 2/r32/EDX . . # compare *EBX with EDX
75/jump-if-not-equal $string_not_equal/disp8
$string_lengths_equal:
75/jump-if-not-equal $string-equal:false/disp8
$string-equal:lengths:
# var i/ECX : int = 0
b9/copy . . . . . . . 0/imm32 # copy to ECX
# EBX = &b[i]
43/inc-EBX
# EAX = &s[i]
40/inc-EAX
$string_equal_loop:
$string-equal:loop:
# if i >= s.length return true
39/compare 3/mod/direct 1/rm32/ECX . . . 2/r32/EDX . . # compare ECX with EDX
7d/jump-if-greater-or-equal $string_equal/disp8
7d/jump-if-greater-or-equal $string-equal:true/disp8
# if b[i] != s[i] return false
# ESI = s[i]
8b/copy 0/mod/indirect 0/rm32/EAX . . . 6/r32/ESI . . # copy *EAX to ESI
# compare b[i] with ESI
39/compare 0/mod/indirect 3/rm32/EBX . . . 6/r32/ESI . . # compare *EBX with ESI
75/jump-if-not-equal $string_not_equal/disp8
75/jump-if-not-equal $string-equal:false/disp8
# ++i
41/inc-ECX
40/inc-EAX
43/inc-EBX
# loop
eb/jump $string_equal_loop/disp8
$string_equal:
eb/jump $string-equal:loop/disp8
$string-equal:true:
# return true
b8/copy . . . . . . . 1/imm32 # copy to EAX
eb/jump $string_equal_end/disp8
$string_not_equal:
eb/jump $string-equal:end/disp8
$string-equal:false:
# return false
b8/copy . . . . . . . 0/imm32 # copy to EAX
$string_equal_end:
$string-equal:end:
# restore registers
5e/pop-to-ESI
5b/pop-to-EBX
@ -87,82 +87,82 @@ $string_equal_end:
## tests
test_compare_empty_with_empty_string:
# EAX = string_equal("", "")
test-compare-empty-with-empty-string:
# EAX = string-equal("", "")
# push args
68/push ""/imm32
68/push ""/imm32
# call
e8/call string_equal/disp32
e8/call string-equal/disp32
# discard args
81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP
# call check_ints_equal(EAX, 1, msg)
# call check-ints-equal(EAX, 1, msg)
# push args
68/push "F - test_compare_empty_with_empty_string"/imm32
68/push "F - test-compare-empty-with-empty-string"/imm32
68/push 1/imm32/true
50/push-EAX
# call
e8/call check_ints_equal/disp32
e8/call check-ints-equal/disp32
# discard args
81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP
c3/return
test_compare_empty_with_non_empty_string: # also checks length-mismatch code path
# EAX = string_equal("", "Abc")
test-compare-empty-with-non-empty-string: # also checks length-mismatch code path
# EAX = string-equal("", "Abc")
# push args
68/push "Abc"/imm32
68/push ""/imm32
# call
e8/call string_equal/disp32
e8/call string-equal/disp32
# discard args
81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP
# call check_ints_equal(EAX, 0, msg)
# call check-ints-equal(EAX, 0, msg)
# push args
68/push "F - test_compare_empty_with_non_empty_string"/imm32
68/push "F - test-compare-empty-with-non-empty-string"/imm32
68/push 0/imm32/false
50/push-EAX
# call
e8/call check_ints_equal/disp32
e8/call check-ints-equal/disp32
# discard args
81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP
c3/return
test_compare_equal_strings:
# EAX = string_equal("Abc", "Abc")
test-compare-equal-strings:
# EAX = string-equal("Abc", "Abc")
# push args
68/push "Abc"/imm32
68/push "Abc"/imm32
# call
e8/call string_equal/disp32
e8/call string-equal/disp32
# discard args
81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP
# call check_ints_equal(EAX, 1, msg)
# call check-ints-equal(EAX, 1, msg)
# push args
68/push "F - test_compare_equal_strings"/imm32
68/push "F - test-compare-equal-strings"/imm32
68/push 1/imm32/true
50/push-EAX
# call
e8/call check_ints_equal/disp32
e8/call check-ints-equal/disp32
# discard args
81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP
c3/return
test_compare_inequal_strings_equal_lengths:
# EAX = string_equal("Abc", "Adc")
test-compare-inequal-strings-equal-lengths:
# EAX = string-equal("Abc", "Adc")
# push args
68/push "Adc"/imm32
68/push "Abc"/imm32
# call
e8/call string_equal/disp32
e8/call string-equal/disp32
# discard args
81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP
# call check_ints_equal(EAX, 0, msg)
# call check-ints-equal(EAX, 0, msg)
# push args
68/push "F - test_compare_inequal_strings_equal_lengths"/imm32
68/push "F - test-compare-inequal-strings-equal-lengths"/imm32
68/push 0/imm32/false
50/push-EAX
# call
e8/call check_ints_equal/disp32
e8/call check-ints-equal/disp32
# discard args
81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP
c3/return

Binary file not shown.

View File

@ -50,38 +50,38 @@ abort: # s : (address array byte) -> <void>
# print out "Error: #{s} expected\n" to stderr
error: # s : (address array byte) -> <void>
# write_stderr("Error: ")
# write-stderr("Error: ")
# push args
68/push "Error: "/imm32
# call
e8/call write_stderr/disp32
e8/call write-stderr/disp32
# discard arg
81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP
# write_stderr(s)
# write-stderr(s)
# push args
ff 6/subop/push 1/mod/*+disp8 4/rm32/sib 4/base/ESP 4/index/none . . 4/disp8 . # push *(ESP+4)
# call
e8/call write_stderr/disp32
e8/call write-stderr/disp32
# discard arg
81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP
# write_stderr(" expected")
# write-stderr(" expected")
# push args
68/push " expected"/imm32
# call
e8/call write_stderr/disp32
e8/call write-stderr/disp32
# discard arg
81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP
# write_stderr("\n")
# write-stderr("\n")
# push args
68/push Newline/imm32
# call
e8/call write_stderr/disp32
e8/call write-stderr/disp32
# discard arg
81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP
# end
c3/return
write_stdout: # s : (address array byte) -> <void>
write-stdout: # s : (address array byte) -> <void>
# prolog
55/push-EBP
89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP

Binary file not shown.

View File

@ -24,30 +24,30 @@
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
7e/jump-if-lesser-or-equal $run-main/disp8
# and if (argv[1] == "test")
# 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
e8/call kernel_string_equal/disp32
e8/call kernel-string-equal/disp32
# discard args
81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP
# check result
3d/compare-EAX 1/imm32
75/jump-if-not-equal $run_main/disp8
75/jump-if-not-equal $run-main/disp8
# then
e8/call run_tests/disp32
eb/jump $main_exit/disp8
e8/call run-tests/disp32
eb/jump $main-exit/disp8
# else EAX = factorial(5)
$run_main:
$run-main:
# push arg
68/push 5/imm32
# call
e8/call factorial/disp32
# discard arg
81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP
$main_exit:
$main-exit:
# exit(EAX)
89/copy 3/mod/direct 3/rm32/EBX . . . 0/r32/EAX . . # copy EAX to EBX
b8/copy . . . . . . . 1/imm32 # copy to EAX
@ -84,7 +84,7 @@ $factorial:exit:
5d/pop-to-EBP
c3/return
test_factorial:
test-factorial:
# factorial(5)
# push arg
68/push 5/imm32
@ -92,13 +92,13 @@ test_factorial:
e8/call factorial/disp32
# discard arg
81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP
# check_ints_equal(EAX, 120, failure message)
# check-ints-equal(EAX, 120, failure message)
# push args
68/push "F - test_factorial"/imm32
68/push "F - test-factorial"/imm32
68/push 0x78/imm32/expected-120
50/push-EAX
# call
e8/call check_ints_equal/disp32
e8/call check-ints-equal/disp32
# discard args
81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP
# end

View File

@ -12,7 +12,7 @@
# op subop mod rm32 base index scale r32
# 1-3 bytes 3 bits 2 bits 3 bits 3 bits 3 bits 2 bits 2 bits 0/1/2/4 bytes 0/1/2/4 bytes
# main: return argv_equal(argv[1], argv[2])
# main: return argv-equal(argv[1], argv[2])
# At the start of a SubX program:
# argc: *ESP
# argv[0]: *(ESP+4)
@ -20,13 +20,13 @@
# ...
# 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
e8/call argv_equal/disp32
e8/call argv-equal/disp32
# exit(EAX)
$exit:
89/copy 3/mod/direct 3/rm32/EBX . . . 0/r32/EAX . . # copy EAX to EBX
@ -35,12 +35,12 @@ $exit:
# compare two null-terminated ascii strings
# reason for the name: the only place we should have null-terminated ascii strings is from commandline args
argv_equal: # (s1, s2) : null-terminated ascii strings -> EAX : boolean
argv-equal: # (s1, s2) : null-terminated ascii strings -> EAX : boolean
# initialize s1 (ECX) and s2 (EDX)
8b/copy 1/mod/*+disp8 4/rm32/sib 4/base/ESP 4/index/none . 1/r32/ECX 4/disp8 . # copy *(ESP+4) to ECX
8b/copy 1/mod/*+disp8 4/rm32/sib 4/base/ESP 4/index/none . 2/r32/EDX 8/disp8 . # copy *(ESP+8) to EDX
# while (true)
$argv_loop:
$argv-equal:loop:
# c1/EAX, c2/EBX = *s1, *s2
b8/copy 0/imm32 # clear EAX
8a/copy 0/mod/indirect 1/rm32/ECX . . . 0/r32/EAX . . # copy byte at *ECX to lower byte of EAX
@ -48,23 +48,24 @@ $argv_loop:
8a/copy 0/mod/indirect 2/rm32/EDX . . . 3/r32/EBX . . # copy byte at *EDX to lower byte of EBX
# if (c1 == 0) break
3d/compare-EAX 0/imm32
74/jump-if-equal $argv_break/disp8
74/jump-if-equal $argv-equal:break/disp8
# if (c1 != c2) return false
39/compare 3/mod/direct 0/rm32/EAX . . . 3/r32/EBX . . # compare EAX with EBX
75/jump-if-not-equal $argv_fail/disp8
75/jump-if-not-equal $argv-equal:false/disp8
# ++s1, ++s2
41/inc-ECX
42/inc-EDX
# end while
eb/jump $argv_loop/disp8
$argv_break:
eb/jump $argv-equal:loop/disp8
$argv-equal:break:
# if (c2 == 0) return true
81 7/subop/compare 3/mod/direct 3/rm32/EBX . . . . . 0/imm32 # compare EBX
75/jump-if-not-equal $argv_fail/disp8
75/jump-if-not-equal $argv-equal:false/disp8
$argv-equal:success:
b8/copy . . . . . . . 1/imm32 # copy to EAX
c3/return
# return false
$argv_fail:
$argv-equal:false:
b8/copy . . . . . . . 0/imm32 # copy to EAX
c3/return

Binary file not shown.

View File

@ -21,7 +21,7 @@
# 1-3 bytes 3 bits 2 bits 3 bits 3 bits 3 bits 2 bits 2 bits 0/1/2/4 bytes 0/1/2/4 bytes
# main:
e8/call run_tests/disp32 # 'run_tests' is a function created automatically by SubX. It calls all functions that start with 'test_'.
e8/call run-tests/disp32 # 'run-tests' is a function created automatically by SubX. It calls all functions that start with 'test-'.
# exit(EAX)
89/copy 3/mod/direct 3/rm32/EBX . . . 0/r32/EAX . . # copy EAX to EBX
b8/copy . . . . . . . 1/imm32 # copy to EAX
@ -29,7 +29,7 @@
# compare a null-terminated ascii string with a more idiomatic length-prefixed byte array
# reason for the name: the only place we should have null-terminated ascii strings is from commandline args
kernel_string_equal: # s : null-terminated ascii string, benchmark : length-prefixed ascii string -> EAX : boolean
kernel-string-equal: # s : null-terminated ascii string, benchmark : length-prefixed ascii string -> EAX : boolean
# prolog
55/push-EBP
89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP
@ -64,9 +64,9 @@ kernel_string_equal: # s : null-terminated ascii string, benchmark : length-pre
# initialize loop counter i into ECX
b9/copy . . . . . . . 0/imm32/exit # copy to ECX
# while (i/ECX < n/EDX)
$kernel_string_loop:
$kernel-string-equal:loop:
39/compare 3/mod/direct 1/rm32/ECX . . . 2/r32/EDX . . # compare ECX with EDX
74/jump-if-equal $kernel_string_break/disp8
74/jump-if-equal $kernel-string-equal:break/disp8
# c1/EAX, c2/EBX = *s, *benchmark
b8/copy 0/imm32 # clear EAX
8a/copy 0/mod/indirect 7/rm32/EDI . . . 0/r32/EAX . . # copy byte at *EDI to lower byte of EAX
@ -74,29 +74,30 @@ $kernel_string_loop:
8a/copy 0/mod/indirect 6/rm32/ESI . . . 3/r32/EBX . . # copy byte at *ESI to lower byte of EBX
# if (c1 == 0) return false
3d/compare-EAX 0/imm32
74/jump-if-equal $kernel_string_fail/disp8
74/jump-if-equal $kernel-string-equal:false/disp8
# if (c1 != c2) return false
39/compare 3/mod/direct 0/rm32/EAX . . . 3/r32/EBX . . # compare EAX with EBX
75/jump-if-not-equal $kernel_string_fail/disp8
75/jump-if-not-equal $kernel-string-equal:false/disp8
# ++s1, ++s2, ++i
41/inc-ECX
46/inc-ESI
47/inc-EDI
# end while
eb/jump $kernel_string_loop/disp8
$kernel_string_break:
eb/jump $kernel-string-equal:loop/disp8
$kernel-string-equal:break:
# if (*s/EDI == 0) return true
b8/copy 0/imm32 # clear EAX
8a/copy 0/mod/indirect 7/rm32/EDI . . . 0/r32/EAX . . # copy byte at *EDI to lower byte of EAX
81 7/subop/compare 3/mod/direct 0/rm32/EAX . . . . . 0/imm32 # compare EAX
75/jump-if-not-equal $kernel_string_fail/disp8
75/jump-if-not-equal $kernel-string-equal:false/disp8
b8/copy . . . . . . . 1/imm32 # copy to EAX
eb/jump $kernel_string_end/disp8
$kernel-string-equal:true:
eb/jump $kernel-string-equal:end/disp8
# return false
$kernel_string_fail:
$kernel-string-equal:false:
b8/copy . . . . . . . 0/imm32 # copy to EAX
$kernel_string_end:
$kernel-string-equal:end:
# restore registers
5f/pop-to-EDI
5e/pop-to-ESI
@ -110,142 +111,142 @@ $kernel_string_end:
## tests
test_compare_null_kernel_string_with_empty_array:
# EAX = kernel_string_equal(Null_kernel_string, "")
test-compare-null-kernel-string-with-empty-array:
# EAX = kernel-string-equal(Null-kernel-string, "")
# push args
68/push ""/imm32
68/push Null_kernel_string/imm32
68/push Null-kernel-string/imm32
# call
e8/call kernel_string_equal/disp32
e8/call kernel-string-equal/disp32
# discard args
81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP
# call check_ints_equal(EAX, 1, msg)
# call check-ints-equal(EAX, 1, msg)
# push args
68/push "F - test_compare_null_kernel_string_with_empty_array"/imm32
68/push "F - test-compare-null-kernel-string-with-empty-array"/imm32
68/push 1/imm32/true
50/push-EAX
# call
e8/call check_ints_equal/disp32
e8/call check-ints-equal/disp32
# discard args
81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP
c3/return
test_compare_null_kernel_string_with_non_empty_array:
# EAX = kernel_string_equal(Null_kernel_string, "Abc")
test-compare-null-kernel-string-with-non-empty-array:
# EAX = kernel-string-equal(Null-kernel-string, "Abc")
# push args
68/push "Abc"/imm32
68/push Null_kernel_string/imm32
68/push Null-kernel-string/imm32
# call
e8/call kernel_string_equal/disp32
e8/call kernel-string-equal/disp32
# discard args
81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP
# call check_ints_equal(EAX, 0, msg)
# call check-ints-equal(EAX, 0, msg)
# push args
68/push "F - test_compare_null_kernel_string_with_non_empty_array"/imm32
68/push "F - test-compare-null-kernel-string-with-non-empty-array"/imm32
68/push 0/imm32/false
50/push-EAX
# call
e8/call check_ints_equal/disp32
e8/call check-ints-equal/disp32
# discard args
81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP
c3/return
test_compare_kernel_string_with_equal_array:
# EAX = kernel_string_equal(Abc_kernel_string, "Abc")
test-compare-kernel-string-with-equal-array:
# EAX = kernel-string-equal(Abc-kernel-string, "Abc")
# push args
68/push "Abc"/imm32
68/push Abc_kernel_string/imm32
68/push Abc-kernel-string/imm32
# call
e8/call kernel_string_equal/disp32
e8/call kernel-string-equal/disp32
# discard args
81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP
# call check_ints_equal(EAX, 1, msg)
# call check-ints-equal(EAX, 1, msg)
# push args
68/push "F - test_compare_kernel_string_with_equal_array"/imm32
68/push "F - test-compare-kernel-string-with-equal-array"/imm32
68/push 1/imm32/true
50/push-EAX
# call
e8/call check_ints_equal/disp32
e8/call check-ints-equal/disp32
# discard args
81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP
c3/return
test_compare_kernel_string_with_inequal_array:
# EAX = kernel_string_equal(Abc_kernel_string, "Adc")
test-compare-kernel-string-with-inequal-array:
# EAX = kernel-string-equal(Abc-kernel-string, "Adc")
# push args
68/push "Adc"/imm32
68/push Abc_kernel_string/imm32
68/push Abc-kernel-string/imm32
# call
e8/call kernel_string_equal/disp32
e8/call kernel-string-equal/disp32
# discard args
81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP
# call check_ints_equal(EAX, 0, msg)
# call check-ints-equal(EAX, 0, msg)
# push args
68/push "F - test_compare_kernel_string_with_equal_array"/imm32
68/push "F - test-compare-kernel-string-with-equal-array"/imm32
68/push 0/imm32/false
50/push-EAX
# call
e8/call check_ints_equal/disp32
e8/call check-ints-equal/disp32
# discard args
81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP
c3/return
test_compare_kernel_string_with_empty_array:
# EAX = kernel_string_equal(Abc_kernel_string, "")
test-compare-kernel-string-with-empty-array:
# EAX = kernel-string-equal(Abc-kernel-string, "")
# push args
68/push ""/imm32
68/push Abc_kernel_string/imm32
68/push Abc-kernel-string/imm32
# call
e8/call kernel_string_equal/disp32
e8/call kernel-string-equal/disp32
# discard args
81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP
# call check_ints_equal(EAX, 0)
# call check-ints-equal(EAX, 0)
# push args
68/push "F - test_compare_kernel_string_with_equal_array"/imm32
68/push "F - test-compare-kernel-string-with-equal-array"/imm32
68/push 0/imm32/false
50/push-EAX
# call
e8/call check_ints_equal/disp32
e8/call check-ints-equal/disp32
# discard args
81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP
c3/return
test_compare_kernel_string_with_shorter_array:
# EAX = kernel_string_equal(Abc_kernel_string, "Ab")
test-compare-kernel-string-with-shorter-array:
# EAX = kernel-string-equal(Abc-kernel-string, "Ab")
# push args
68/push "Ab"/imm32
68/push Abc_kernel_string/imm32
68/push Abc-kernel-string/imm32
# call
e8/call kernel_string_equal/disp32
e8/call kernel-string-equal/disp32
# discard args
81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP
# call check_ints_equal(EAX, 0)
# call check-ints-equal(EAX, 0)
# push args
68/push "F - test_compare_kernel_string_with_shorter_array"/imm32
68/push "F - test-compare-kernel-string-with-shorter-array"/imm32
68/push 0/imm32/false
50/push-EAX
# call
e8/call check_ints_equal/disp32
e8/call check-ints-equal/disp32
# discard args
81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP
c3/return
test_compare_kernel_string_with_longer_array:
# EAX = kernel_string_equal(Abc_kernel_string, "Abcd")
test-compare-kernel-string-with-longer-array:
# EAX = kernel-string-equal(Abc-kernel-string, "Abcd")
# push args
68/push "Abcd"/imm32
68/push Abc_kernel_string/imm32
68/push Abc-kernel-string/imm32
# call
e8/call kernel_string_equal/disp32
e8/call kernel-string-equal/disp32
# discard args
81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP
# call check_ints_equal(EAX, 0)
# call check-ints-equal(EAX, 0)
# push args
68/push "F - test_compare_kernel_string_with_longer_array"/imm32
68/push "F - test-compare-kernel-string-with-longer-array"/imm32
68/push 0/imm32/false
50/push-EAX
# call
e8/call check_ints_equal/disp32
e8/call check-ints-equal/disp32
# discard args
81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP
c3/return
@ -253,7 +254,7 @@ test_compare_kernel_string_with_longer_array:
## helpers
# print msg to stderr if a != b, otherwise print "."
check_ints_equal: # (a : int, b : int, msg : (address array byte)) -> boolean
check-ints-equal: # (a : int, b : int, msg : (address array byte)) -> boolean
# prolog
55/push-EBP
89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP
@ -265,35 +266,35 @@ check_ints_equal: # (a : int, b : int, msg : (address array byte)) -> boolean
8b/copy 1/mod/*+disp8 4/rm32/sib 5/base/EBP 4/index/none . 3/r32/EBX 0xc/disp8 . # copy *(EBP+12) to EBX
# if EAX == b/EBX
39/compare 3/mod/direct 0/rm32/EAX . . . 3/r32/EBX . . # compare EAX and EBX
75/jump-if-unequal $check_ints_equal:else/disp8
75/jump-if-unequal $check-ints-equal:else/disp8
# print('.')
# push args
68/push "."/imm32
# call
e8/call write_stderr/disp32
e8/call write-stderr/disp32
# discard arg
81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP
# return
eb/jump $check_ints_equal:end/disp8
eb/jump $check-ints-equal:end/disp8
# else:
$check_ints_equal:else:
$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
51/push-ECX
# call
e8/call write_stderr/disp32
e8/call write-stderr/disp32
# discard arg
81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP
# print newline
# push args
68/push Newline/imm32
# call
e8/call write_stderr/disp32
e8/call write-stderr/disp32
# discard arg
81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP
$check_ints_equal:end:
$check-ints-equal:end:
# restore registers
5b/pop-to-EBX
59/pop-to-ECX
@ -302,7 +303,7 @@ $check_ints_equal:end:
5d/pop-to-EBP
c3/return
write_stderr: # s : (address array byte) -> <void>
write-stderr: # s : (address array byte) -> <void>
# prolog
55/push-EBP
89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP
@ -340,10 +341,10 @@ Newline:
# data
0a/newline
# for kernel_string_equal tests
Null_kernel_string:
# for kernel-string-equal tests
Null-kernel-string:
00/null
Abc_kernel_string:
Abc-kernel-string:
41/A 62/b 63/c 00/null
# vim:nowrap:textwidth=0

View File

@ -12,7 +12,7 @@
# 1-3 bytes 3 bits 2 bits 3 bits 3 bits 3 bits 2 bits 2 bits 0/1/2/4 bytes 0/1/2/4 bytes
# mmap(0x1000)
bb/copy . . . . . . . mmap_new_segment/imm32 # copy to EBX
bb/copy . . . . . . . mmap-new-segment/imm32 # copy to EBX
b8/copy . . . . . . . 0x5a/imm32/mmap # copy to EAX
cd/syscall 0x80/imm8
@ -26,7 +26,7 @@
== data
# various constants used here were found in the Linux sources (search for file mman-common.h)
mmap_new_segment: # type mmap_arg_struct
mmap-new-segment: # type mmap_arg_struct
# addr
00 00 00 00 # null
# len

View File

@ -20,11 +20,11 @@
# 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
89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP
# call ascii_length(argv[1])
# 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
e8/call ascii_length/disp32
e8/call ascii-length/disp32
# discard args
81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP
@ -33,24 +33,24 @@
b8/copy . . . . . . . 1/imm32/exit # copy to EAX
cd/syscall 0x80/imm8
ascii_length: # (s)
ascii-length: # (s)
# initialize s (EDX)
8b/copy 1/mod/*+disp8 4/rm32/sib 4/base/ESP 4/index/none 2/r32/EDX 4/disp8 # copy *(ESP+4) to EDX
# var result = 0 (EAX)
b8/copy . . . . . . . 0/imm32 # copy to EAX
$ascii_length_loop:
$ascii-length-loop:
# var c = *s (ECX)
8a/copy 0/mod/* 2/rm32/EDX . . . 1/r32/ECX . . # copy byte at *EDX to lower byte of ECX
# if c == '\0' break
81 7/subop/compare 3/mod/direct 1/rm32/ECX . . . . . 0/imm32 # compare ECX
74/jump-if-equal $ascii_length_ret/disp8
74/jump-if-equal $ascii-length-ret/disp8
# ++s
81 0/subop/add 3/mod/direct 2/rm32/EDX . . . . . 1/imm32 # add to EDX
# ++result
40/inc-EAX
# loop
eb/jump $ascii_length_loop/disp8
$ascii_length_ret:
eb/jump $ascii-length-loop/disp8
$ascii-length-ret:
# return (result in EAX)
c3/return

View File

@ -22,13 +22,13 @@
# 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
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
e8/call ascii_difference/disp32
e8/call ascii-difference/disp32
# discard args
81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP
# exit(EAX)
@ -36,7 +36,7 @@
b8/copy . . . . . . . 1/imm32/exit # copy to EAX
cd/syscall 0x80/imm8
ascii_difference: # (s1, s2) : null-terminated ascii strings
ascii-difference: # (s1, s2) : null-terminated ascii strings
# a = first letter of s1 (ECX)
8b/copy 1/mod/*+disp8 4/rm32/sib 4/base/ESP 4/index/none 0/r32/EAX 4/disp8 . # copy *(ESP+4) to EAX
8b/copy 0/mod/indirect 0/rm32/EAX . . . 0/r32/EAX . . # copy *EAX to EAX

View File

@ -15,6 +15,8 @@ set cpo&vim
setlocal formatoptions-=t " allow long lines
setlocal formatoptions+=c " but comments should still wrap
setlocal iskeyword+=-
syntax match subxComment /#.*$/ | highlight link subxComment Comment
syntax match subxSalientComment /##.*$/ | highlight link subxSalientComment SalientComment
set comments-=:#