This commit is contained in:
Kartik Agaram 2018-10-05 21:30:22 -07:00
parent 03d50cc83c
commit 94ad882e82
24 changed files with 132 additions and 162 deletions

View File

@ -29,10 +29,7 @@ cerr << " instructions\n";
:(scenario pack_immediate_constants) :(scenario pack_immediate_constants)
== 0x1 == 0x1
# instruction effective address operand displacement immediate bb 0x2a/imm32
# 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
bb 0x2a/imm32 # copy 42 to EBX
+transform: packing instruction 'bb 0x2a/imm32' +transform: packing instruction 'bb 0x2a/imm32'
+transform: instruction after packing: 'bb 2a 00 00 00' +transform: instruction after packing: 'bb 2a 00 00 00'
+run: copy imm32 0x0000002a to EBX +run: copy imm32 0x0000002a to EBX
@ -335,40 +332,31 @@ void transform(const string& text_bytes) {
:(scenario pack_imm32_large) :(scenario pack_imm32_large)
== 0x1 == 0x1
b9 0x080490a7/imm32 # copy to ECX b9 0x080490a7/imm32
+transform: packing instruction 'b9 0x080490a7/imm32' +transform: packing instruction 'b9 0x080490a7/imm32'
+transform: instruction after packing: 'b9 a7 90 04 08' +transform: instruction after packing: 'b9 a7 90 04 08'
:(scenario pack_immediate_constants_hex) :(scenario pack_immediate_constants_hex)
== 0x1 == 0x1
# instruction effective address operand displacement immediate b9 0x2a/imm32
# op subop mod rm32 base index scale r32 +transform: packing instruction 'b9 0x2a/imm32'
# 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 +transform: instruction after packing: 'b9 2a 00 00 00'
bb 0x2a/imm32 # copy 42 to EBX +run: copy imm32 0x0000002a to ECX
+transform: packing instruction 'bb 0x2a/imm32'
+transform: instruction after packing: 'bb 2a 00 00 00'
+run: copy imm32 0x0000002a to EBX
:(scenarios transform) :(scenarios transform)
:(scenario pack_silently_ignores_non_hex) :(scenario pack_silently_ignores_non_hex)
% Hide_errors = true; % Hide_errors = true;
== 0x1 == 0x1
# instruction effective address operand displacement immediate b9 foo/imm32
# op subop mod rm32 base index scale r32 +transform: packing instruction 'b9 foo/imm32'
# 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
bb foo/imm32 # copy to EBX
+transform: packing instruction 'bb foo/imm32'
# no change (we're just not printing metadata to the trace) # no change (we're just not printing metadata to the trace)
+transform: instruction after packing: 'bb foo' +transform: instruction after packing: 'b9 foo'
:(scenarios run) :(scenarios run)
:(scenario pack_flags_bad_hex) :(scenario pack_flags_bad_hex)
% Hide_errors = true; % Hide_errors = true;
== 0x1 == 0x1
# instruction effective address operand displacement immediate b9 0xfoo/imm32
# 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
bb 0xfoo/imm32 # copy to EBX
+error: not a number: 0xfoo +error: not a number: 0xfoo
//:: helpers //:: helpers

View File

@ -4,10 +4,7 @@
:(scenario check_missing_imm8_operand) :(scenario check_missing_imm8_operand)
% Hide_errors = true; % Hide_errors = true;
== 0x1 == 0x1
# instruction effective address operand displacement immediate cd # int ??
# 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
cd # int ??
+error: 'cd' (software interrupt): missing imm8 operand +error: 'cd' (software interrupt): missing imm8 operand
:(before "Pack Operands(segment code)") :(before "Pack Operands(segment code)")

View File

@ -4,7 +4,7 @@
:(scenario segment_name) :(scenario segment_name)
== code == code
05/add 0x0d0c0b0a/imm32 # add 0x0d0c0b0a to EAX 05/add-to-EAX 0x0d0c0b0a/imm32
# code starts at 0x08048000 + p_offset, which is 0x54 for a single-segment binary # code starts at 0x08048000 + p_offset, which is 0x54 for a single-segment binary
+load: 0x09000054 -> 05 +load: 0x09000054 -> 05
+load: 0x09000055 -> 0a +load: 0x09000055 -> 0a
@ -65,9 +65,9 @@ if (Currently_parsing_named_segment) {
:(scenario repeated_segment_merges_data) :(scenario repeated_segment_merges_data)
== code == code
05/add 0x0d0c0b0a/imm32 # add 0x0d0c0b0a to EAX 05/add-to-EAX 0x0d0c0b0a/imm32
== code == code
2d/subtract 0xddccbbaa/imm32 # subtract 0xddccbbaa from EAX 2d/subtract-from-EAX 0xddccbbaa/imm32
+parse: new segment 'code' +parse: new segment 'code'
+parse: prepending to segment 'code' +parse: prepending to segment 'code'
+load: 0x09000054 -> 2d +load: 0x09000054 -> 2d

View File

@ -26,7 +26,7 @@ if (SIZE(s) == 2) return true;
:(scenario pack_immediate_ignores_single_byte_nondigit_operand) :(scenario pack_immediate_ignores_single_byte_nondigit_operand)
% Hide_errors = true; % Hide_errors = true;
== 0x1 == 0x1
b9/copy a/imm32 # copy to ECX b9/copy a/imm32
+transform: packing instruction 'b9/copy a/imm32' +transform: packing instruction 'b9/copy a/imm32'
# no change (we're just not printing metadata to the trace) # no change (we're just not printing metadata to the trace)
+transform: instruction after packing: 'b9 a' +transform: instruction after packing: 'b9 a'
@ -34,7 +34,7 @@ b9/copy a/imm32 # copy to ECX
:(scenario pack_immediate_ignores_3_hex_digit_operand) :(scenario pack_immediate_ignores_3_hex_digit_operand)
% Hide_errors = true; % Hide_errors = true;
== 0x1 == 0x1
b9/copy aaa/imm32 # copy to ECX b9/copy aaa/imm32
+transform: packing instruction 'b9/copy aaa/imm32' +transform: packing instruction 'b9/copy aaa/imm32'
# no change (we're just not printing metadata to the trace) # no change (we're just not printing metadata to the trace)
+transform: instruction after packing: 'b9 aaa' +transform: instruction after packing: 'b9 aaa'
@ -42,7 +42,7 @@ b9/copy aaa/imm32 # copy to ECX
:(scenario pack_immediate_ignores_non_hex_operand) :(scenario pack_immediate_ignores_non_hex_operand)
% Hide_errors = true; % Hide_errors = true;
== 0x1 == 0x1
b9/copy xxx/imm32 # copy to ECX b9/copy xxx/imm32
+transform: packing instruction 'b9/copy xxx/imm32' +transform: packing instruction 'b9/copy xxx/imm32'
# no change (we're just not printing metadata to the trace) # no change (we're just not printing metadata to the trace)
+transform: instruction after packing: 'b9 xxx' +transform: instruction after packing: 'b9 xxx'
@ -70,11 +70,8 @@ void check_valid_name(const string& s) {
:(scenario map_label) :(scenario map_label)
== 0x1 == 0x1
# 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
loop: loop:
05 0x0d0c0b0a/imm32 # add to EAX 05 0x0d0c0b0a/imm32
+transform: label 'loop' is at address 1 +transform: label 'loop' is at address 1
:(before "End Level-2 Transforms") :(before "End Level-2 Transforms")
@ -207,18 +204,15 @@ string drop_last(const string& s) {
:(scenario multiple_labels_at) :(scenario multiple_labels_at)
== 0x1 == 0x1
# 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
# address 1 # address 1
loop: loop:
$loop2: $loop2:
# address 1 (labels take up no space) # address 1 (labels take up no space)
05 0x0d0c0b0a/imm32 # add to EAX 05 0x0d0c0b0a/imm32
# address 6 # address 6
eb $loop2/disp8 eb $loop2/disp8
# address 8 # address 8
eb $loop3/disp8 eb $loop3/disp8
# address 0xa # address 0xa
$loop3: $loop3:
+transform: label 'loop' is at address 1 +transform: label 'loop' is at address 1
@ -232,31 +226,22 @@ loop:
:(scenario label_too_short) :(scenario label_too_short)
% Hide_errors = true; % Hide_errors = true;
== 0x1 == 0x1
# 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
xz: xz:
05 0x0d0c0b0a/imm32 # add to EAX 05 0x0d0c0b0a/imm32
+error: 'xz' is two characters long which can look like raw hex bytes at a glance; use a different name +error: 'xz' is two characters long which can look like raw hex bytes at a glance; use a different name
:(scenario label_hex) :(scenario label_hex)
% Hide_errors = true; % Hide_errors = true;
== 0x1 == 0x1
# 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
0xab: 0xab:
05 0x0d0c0b0a/imm32 # add to EAX 05 0x0d0c0b0a/imm32
+error: '0xab' looks like a hex number; use a different name +error: '0xab' looks like a hex number; use a different name
:(scenario label_negative_hex) :(scenario label_negative_hex)
% Hide_errors = true; % Hide_errors = true;
== 0x1 == 0x1
# 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
-a: # indent to avoid looking like a trace_should_not_contain command for this scenario -a: # indent to avoid looking like a trace_should_not_contain command for this scenario
05 0x0d0c0b0a/imm32 # add to EAX 05 0x0d0c0b0a/imm32
+error: '-a' starts with '-', which can be confused with a negative number; use a different name +error: '-a' starts with '-', which can be confused with a negative number; use a different name
//: now that we have labels, we need to adjust segment size computation to //: now that we have labels, we need to adjust segment size computation to
@ -264,11 +249,11 @@ xz:
:(scenario segment_size_ignores_labels) :(scenario segment_size_ignores_labels)
== code # 0x09000074 == code # 0x09000074
05/add 0x0d0c0b0a/imm32 # 5 bytes 05/add 0x0d0c0b0a/imm32 # 5 bytes
foo: # 0 bytes foo: # 0 bytes
== data # 0x0a000079 == data # 0x0a000079
bar: bar:
00 00
+transform: segment 1 begins at address 0x0a000079 +transform: segment 1 begins at address 0x0a000079
:(before "End num_bytes(curr) Special-cases") :(before "End num_bytes(curr) Special-cases")

View File

@ -8,7 +8,7 @@
:(scenario global_variable) :(scenario global_variable)
== code == code
b9/copy x/imm32 # copy to ECX b9 x/imm32
== data == data
x: x:
00 00 00 00 00 00 00 00
@ -129,7 +129,7 @@ bool has_metadata(const word& w, const string& m) {
:(scenario global_variable_disallowed_in_jump) :(scenario global_variable_disallowed_in_jump)
% Hide_errors = true; % Hide_errors = true;
== code == code
eb/jump x/disp8 eb/jump x/disp8
== data == data
x: x:
00 00 00 00 00 00 00 00
@ -140,7 +140,7 @@ x:
:(scenario global_variable_disallowed_in_call) :(scenario global_variable_disallowed_in_call)
% Hide_errors = true; % Hide_errors = true;
== code == code
e8/call x/disp32 e8/call x/disp32
== data == data
x: x:
00 00 00 00 00 00 00 00

View File

@ -5,7 +5,7 @@
:(scenario transform_literal_string) :(scenario transform_literal_string)
== code == code
b8/copy "test"/imm32 # copy to EAX b8/copy "test"/imm32
== data # need to manually create this for now == data # need to manually create this for now
+transform: -- move literal strings to data segment +transform: -- move literal strings to data segment
+transform: adding global variable '__subx_global_1' containing "test" +transform: adding global variable '__subx_global_1' containing "test"

View File

@ -15,7 +15,7 @@ write-stderr: # s : (address array byte) -> <void>
53/push-EBX 53/push-EBX
# write(2/stderr, (data) s+4, (size) *s) # write(2/stderr, (data) s+4, (size) *s)
# fd = 2 (stderr) # fd = 2 (stderr)
bb/copy . . . . . . . 2/imm32 # copy to EBX bb/copy-to-EBX 2/imm32
# x = s+4 # x = s+4
8b/copy 1/mod/*+disp8 4/rm32/sib 5/base/EBP 4/index/none . 1/r32/ECX 8/disp8 . # copy *(EBP+8) to ECX 8b/copy 1/mod/*+disp8 4/rm32/sib 5/base/EBP 4/index/none . 1/r32/ECX 8/disp8 . # copy *(EBP+8) to ECX
81 0/subop/add 3/mod/direct 1/rm32/ECX . . . . . 4/imm32 # add to ECX 81 0/subop/add 3/mod/direct 1/rm32/ECX . . . . . 4/imm32 # add to ECX
@ -23,7 +23,7 @@ write-stderr: # s : (address array byte) -> <void>
8b/copy 1/mod/*+disp8 4/rm32/sib 5/base/EBP 4/index/none . 2/r32/EDX 8/disp8 . # copy *(EBP+8) to EDX 8b/copy 1/mod/*+disp8 4/rm32/sib 5/base/EBP 4/index/none . 2/r32/EDX 8/disp8 . # copy *(EBP+8) to EDX
8b/copy 0/mod/indirect 2/rm32/EDX . . . 2/r32/EDX . . # copy *EDX to EDX 8b/copy 0/mod/indirect 2/rm32/EDX . . . 2/r32/EDX . . # copy *EDX to EDX
# call write() # call write()
b8/copy . . . . . . . 4/imm32/write # copy to EAX b8/copy-to-EAX 4/imm32/write
cd/syscall 0x80/imm8 cd/syscall 0x80/imm8
# restore registers # restore registers
5b/pop-to-EBX 5b/pop-to-EBX

View File

@ -24,7 +24,7 @@
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(Num-test-failures) # 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 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 b8/copy-to-EAX 1/imm32
cd/syscall 0x80/imm8 cd/syscall 0x80/imm8
# compare a null-terminated ascii string with a more idiomatic length-prefixed byte array # compare a null-terminated ascii string with a more idiomatic length-prefixed byte array
@ -63,15 +63,15 @@ kernel-string-equal: # s : null-terminated ascii string, benchmark : length-pre
8b/copy 1/mod/*+disp8 4/rm32/sib 5/base/EBP 4/index/none . 6/r32/ESI 0xc/disp8 . # copy *(EBP+12) to ESI 8b/copy 1/mod/*+disp8 4/rm32/sib 5/base/EBP 4/index/none . 6/r32/ESI 0xc/disp8 . # copy *(EBP+12) to ESI
81 0/subop/add 3/mod/direct 6/rm32/ESI . . . . . 4/imm32 # add to ESI 81 0/subop/add 3/mod/direct 6/rm32/ESI . . . . . 4/imm32 # add to ESI
# initialize loop counter i into ECX # initialize loop counter i into ECX
b9/copy . . . . . . . 0/imm32/exit # copy to ECX b9/copy-to-ECX 0/imm32/exit
# while (i/ECX < n/EDX) # while (i/ECX < n/EDX)
$kernel-string-equal:loop: $kernel-string-equal:loop:
39/compare 3/mod/direct 1/rm32/ECX . . . 2/r32/EDX . . # compare ECX with EDX 39/compare 3/mod/direct 1/rm32/ECX . . . 2/r32/EDX . . # compare ECX with EDX
74/jump-if-equal $kernel-string-equal:break/disp8 74/jump-if-equal $kernel-string-equal:break/disp8
# c1/EAX, c2/EBX = *s, *benchmark # c1/EAX, c2/EBX = *s, *benchmark
b8/copy 0/imm32 # clear EAX b8/copy-to-EAX 0/imm32
8a/copy 0/mod/indirect 7/rm32/EDI . . . 0/r32/EAX . . # copy byte at *EDI to lower byte of EAX 8a/copy 0/mod/indirect 7/rm32/EDI . . . 0/r32/EAX . . # copy byte at *EDI to lower byte of EAX
bb/copy 0/imm32 # clear EBX bb/copy-to-EBX 0/imm32
8a/copy 0/mod/indirect 6/rm32/ESI . . . 3/r32/EBX . . # copy byte at *ESI to lower byte of EBX 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 # if (c1 == 0) return false
3d/compare-EAX 0/imm32 3d/compare-EAX 0/imm32
@ -87,16 +87,16 @@ $kernel-string-equal:loop:
eb/jump $kernel-string-equal:loop/disp8 eb/jump $kernel-string-equal:loop/disp8
$kernel-string-equal:break: $kernel-string-equal:break:
# if (*s/EDI == 0) return true # if (*s/EDI == 0) return true
b8/copy 0/imm32 # clear EAX b8/copy-to-EAX 0/imm32
8a/copy 0/mod/indirect 7/rm32/EDI . . . 0/r32/EAX . . # copy byte at *EDI to lower byte of 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 3d/compare-EAX 0/imm32
75/jump-if-not-equal $kernel-string-equal:false/disp8 75/jump-if-not-equal $kernel-string-equal:false/disp8
$kernel-string-equal:true: $kernel-string-equal:true:
b8/copy . . . . . . . 1/imm32 # copy to EAX b8/copy-to-EAX 1/imm32
eb/jump $kernel-string-equal:end/disp8 eb/jump $kernel-string-equal:end/disp8
# return false # return false
$kernel-string-equal:false: $kernel-string-equal:false:
b8/copy . . . . . . . 0/imm32 # copy to EAX b8/copy-to-EAX 0/imm32
$kernel-string-equal:end: $kernel-string-equal:end:
# restore registers # restore registers

View File

@ -20,7 +20,7 @@
# exit(EAX) # exit(EAX)
89/copy 3/mod/direct 3/rm32/EBX . . . 0/r32/EAX . . # copy EAX to EBX 89/copy 3/mod/direct 3/rm32/EBX . . . 0/r32/EAX . . # copy EAX to EBX
b8/copy . . . . . . . 1/imm32/exit # copy to EAX b8/copy-to-EAX 1/imm32/exit
cd/syscall 0x80/imm8 cd/syscall 0x80/imm8
new-segment: # len : int -> address new-segment: # len : int -> address
@ -31,11 +31,11 @@ new-segment: # len : int -> address
# copy len to mmap-new-segment.len # copy len to mmap-new-segment.len
# TODO: compute mmap-new-segment+4 before runtime # 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 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-to-EBX mmap-new-segment/imm32
89/copy 1/mod/*+disp8 3/rm32/EBX . . . 0/r32/EAX 4/disp8 . # copy EAX to *(EBX+4) 89/copy 1/mod/*+disp8 3/rm32/EBX . . . 0/r32/EAX 4/disp8 . # copy EAX to *(EBX+4)
# mmap(mmap-new-segment) # mmap(mmap-new-segment)
bb/copy . . . . . . . mmap-new-segment/imm32 # copy to EBX bb/copy-to-EBX mmap-new-segment/imm32
b8/copy . . . . . . . 0x5a/imm32/mmap # copy to EAX b8/copy-to-EAX 0x5a/imm32/mmap
cd/syscall 0x80/imm8 cd/syscall 0x80/imm8
# epilog # epilog
5b/pop-to-EBX 5b/pop-to-EBX

View File

@ -10,7 +10,7 @@
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(Num-test-failures) # 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 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 b8/copy-to-EAX 1/imm32
cd/syscall 0x80/imm8 cd/syscall 0x80/imm8
string-equal: # s : string, benchmark : string -> EAX : boolean string-equal: # s : string, benchmark : string -> EAX : boolean
@ -46,7 +46,7 @@ string-equal: # s : string, benchmark : string -> EAX : boolean
75/jump-if-not-equal $string-equal:false/disp8 75/jump-if-not-equal $string-equal:false/disp8
$string-equal:lengths: $string-equal:lengths:
# var i/ECX : int = 0 # var i/ECX : int = 0
b9/copy . . . . . . . 0/imm32 # copy to ECX b9/copy-to-ECX 0/imm32
# EBX = &b[i] # EBX = &b[i]
43/inc-EBX 43/inc-EBX
# EAX = &s[i] # EAX = &s[i]
@ -69,11 +69,11 @@ $string-equal:loop:
eb/jump $string-equal:loop/disp8 eb/jump $string-equal:loop/disp8
$string-equal:true: $string-equal:true:
# return true # return true
b8/copy . . . . . . . 1/imm32 # copy to EAX b8/copy-to-EAX 1/imm32
eb/jump $string-equal:end/disp8 eb/jump $string-equal:end/disp8
$string-equal:false: $string-equal:false:
# return false # return false
b8/copy . . . . . . . 0/imm32 # copy to EAX b8/copy-to-EAX 0/imm32
$string-equal:end: $string-equal:end:
# restore registers # restore registers
5e/pop-to-ESI 5e/pop-to-ESI

View File

@ -27,8 +27,8 @@
# discard arg # discard arg
81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP
# exit(0) # exit(0)
bb/copy . . . . . . . 0/imm32 # copy to EBX bb/copy-to-EBX 0/imm32
b8/copy . . . . . . . 1/imm32/exit # copy to EAX b8/copy-to-EAX 1/imm32/exit
cd/syscall 0x80/imm8 cd/syscall 0x80/imm8
## helpers ## helpers
@ -44,8 +44,8 @@ abort: # s : (address array byte) -> <void>
# discard arg # discard arg
81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP
# exit(1) # exit(1)
bb/copy . . . . . . . 1/imm32 # copy to EBX bb/copy-to-EBX 1/imm32
b8/copy . . . . . . . 1/imm32/exit # copy to EAX b8/copy-to-EAX 1/imm32/exit
cd/syscall 0x80/imm8 cd/syscall 0x80/imm8
# print out "Error: #{s} expected\n" to stderr # print out "Error: #{s} expected\n" to stderr
@ -92,7 +92,7 @@ write-stdout: # s : (address array byte) -> <void>
53/push-EBX 53/push-EBX
# write(1/stdout, (data) s+4, (size) *s) # write(1/stdout, (data) s+4, (size) *s)
# fd = 1 (stdout) # fd = 1 (stdout)
bb/copy . . . . . . . 1/imm32 # copy to EBX bb/copy-to-EBX 1/imm32
# x = s+4 # x = s+4
8b/copy 1/mod/*+disp8 4/rm32/sib 5/base/EBP 4/index/none . 1/r32/ECX 8/disp8 . # copy *(EBP+8) to ECX 8b/copy 1/mod/*+disp8 4/rm32/sib 5/base/EBP 4/index/none . 1/r32/ECX 8/disp8 . # copy *(EBP+8) to ECX
81 0/subop/add 3/mod/direct 1/rm32/ECX . . . . . 4/imm32 # add to ECX 81 0/subop/add 3/mod/direct 1/rm32/ECX . . . . . 4/imm32 # add to ECX
@ -100,7 +100,7 @@ write-stdout: # s : (address array byte) -> <void>
8b/copy 1/mod/*+disp8 4/rm32/sib 5/base/EBP 4/index/none . 2/r32/EDX 8/disp8 . # copy *(EBP+8) to EDX 8b/copy 1/mod/*+disp8 4/rm32/sib 5/base/EBP 4/index/none . 2/r32/EDX 8/disp8 . # copy *(EBP+8) to EDX
8b/copy 0/mod/indirect 2/rm32/EDX . . . 2/r32/EDX . . # copy *EDX to EDX 8b/copy 0/mod/indirect 2/rm32/EDX . . . 2/r32/EDX . . # copy *EDX to EDX
# call write() # call write()
b8/copy . . . . . . . 4/imm32/write # copy to EAX b8/copy-to-EAX 4/imm32/write
cd/syscall 0x80/imm8 cd/syscall 0x80/imm8
# restore registers # restore registers
5b/pop-to-EBX 5b/pop-to-EBX

View File

@ -50,7 +50,7 @@ $run-main:
$main-exit: $main-exit:
# exit(EAX) # exit(EAX)
89/copy 3/mod/direct 3/rm32/EBX . . . 0/r32/EAX . . # copy EAX to EBX 89/copy 3/mod/direct 3/rm32/EBX . . . 0/r32/EAX . . # copy EAX to EBX
b8/copy . . . . . . . 1/imm32 # copy to EAX b8/copy-to-EAX 1/imm32
cd/syscall 0x80/imm8 cd/syscall 0x80/imm8
# factorial(n) # factorial(n)
@ -60,7 +60,7 @@ factorial:
89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP 89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP
53/push-EBX 53/push-EBX
# initialize EAX to 1 (base case) # initialize EAX to 1 (base case)
b8/copy . . . . . . . 1/imm32 # copy to EAX b8/copy-to-EAX 1/imm32
# if (n <= 1) jump exit # if (n <= 1) jump exit
81 7/subop/compare 1/mod/*+disp8 4/rm32/sib 5/base/EBP 4/index/none . . 8/disp8 1/imm32 # compare *(EBP+8) 81 7/subop/compare 1/mod/*+disp8 4/rm32/sib 5/base/EBP 4/index/none . . 8/disp8 1/imm32 # compare *(EBP+8)
7e/jump-if-<= $factorial:exit/disp8 7e/jump-if-<= $factorial:exit/disp8

View File

@ -12,9 +12,9 @@
# instruction effective address operand displacement immediate # instruction effective address operand displacement immediate
# op subop mod rm32 base index scale r32 # 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 # 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
bb/copy . . . . . . . 2a/imm32 # copy 42 to EBX bb/copy-to-EBX 2a/imm32
# exit(EBX) # exit(EBX)
b8/copy . . . . . . . 1/imm32 # copy to EAX b8/copy-to-EAX 1/imm32
cd/syscall 0x80/imm8 cd/syscall 0x80/imm8
# vim:nowrap:textwidth=0 # vim:nowrap:textwidth=0

View File

@ -30,7 +30,7 @@
# exit(EAX) # exit(EAX)
$exit: $exit:
89/copy 3/mod/direct 3/rm32/EBX . . . 0/r32/EAX . . # copy EAX to EBX 89/copy 3/mod/direct 3/rm32/EBX . . . 0/r32/EAX . . # copy EAX to EBX
b8/copy . . . . . . . 1/imm32 # copy to EAX b8/copy-to-EAX 1/imm32
cd/syscall 0x80/imm8 cd/syscall 0x80/imm8
# compare two null-terminated ascii strings # compare two null-terminated ascii strings
@ -42,9 +42,9 @@ argv-equal: # (s1, s2) : null-terminated ascii strings -> EAX : boolean
# while (true) # while (true)
$argv-equal:loop: $argv-equal:loop:
# c1/EAX, c2/EBX = *s1, *s2 # c1/EAX, c2/EBX = *s1, *s2
b8/copy 0/imm32 # clear EAX b8/copy-to-EAX 0/imm32
8a/copy 0/mod/indirect 1/rm32/ECX . . . 0/r32/EAX . . # copy byte at *ECX to lower byte of EAX 8a/copy 0/mod/indirect 1/rm32/ECX . . . 0/r32/EAX . . # copy byte at *ECX to lower byte of EAX
bb/copy 0/imm32 # clear EBX bb/copy-to-EBX 0/imm32
8a/copy 0/mod/indirect 2/rm32/EDX . . . 3/r32/EBX . . # copy byte at *EDX to lower byte of EBX 8a/copy 0/mod/indirect 2/rm32/EDX . . . 3/r32/EBX . . # copy byte at *EDX to lower byte of EBX
# if (c1 == 0) break # if (c1 == 0) break
3d/compare-EAX 0/imm32 3d/compare-EAX 0/imm32
@ -62,11 +62,11 @@ $argv-equal:break:
81 7/subop/compare 3/mod/direct 3/rm32/EBX . . . . . 0/imm32 # compare EBX 81 7/subop/compare 3/mod/direct 3/rm32/EBX . . . . . 0/imm32 # compare EBX
75/jump-if-not-equal $argv-equal:false/disp8 75/jump-if-not-equal $argv-equal:false/disp8
$argv-equal:success: $argv-equal:success:
b8/copy . . . . . . . 1/imm32 # copy to EAX b8/copy-to-EAX 1/imm32
c3/return c3/return
# return false # return false
$argv-equal:false: $argv-equal:false:
b8/copy . . . . . . . 0/imm32 # copy to EAX b8/copy-to-EAX 0/imm32
c3/return c3/return
# vim:nowrap:textwidth=0 # vim:nowrap:textwidth=0

View File

@ -24,7 +24,7 @@
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) # exit(EAX)
89/copy 3/mod/direct 3/rm32/EBX . . . 0/r32/EAX . . # copy EAX to EBX 89/copy 3/mod/direct 3/rm32/EBX . . . 0/r32/EAX . . # copy EAX to EBX
b8/copy . . . . . . . 1/imm32 # copy to EAX b8/copy-to-EAX 1/imm32
cd/syscall 0x80/imm8 cd/syscall 0x80/imm8
# compare a null-terminated ascii string with a more idiomatic length-prefixed byte array # compare a null-terminated ascii string with a more idiomatic length-prefixed byte array
@ -62,15 +62,15 @@ kernel-string-equal: # s : null-terminated ascii string, benchmark : length-pre
8b/copy 1/mod/*+disp8 4/rm32/sib 5/base/EBP 4/index/none . 6/r32/ESI 0xc/disp8 . # copy *(EBP+12) to ESI 8b/copy 1/mod/*+disp8 4/rm32/sib 5/base/EBP 4/index/none . 6/r32/ESI 0xc/disp8 . # copy *(EBP+12) to ESI
81 0/subop/add 3/mod/direct 6/rm32/ESI . . . . . 4/imm32 # add to ESI 81 0/subop/add 3/mod/direct 6/rm32/ESI . . . . . 4/imm32 # add to ESI
# initialize loop counter i into ECX # initialize loop counter i into ECX
b9/copy . . . . . . . 0/imm32/exit # copy to ECX b9/copy-to-ECX 0/imm32/exit
# while (i/ECX < n/EDX) # while (i/ECX < n/EDX)
$kernel-string-equal:loop: $kernel-string-equal:loop:
39/compare 3/mod/direct 1/rm32/ECX . . . 2/r32/EDX . . # compare ECX with EDX 39/compare 3/mod/direct 1/rm32/ECX . . . 2/r32/EDX . . # compare ECX with EDX
74/jump-if-equal $kernel-string-equal:break/disp8 74/jump-if-equal $kernel-string-equal:break/disp8
# c1/EAX, c2/EBX = *s, *benchmark # c1/EAX, c2/EBX = *s, *benchmark
b8/copy 0/imm32 # clear EAX b8/copy-to-EAX 0/imm32
8a/copy 0/mod/indirect 7/rm32/EDI . . . 0/r32/EAX . . # copy byte at *EDI to lower byte of EAX 8a/copy 0/mod/indirect 7/rm32/EDI . . . 0/r32/EAX . . # copy byte at *EDI to lower byte of EAX
bb/copy 0/imm32 # clear EBX bb/copy-to-EBX 0/imm32
8a/copy 0/mod/indirect 6/rm32/ESI . . . 3/r32/EBX . . # copy byte at *ESI to lower byte of EBX 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 # if (c1 == 0) return false
3d/compare-EAX 0/imm32 3d/compare-EAX 0/imm32
@ -86,16 +86,16 @@ $kernel-string-equal:loop:
eb/jump $kernel-string-equal:loop/disp8 eb/jump $kernel-string-equal:loop/disp8
$kernel-string-equal:break: $kernel-string-equal:break:
# if (*s/EDI == 0) return true # if (*s/EDI == 0) return true
b8/copy 0/imm32 # clear EAX b8/copy-to-EAX 0/imm32
8a/copy 0/mod/indirect 7/rm32/EDI . . . 0/r32/EAX . . # copy byte at *EDI to lower byte of 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 81 7/subop/compare 3/mod/direct 0/rm32/EAX . . . . . 0/imm32 # compare EAX
75/jump-if-not-equal $kernel-string-equal:false/disp8 75/jump-if-not-equal $kernel-string-equal:false/disp8
b8/copy . . . . . . . 1/imm32 # copy to EAX b8/copy-to-EAX 1/imm32
$kernel-string-equal:true: $kernel-string-equal:true:
eb/jump $kernel-string-equal:end/disp8 eb/jump $kernel-string-equal:end/disp8
# return false # return false
$kernel-string-equal:false: $kernel-string-equal:false:
b8/copy . . . . . . . 0/imm32 # copy to EAX b8/copy-to-EAX 0/imm32
$kernel-string-equal:end: $kernel-string-equal:end:
# restore registers # restore registers
@ -314,7 +314,7 @@ write-stderr: # s : (address array byte) -> <void>
53/push-EBX 53/push-EBX
# write(2/stderr, (data) s+4, (size) *s) # write(2/stderr, (data) s+4, (size) *s)
# fd = 2 (stderr) # fd = 2 (stderr)
bb/copy . . . . . . . 2/imm32 # copy to EBX bb/copy-to-EBX 2/imm32
# x = s+4 # x = s+4
8b/copy 1/mod/*+disp8 4/rm32/sib 5/base/EBP 4/index/none . 1/r32/ECX 8/disp8 . # copy *(EBP+8) to ECX 8b/copy 1/mod/*+disp8 4/rm32/sib 5/base/EBP 4/index/none . 1/r32/ECX 8/disp8 . # copy *(EBP+8) to ECX
81 0/subop/add 3/mod/direct 1/rm32/ECX . . . . . 4/imm32 # add to ECX 81 0/subop/add 3/mod/direct 1/rm32/ECX . . . . . 4/imm32 # add to ECX
@ -322,7 +322,7 @@ write-stderr: # s : (address array byte) -> <void>
8b/copy 1/mod/*+disp8 4/rm32/sib 5/base/EBP 4/index/none . 2/r32/EDX 8/disp8 . # copy *(EBP+8) to EDX 8b/copy 1/mod/*+disp8 4/rm32/sib 5/base/EBP 4/index/none . 2/r32/EDX 8/disp8 . # copy *(EBP+8) to EDX
8b/copy 0/mod/indirect 2/rm32/EDX . . . 2/r32/EDX . . # copy *EDX to EDX 8b/copy 0/mod/indirect 2/rm32/EDX . . . 2/r32/EDX . . # copy *EDX to EDX
# call write() # call write()
b8/copy . . . . . . . 4/imm32/write # copy to EAX b8/copy-to-EAX 4/imm32/write
cd/syscall 0x80/imm8 cd/syscall 0x80/imm8
# restore registers # restore registers
5b/pop-to-EBX 5b/pop-to-EBX

View File

@ -12,8 +12,8 @@
# 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 # 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) # mmap(0x1000)
bb/copy . . . . . . . mmap-new-segment/imm32 # copy to EBX bb/copy-to-EBX mmap-new-segment/imm32
b8/copy . . . . . . . 0x5a/imm32/mmap # copy to EAX b8/copy-to-EAX 0x5a/imm32/mmap
cd/syscall 0x80/imm8 cd/syscall 0x80/imm8
# store to *EAX # store to *EAX
@ -21,7 +21,7 @@
# exit(EAX) # exit(EAX)
89/copy 3/mod/direct 3/rm32/EBX . . . 0/r32/EAX . . # copy EAX to EBX 89/copy 3/mod/direct 3/rm32/EBX . . . 0/r32/EAX . . # copy EAX to EBX
b8/copy . . . . . . . 1/imm32/exit # copy to EAX b8/copy-to-EAX 1/imm32/exit
cd/syscall 0x80/imm8 cd/syscall 0x80/imm8
== data == data

View File

@ -11,10 +11,10 @@
# instruction effective address operand displacement immediate # instruction effective address operand displacement immediate
# op subop mod rm32 base index scale r32 # 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 # 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
bb/copy . . . . . . . 1/imm32 # copy to EBX bb/copy-to-EBX 1/imm32
43/inc-EBX 43/inc-EBX
# exit(EBX) # exit(EBX)
b8/copy . . . . . . . 1/imm32 # copy to EAX b8/copy-to-EAX 1/imm32
cd/syscall 0x80/imm8 cd/syscall 0x80/imm8
# vim:nowrap:textwidth=0 # vim:nowrap:textwidth=0

View File

@ -12,9 +12,9 @@
# op subop mod rm32 base index scale r32 # 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 # 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 # result: EBX = 0
bb/copy . . . . . . . 0/imm32 # copy to EBX bb/copy-to-EBX 0/imm32
# counter: ECX = 1 # counter: ECX = 1
b9/copy . . . . . . . 1/imm32 # copy to ECX b9/copy-to-ECX 1/imm32
$loop: $loop:
# while (counter <= 10) # while (counter <= 10)
@ -29,7 +29,7 @@ $loop:
$exit: $exit:
# exit(EBX) # exit(EBX)
b8/copy . . . . . . . 1/imm32 # copy to EAX b8/copy-to-EAX 1/imm32
cd/syscall 0x80/imm8 cd/syscall 0x80/imm8
# vim:nowrap:textwidth=0 # vim:nowrap:textwidth=0

View File

@ -11,28 +11,28 @@
# read(stdin, x, 1) # read(stdin, x, 1)
# fd = 0 (stdin) # fd = 0 (stdin)
bb/copy . . . . . . . 0/imm32 # copy to EBX bb/copy-to-EBX 0/imm32
# initialize x (location to write result to) # initialize x (location to write result to)
b9/copy . . . . . . . x/imm32 # copy to ECX b9/copy-to-ECX x/imm32
# size = 1 character # size = 1 character
ba/copy . . . . . . . 1/imm32 # copy to EDX ba/copy-to-EDX 1/imm32
# read(fd, x, size) # read(fd, x, size)
b8/copy . . . . . . . 3/imm32/read # copy to EAX b8/copy-to-EAX 3/imm32/read
cd/syscall 0x80/imm8 cd/syscall 0x80/imm8
# write(stdout, x, 1) # write(stdout, x, 1)
# fd = 1 (stdout) # fd = 1 (stdout)
bb/copy . . . . . . . 1/imm32 # copy to EBX bb/copy-to-EBX 1/imm32
# initialize x (location to read from) # initialize x (location to read from)
b9/copy . . . . . . . x/imm32 # copy to ECX b9/copy-to-ECX x/imm32
# size = 1 character # size = 1 character
ba/copy . . . . . . . 1/imm32 # copy to EDX ba/copy-to-EDX 1/imm32
# write(fd, x, size) # write(fd, x, size)
b8/copy . . . . . . . 4/imm32/write # copy to EAX b8/copy-to-EAX 4/imm32/write
cd/syscall 0x80/imm8 cd/syscall 0x80/imm8
# exit(EBX) # exit(EBX)
b8/copy . . . . . . . 1/imm32/exit # copy to EAX b8/copy-to-EAX 1/imm32/exit
cd/syscall 0x80/imm8 cd/syscall 0x80/imm8
== data == data

View File

@ -15,28 +15,28 @@
# read(stdin, x, 1) # read(stdin, x, 1)
# fd = 0 (stdin) # fd = 0 (stdin)
bb/copy . . . . . . . 0/imm32 # copy to EBX bb/copy-to-EBX 0/imm32
# initialize x (location to write result to) # initialize x (location to write result to)
8d/copy-address 1/mod/*+disp8 4/rm32/sib 4/base/ESP 4/index/none 1/r32/ECX 4/disp8 . # copy ESP+4 to ECX 8d/copy-address 1/mod/*+disp8 4/rm32/sib 4/base/ESP 4/index/none 1/r32/ECX 4/disp8 . # copy ESP+4 to ECX
# size = 1 character # size = 1 character
ba/copy . . . . . . . 1/imm32 # copy to EDX ba/copy-to-EDX 1/imm32
# read(fd, x, size) # read(fd, x, size)
b8/copy . . . . . . . 3/imm32/read # copy to EAX b8/copy-to-EAX 3/imm32/read
cd/syscall 0x80/imm8 cd/syscall 0x80/imm8
# write(stdout, x, 1) # write(stdout, x, 1)
# fd = 1 (stdout) # fd = 1 (stdout)
bb/copy . . . . . . . 1/imm32 # copy to EBX bb/copy-to-EBX 1/imm32
# initialize x (location to read from) # initialize x (location to read from)
8d/copy-address 1/mod/*+disp8 4/rm32/sib 4/base/ESP 4/index/none 1/r32/ECX 4/disp8 . # copy ESP+4 to ECX 8d/copy-address 1/mod/*+disp8 4/rm32/sib 4/base/ESP 4/index/none 1/r32/ECX 4/disp8 . # copy ESP+4 to ECX
# size = 1 character # size = 1 character
ba/copy . . . . . . . 1/imm32 # copy to EDX ba/copy-to-EDX 1/imm32
# write(fd, x, size) # write(fd, x, size)
b8/copy . . . . . . . 4/imm32/write # copy to EAX b8/copy-to-EAX 4/imm32/write
cd/syscall 0x80/imm8 cd/syscall 0x80/imm8
# exit(EBX) # exit(EBX)
b8/copy . . . . . . . 1/imm32/exit # copy to EAX b8/copy-to-EAX 1/imm32/exit
cd/syscall 0x80/imm8 cd/syscall 0x80/imm8
# vim:nowrap:textwidth=0 # vim:nowrap:textwidth=0

View File

@ -12,17 +12,17 @@
# write(stdout, x, size) # write(stdout, x, size)
# fd = 1 (stdout) # fd = 1 (stdout)
bb/copy . . . . . . . 1/imm32 # copy to EBX bb/copy-to-EBX 1/imm32
# initialize x (location to write result to) # initialize x (location to write result to)
b9/copy . . . . . . . x/imm32 # copy to ECX b9/copy-to-ECX x/imm32
# initialize size # initialize size
8b/copy 0/mod/indirect 5/rm32/.disp32 . . 2/r32/EDX size/disp32 . # copy *size to EDX 8b/copy 0/mod/indirect 5/rm32/.disp32 . . 2/r32/EDX size/disp32 . # copy *size to EDX
# write(fd, x, size) # write(fd, x, size)
b8/copy . . . . . . . 4/imm32/write # copy to EAX b8/copy-to-EAX 4/imm32/write
cd/syscall 0x80/imm8 cd/syscall 0x80/imm8
# exit(EBX) # exit(EBX)
b8/copy . . . . . . . 1/imm32/exit # copy to EAX b8/copy-to-EAX 1/imm32/exit
cd/syscall 0x80/imm8 cd/syscall 0x80/imm8
== data == data

View File

@ -16,78 +16,78 @@
# 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 # 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
# creat(filename) # creat(filename)
bb/copy . . . . . . . filename/imm32 # copy to EBX bb/copy-to-EBX filename/imm32
b9/copy . . . . . . . 0x180/imm32/fixed-perms # copy to ECX b9/copy-to-ECX 0x180/imm32/fixed-perms
b8/copy . . . . . . . 8/imm32/creat # copy to EAX b8/copy-to-EAX 8/imm32/creat
cd/syscall 0x80/imm8 cd/syscall 0x80/imm8
# stream = open(filename, O_WRONLY, 0) # we can't use 'fd' because it looks like a hex byte # stream = open(filename, O_WRONLY, 0) # we can't use 'fd' because it looks like a hex byte
bb/copy . . . . . . . filename/imm32 # copy to EBX bb/copy-to-EBX filename/imm32
b9/copy . . . . . . . 1/imm32/wronly # copy to ECX b9/copy-to-ECX 1/imm32/wronly
ba/copy . . . . . . . 0x180/imm32/fixed-perms # copy to EDX ba/copy-to-EDX 0x180/imm32/fixed-perms
b8/copy . . . . . . . 5/imm32/open # copy to EAX b8/copy-to-EAX 5/imm32/open
cd/syscall 0x80/imm8 cd/syscall 0x80/imm8
# save stream # save stream
bb/copy . . . . . . . stream/imm32 # copy to EBX bb/copy-to-EBX stream/imm32
89/copy 0/mod/indirect 3/rm32/EBX 0/r32/EAX # copy EAX to *EBX 89/copy 0/mod/indirect 3/rm32/EBX 0/r32/EAX # copy EAX to *EBX
# write(stream, "a", 1) # write(stream, "a", 1)
# load stream # load stream
bb/copy . . . . . . . stream/imm32 # copy to EBX bb/copy-to-EBX stream/imm32
8b/copy 0/mod/indirect 3/rm32/EBX 3/r32/EBX # copy *EBX to EBX 8b/copy 0/mod/indirect 3/rm32/EBX 3/r32/EBX # copy *EBX to EBX
# #
b9/copy . . . . . . . a/imm32 # copy to ECX b9/copy-to-ECX a/imm32
ba/copy . . . . . . . 1/imm32/size # copy to EDX ba/copy-to-EDX 1/imm32/size
b8/copy . . . . . . . 4/imm32/write # copy to EAX b8/copy-to-EAX 4/imm32/write
cd/syscall 0x80/imm8 cd/syscall 0x80/imm8
# close(stream) # close(stream)
# load stream # load stream
bb/copy . . . . . . . stream/imm32 # copy to EBX bb/copy-to-EBX stream/imm32
8b/copy 0/mod/indirect 3/rm32/EBX 3/r32/EBX # copy *EBX to EBX 8b/copy 0/mod/indirect 3/rm32/EBX 3/r32/EBX # copy *EBX to EBX
# #
b8/copy . . . . . . . 6/imm32/close # copy to EAX b8/copy-to-EAX 6/imm32/close
cd/syscall 0x80/imm8 cd/syscall 0x80/imm8
# stream = open(filename, O_RDONLY, 0) # stream = open(filename, O_RDONLY, 0)
bb/copy . . . . . . . filename/imm32 # copy to EBX bb/copy-to-EBX filename/imm32
b9/copy . . . . . . . 0/imm32/rdonly # copy to ECX b9/copy-to-ECX 0/imm32/rdonly
ba/copy . . . . . . . 0x180/imm32/fixed-perms # copy to EDX ba/copy-to-EDX 0x180/imm32/fixed-perms
b8/copy . . . . . . . 5/imm32/open # copy to EAX b8/copy-to-EAX 5/imm32/open
cd/syscall 0x80/imm8 cd/syscall 0x80/imm8
# save stream # save stream
bb/copy . . . . . . . stream/imm32 # copy to EBX bb/copy-to-EBX stream/imm32
89/copy 0/mod/indirect 3/rm32/EBX 0/r32/EAX # copy EAX to *EBX 89/copy 0/mod/indirect 3/rm32/EBX 0/r32/EAX # copy EAX to *EBX
# read(stream, b, 1) # read(stream, b, 1)
# load stream # load stream
bb/copy . . . . . . . stream/imm32 # copy to EBX bb/copy-to-EBX stream/imm32
8b/copy 0/mod/indirect 3/rm32/EBX 3/r32/EBX # copy *EBX to EBX 8b/copy 0/mod/indirect 3/rm32/EBX 3/r32/EBX # copy *EBX to EBX
# #
b9/copy . . . . . . . b/imm32 # copy to ECX b9/copy-to-ECX b/imm32
ba/copy . . . . . . . 1/imm32/size # copy to EDX ba/copy-to-EDX 1/imm32/size
b8/copy . . . . . . . 3/imm32/read # copy to EAX b8/copy-to-EAX 3/imm32/read
cd/syscall 0x80/imm8 cd/syscall 0x80/imm8
# close(stream) # close(stream)
# load stream # load stream
bb/copy . . . . . . . stream/imm32 # copy to EBX bb/copy-to-EBX stream/imm32
8b/copy 0/mod/indirect 3/rm32/EBX 3/r32/EBX # copy *EBX to EBX 8b/copy 0/mod/indirect 3/rm32/EBX 3/r32/EBX # copy *EBX to EBX
# #
b8/copy . . . . . . . 6/imm32/close # copy to EAX b8/copy-to-EAX 6/imm32/close
cd/syscall 0x80/imm8 cd/syscall 0x80/imm8
# unlink(filename) # unlink(filename)
bb/copy . . . . . . . filename/imm32 # copy to EBX bb/copy-to-EBX filename/imm32
b8/copy . . . . . . . 0xa/imm32/unlink # copy to EAX b8/copy-to-EAX 0xa/imm32/unlink
cd/syscall 0x80/imm8 cd/syscall 0x80/imm8
# exit(b) # exit(b)
# load b # load b
bb/copy . . . . . . . b/imm32 # copy to EBX bb/copy-to-EBX b/imm32
8b/copy 0/mod/indirect 3/rm32/EBX 3/r32/EBX # copy *EBX to EBX 8b/copy 0/mod/indirect 3/rm32/EBX 3/r32/EBX # copy *EBX to EBX
# #
b8/copy . . . . . . . 1/imm32/exit # copy to EAX b8/copy-to-EAX 1/imm32/exit
cd/syscall 0x80/imm8 cd/syscall 0x80/imm8
== data == data

View File

@ -30,14 +30,14 @@
# exit(EAX) # exit(EAX)
89/copy 3/mod/direct 3/rm32/EBX . . . 0/r32/EAX . . # copy EAX to EBX 89/copy 3/mod/direct 3/rm32/EBX . . . 0/r32/EAX . . # copy EAX to EBX
b8/copy . . . . . . . 1/imm32/exit # copy to EAX b8/copy-to-EAX 1/imm32/exit
cd/syscall 0x80/imm8 cd/syscall 0x80/imm8
ascii-length: # (s) ascii-length: # (s)
# initialize s (EDX) # 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 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) # var result = 0 (EAX)
b8/copy . . . . . . . 0/imm32 # copy to EAX b8/copy-to-EAX 0/imm32
$ascii-length-loop: $ascii-length-loop:
# var c = *s (ECX) # var c = *s (ECX)
8a/copy 0/mod/* 2/rm32/EDX . . . 1/r32/ECX . . # copy byte at *EDX to lower byte of ECX 8a/copy 0/mod/* 2/rm32/EDX . . . 1/r32/ECX . . # copy byte at *EDX to lower byte of ECX

View File

@ -33,7 +33,7 @@
81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP
# exit(EAX) # exit(EAX)
89/copy 3/mod/direct 3/rm32/EBX . . . 0/r32/EAX . . # copy EAX to EBX 89/copy 3/mod/direct 3/rm32/EBX . . . 0/r32/EAX . . # copy EAX to EBX
b8/copy . . . . . . . 1/imm32/exit # copy to EAX b8/copy-to-EAX 1/imm32/exit
cd/syscall 0x80/imm8 cd/syscall 0x80/imm8
ascii-difference: # (s1, s2) : null-terminated ascii strings ascii-difference: # (s1, s2) : null-terminated ascii strings