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)
== 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
bb 0x2a/imm32 # copy 42 to EBX
bb 0x2a/imm32
+transform: packing instruction 'bb 0x2a/imm32'
+transform: instruction after packing: 'bb 2a 00 00 00'
+run: copy imm32 0x0000002a to EBX
@ -335,40 +332,31 @@ void transform(const string& text_bytes) {
:(scenario pack_imm32_large)
== 0x1
b9 0x080490a7/imm32 # copy to ECX
b9 0x080490a7/imm32
+transform: packing instruction 'b9 0x080490a7/imm32'
+transform: instruction after packing: 'b9 a7 90 04 08'
:(scenario pack_immediate_constants_hex)
== 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
bb 0x2a/imm32 # copy 42 to EBX
+transform: packing instruction 'bb 0x2a/imm32'
+transform: instruction after packing: 'bb 2a 00 00 00'
+run: copy imm32 0x0000002a to EBX
b9 0x2a/imm32
+transform: packing instruction 'b9 0x2a/imm32'
+transform: instruction after packing: 'b9 2a 00 00 00'
+run: copy imm32 0x0000002a to ECX
:(scenarios transform)
:(scenario pack_silently_ignores_non_hex)
% Hide_errors = true;
== 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
bb foo/imm32 # copy to EBX
+transform: packing instruction 'bb foo/imm32'
b9 foo/imm32
+transform: packing instruction 'b9 foo/imm32'
# 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)
:(scenario pack_flags_bad_hex)
% Hide_errors = true;
== 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
bb 0xfoo/imm32 # copy to EBX
b9 0xfoo/imm32
+error: not a number: 0xfoo
//:: helpers

View File

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

View File

@ -4,7 +4,7 @@
:(scenario segment_name)
== 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
+load: 0x09000054 -> 05
+load: 0x09000055 -> 0a
@ -65,9 +65,9 @@ if (Currently_parsing_named_segment) {
:(scenario repeated_segment_merges_data)
== code
05/add 0x0d0c0b0a/imm32 # add 0x0d0c0b0a to EAX
05/add-to-EAX 0x0d0c0b0a/imm32
== code
2d/subtract 0xddccbbaa/imm32 # subtract 0xddccbbaa from EAX
2d/subtract-from-EAX 0xddccbbaa/imm32
+parse: new segment 'code'
+parse: prepending to segment 'code'
+load: 0x09000054 -> 2d

View File

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

View File

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

View File

@ -5,7 +5,7 @@
:(scenario transform_literal_string)
== code
b8/copy "test"/imm32 # copy to EAX
b8/copy "test"/imm32
== data # need to manually create this for now
+transform: -- move literal strings to data segment
+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
# write(2/stderr, (data) s+4, (size) *s)
# fd = 2 (stderr)
bb/copy . . . . . . . 2/imm32 # copy to EBX
bb/copy-to-EBX 2/imm32
# 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
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 0/mod/indirect 2/rm32/EDX . . . 2/r32/EDX . . # copy *EDX to EDX
# call write()
b8/copy . . . . . . . 4/imm32/write # copy to EAX
b8/copy-to-EAX 4/imm32/write
cd/syscall 0x80/imm8
# restore registers
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-'.
# 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
b8/copy-to-EAX 1/imm32
cd/syscall 0x80/imm8
# 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
81 0/subop/add 3/mod/direct 6/rm32/ESI . . . . . 4/imm32 # add to ESI
# 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)
$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-equal:break/disp8
# 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
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
# if (c1 == 0) return false
3d/compare-EAX 0/imm32
@ -87,16 +87,16 @@ $kernel-string-equal:loop:
eb/jump $kernel-string-equal:loop/disp8
$kernel-string-equal:break:
# 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
3d/compare-EAX 0/imm32
75/jump-if-not-equal $kernel-string-equal:false/disp8
$kernel-string-equal:true:
b8/copy . . . . . . . 1/imm32 # copy to EAX
b8/copy-to-EAX 1/imm32
eb/jump $kernel-string-equal:end/disp8
# return false
$kernel-string-equal:false:
b8/copy . . . . . . . 0/imm32 # copy to EAX
b8/copy-to-EAX 0/imm32
$kernel-string-equal:end:
# restore registers

View File

@ -20,7 +20,7 @@
# exit(EAX)
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
new-segment: # len : int -> address
@ -31,11 +31,11 @@ new-segment: # len : int -> address
# 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-to-EBX mmap-new-segment/imm32
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
b8/copy . . . . . . . 0x5a/imm32/mmap # copy to EAX
bb/copy-to-EBX mmap-new-segment/imm32
b8/copy-to-EAX 0x5a/imm32/mmap
cd/syscall 0x80/imm8
# epilog
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-'.
# 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
b8/copy-to-EAX 1/imm32
cd/syscall 0x80/imm8
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
$string-equal:lengths:
# var i/ECX : int = 0
b9/copy . . . . . . . 0/imm32 # copy to ECX
b9/copy-to-ECX 0/imm32
# EBX = &b[i]
43/inc-EBX
# EAX = &s[i]
@ -69,11 +69,11 @@ $string-equal:loop:
eb/jump $string-equal:loop/disp8
$string-equal:true:
# return true
b8/copy . . . . . . . 1/imm32 # copy to EAX
b8/copy-to-EAX 1/imm32
eb/jump $string-equal:end/disp8
$string-equal:false:
# return false
b8/copy . . . . . . . 0/imm32 # copy to EAX
b8/copy-to-EAX 0/imm32
$string-equal:end:
# restore registers
5e/pop-to-ESI

View File

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

View File

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

View File

@ -12,9 +12,9 @@
# 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
bb/copy . . . . . . . 2a/imm32 # copy 42 to EBX
bb/copy-to-EBX 2a/imm32
# exit(EBX)
b8/copy . . . . . . . 1/imm32 # copy to EAX
b8/copy-to-EAX 1/imm32
cd/syscall 0x80/imm8
# vim:nowrap:textwidth=0

View File

@ -30,7 +30,7 @@
# exit(EAX)
$exit:
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
# compare two null-terminated ascii strings
@ -42,9 +42,9 @@ argv-equal: # (s1, s2) : null-terminated ascii strings -> EAX : boolean
# while (true)
$argv-equal:loop:
# 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
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
# if (c1 == 0) break
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
75/jump-if-not-equal $argv-equal:false/disp8
$argv-equal:success:
b8/copy . . . . . . . 1/imm32 # copy to EAX
b8/copy-to-EAX 1/imm32
c3/return
# return false
$argv-equal:false:
b8/copy . . . . . . . 0/imm32 # copy to EAX
b8/copy-to-EAX 0/imm32
c3/return
# 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-'.
# exit(EAX)
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
# 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
81 0/subop/add 3/mod/direct 6/rm32/ESI . . . . . 4/imm32 # add to ESI
# 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)
$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-equal:break/disp8
# 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
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
# if (c1 == 0) return false
3d/compare-EAX 0/imm32
@ -86,16 +86,16 @@ $kernel-string-equal:loop:
eb/jump $kernel-string-equal:loop/disp8
$kernel-string-equal:break:
# 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
81 7/subop/compare 3/mod/direct 0/rm32/EAX . . . . . 0/imm32 # compare EAX
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:
eb/jump $kernel-string-equal:end/disp8
# return false
$kernel-string-equal:false:
b8/copy . . . . . . . 0/imm32 # copy to EAX
b8/copy-to-EAX 0/imm32
$kernel-string-equal:end:
# restore registers
@ -314,7 +314,7 @@ write-stderr: # s : (address array byte) -> <void>
53/push-EBX
# write(2/stderr, (data) s+4, (size) *s)
# fd = 2 (stderr)
bb/copy . . . . . . . 2/imm32 # copy to EBX
bb/copy-to-EBX 2/imm32
# 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
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 0/mod/indirect 2/rm32/EDX . . . 2/r32/EDX . . # copy *EDX to EDX
# call write()
b8/copy . . . . . . . 4/imm32/write # copy to EAX
b8/copy-to-EAX 4/imm32/write
cd/syscall 0x80/imm8
# restore registers
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
# mmap(0x1000)
bb/copy . . . . . . . mmap-new-segment/imm32 # copy to EBX
b8/copy . . . . . . . 0x5a/imm32/mmap # copy to EAX
bb/copy-to-EBX mmap-new-segment/imm32
b8/copy-to-EAX 0x5a/imm32/mmap
cd/syscall 0x80/imm8
# store to *EAX
@ -21,7 +21,7 @@
# exit(EAX)
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
== data

View File

@ -11,10 +11,10 @@
# 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
bb/copy . . . . . . . 1/imm32 # copy to EBX
bb/copy-to-EBX 1/imm32
43/inc-EBX
# exit(EBX)
b8/copy . . . . . . . 1/imm32 # copy to EAX
b8/copy-to-EAX 1/imm32
cd/syscall 0x80/imm8
# vim:nowrap:textwidth=0

View File

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

View File

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

View File

@ -15,28 +15,28 @@
# read(stdin, x, 1)
# fd = 0 (stdin)
bb/copy . . . . . . . 0/imm32 # copy to EBX
bb/copy-to-EBX 0/imm32
# 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
# size = 1 character
ba/copy . . . . . . . 1/imm32 # copy to EDX
ba/copy-to-EDX 1/imm32
# read(fd, x, size)
b8/copy . . . . . . . 3/imm32/read # copy to EAX
b8/copy-to-EAX 3/imm32/read
cd/syscall 0x80/imm8
# write(stdout, x, 1)
# fd = 1 (stdout)
bb/copy . . . . . . . 1/imm32 # copy to EBX
bb/copy-to-EBX 1/imm32
# 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
# size = 1 character
ba/copy . . . . . . . 1/imm32 # copy to EDX
ba/copy-to-EDX 1/imm32
# write(fd, x, size)
b8/copy . . . . . . . 4/imm32/write # copy to EAX
b8/copy-to-EAX 4/imm32/write
cd/syscall 0x80/imm8
# exit(EBX)
b8/copy . . . . . . . 1/imm32/exit # copy to EAX
b8/copy-to-EAX 1/imm32/exit
cd/syscall 0x80/imm8
# vim:nowrap:textwidth=0

View File

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

View File

@ -30,14 +30,14 @@
# exit(EAX)
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
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
b8/copy-to-EAX 0/imm32
$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

View File

@ -33,7 +33,7 @@
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
b8/copy . . . . . . . 1/imm32/exit # copy to EAX
b8/copy-to-EAX 1/imm32/exit
cd/syscall 0x80/imm8
ascii-difference: # (s1, s2) : null-terminated ascii strings