From 4a943d4ed313eff001504c2b5c472266e86a38af Mon Sep 17 00:00:00 2001 From: Kartik Agaram Date: Tue, 12 Mar 2019 18:56:55 -0700 Subject: 5001 - drop the :(scenario) DSL I've been saying for a while[1][2][3] that adding extra abstractions makes things harder for newcomers, and adding new notations doubly so. And then I notice this DSL in my own backyard. Makes me feel like a hypocrite. [1] https://news.ycombinator.com/item?id=13565743#13570092 [2] https://lobste.rs/s/to8wpr/configuration_files_are_canary_warning [3] https://lobste.rs/s/mdmcdi/little_languages_by_jon_bentley_1986#c_3miuf2 The implementation of the DSL was also highly hacky: a) It was happening in the tangle/ tool, but was utterly unrelated to tangling layers. b) There were several persnickety constraints on the different kinds of lines and the specific order they were expected in. I kept finding bugs where the translator would silently do the wrong thing. Or the error messages sucked, and readers may be stuck looking at the generated code to figure out what happened. Fixing error messages would require a lot more code, which is one of my arguments against DSLs in the first place: they may be easy to implement, but they're hard to design to go with the grain of the underlying platform. They require lots of iteration. Is that effort worth prioritizing in this project? On the other hand, the DSL did make at least some readers' life easier, the ones who weren't immediately put off by having to learn a strange syntax. There were fewer quotes to parse, fewer backslash escapes. Anyway, since there are also people who dislike having to put up with strange syntaxes, we'll call that consideration a wash and tear this DSL out. --- This commit was sheer drudgery. Hopefully it won't need to be redone with a new DSL because I grow sick of backslashes. --- subx/018jump_disp32.cc | 424 +++++++++++++++++++++++++++++-------------------- 1 file changed, 254 insertions(+), 170 deletions(-) (limited to 'subx/018jump_disp32.cc') diff --git a/subx/018jump_disp32.cc b/subx/018jump_disp32.cc index c86cd2df..836146ee 100644 --- a/subx/018jump_disp32.cc +++ b/subx/018jump_disp32.cc @@ -5,16 +5,22 @@ :(before "End Initialize Op Names") put_new(Name, "e9", "jump disp32 bytes away (jmp)"); -:(scenario jump_disp32) -== 0x1 -# op ModR/M SIB displacement immediate - e9 05 00 00 00 # skip 1 instruction - 05 00 00 00 01 - 05 00 00 00 02 -+run: 0x00000001 opcode: e9 -+run: jump 5 -+run: 0x0000000b opcode: 05 --run: 0x00000006 opcode: 05 +:(code) +void test_jump_disp32() { + run( + "== 0x1\n" // code segment + // op ModR/M SIB displacement immediate + " e9 05 00 00 00 \n" // skip 1 instruction + " 05 00 00 00 01 \n" + " 05 00 00 00 02 \n" + ); + CHECK_TRACE_CONTENTS( + "run: 0x00000001 opcode: e9\n" + "run: jump 5\n" + "run: 0x0000000b opcode: 05\n" + ); + CHECK_TRACE_DOESNT_CONTAIN("run: 0x00000006 opcode: 05"); +} :(before "End Single-Byte Opcodes") case 0xe9: { // jump disp32 @@ -29,17 +35,23 @@ case 0xe9: { // jump disp32 :(before "End Initialize Op Names") put_new(Name_0f, "84", "jump disp32 bytes away if equal, if ZF is set (jcc/jz/je)"); -:(scenario je_disp32_success) -% ZF = true; -== 0x1 -# op ModR/M SIB displacement immediate - 0f 84 05 00 00 00 # skip 1 instruction - 05 00 00 00 01 - 05 00 00 00 02 -+run: 0x00000001 opcode: 0f -+run: jump 5 -+run: 0x0000000c opcode: 05 --run: 0x00000007 opcode: 05 +:(code) +void test_je_disp32_success() { + ZF = true; + run( + "== 0x1\n" // code segment + // op ModR/M SIB displacement immediate + " 0f 84 05 00 00 00 \n" // skip 1 instruction + " 05 00 00 00 01 \n" + " 05 00 00 00 02 \n" + ); + CHECK_TRACE_CONTENTS( + "run: 0x00000001 opcode: 0f\n" + "run: jump 5\n" + "run: 0x0000000c opcode: 05\n" + ); + CHECK_TRACE_DOESNT_CONTAIN("run: 0x00000007 opcode: 05"); +} :(before "End Two-Byte Opcodes Starting With 0f") case 0x84: { // jump disp32 if ZF @@ -51,34 +63,46 @@ case 0x84: { // jump disp32 if ZF break; } -:(scenario je_disp32_fail) -% ZF = false; -== 0x1 -# op ModR/M SIB displacement immediate - 0f 84 05 00 00 00 # skip 1 instruction - 05 00 00 00 01 - 05 00 00 00 02 -+run: 0x00000001 opcode: 0f -+run: 0x00000007 opcode: 05 -+run: 0x0000000c opcode: 05 --run: jump 5 +:(code) +void test_je_disp32_fail() { + ZF = false; + run( + "== 0x1\n" // code segment + // op ModR/M SIB displacement immediate + " 0f 84 05 00 00 00 \n" // skip 1 instruction + " 05 00 00 00 01 \n" + " 05 00 00 00 02 \n" + ); + CHECK_TRACE_CONTENTS( + "run: 0x00000001 opcode: 0f\n" + "run: 0x00000007 opcode: 05\n" + "run: 0x0000000c opcode: 05\n" + ); + CHECK_TRACE_DOESNT_CONTAIN("run: jump 5"); +} //:: jump if not equal/not zero :(before "End Initialize Op Names") put_new(Name_0f, "85", "jump disp32 bytes away if not equal, if ZF is not set (jcc/jnz/jne)"); -:(scenario jne_disp32_success) -% ZF = false; -== 0x1 -# op ModR/M SIB displacement immediate - 0f 85 05 00 00 00 # skip 1 instruction - 05 00 00 00 01 - 05 00 00 00 02 -+run: 0x00000001 opcode: 0f -+run: jump 5 -+run: 0x0000000c opcode: 05 --run: 0x00000007 opcode: 05 +:(code) +void test_jne_disp32_success() { + ZF = false; + run( + "== 0x1\n" // code segment + // op ModR/M SIB displacement immediate + " 0f 85 05 00 00 00 \n" // skip 1 instruction + " 05 00 00 00 01 \n" + " 05 00 00 00 02 \n" + ); + CHECK_TRACE_CONTENTS( + "run: 0x00000001 opcode: 0f\n" + "run: jump 5\n" + "run: 0x0000000c opcode: 05\n" + ); + CHECK_TRACE_DOESNT_CONTAIN("run: 0x00000007 opcode: 05"); +} :(before "End Two-Byte Opcodes Starting With 0f") case 0x85: { // jump disp32 unless ZF @@ -90,36 +114,48 @@ case 0x85: { // jump disp32 unless ZF break; } -:(scenario jne_disp32_fail) -% ZF = true; -== 0x1 -# op ModR/M SIB displacement immediate - 0f 85 05 00 00 00 # skip 1 instruction - 05 00 00 00 01 - 05 00 00 00 02 -+run: 0x00000001 opcode: 0f -+run: 0x00000007 opcode: 05 -+run: 0x0000000c opcode: 05 --run: jump 5 +:(code) +void test_jne_disp32_fail() { + ZF = true; + run( + "== 0x1\n" // code segment + // op ModR/M SIB displacement immediate + " 0f 85 05 00 00 00 \n" // skip 1 instruction + " 05 00 00 00 01 \n" + " 05 00 00 00 02 \n" + ); + CHECK_TRACE_CONTENTS( + "run: 0x00000001 opcode: 0f\n" + "run: 0x00000007 opcode: 05\n" + "run: 0x0000000c opcode: 05\n" + ); + CHECK_TRACE_DOESNT_CONTAIN("run: jump 5"); +} //:: jump if greater :(before "End Initialize Op Names") put_new(Name_0f, "8f", "jump disp32 bytes away if greater, if ZF is unset and SF == OF (jcc/jg/jnle)"); -:(scenario jg_disp32_success) -% ZF = false; -% SF = false; -% OF = false; -== 0x1 -# op ModR/M SIB displacement immediate - 0f 8f 05 00 00 00 # skip 1 instruction - 05 00 00 00 01 - 05 00 00 00 02 -+run: 0x00000001 opcode: 0f -+run: jump 5 -+run: 0x0000000c opcode: 05 --run: 0x00000007 opcode: 05 +:(code) +void test_jg_disp32_success() { + ZF = false; + SF = false; + OF = false; + run( + "== 0x1\n" // code segment + // op ModR/M SIB displacement immediate + " 0f 8f 05 00 00 00 \n" // skip 1 instruction + " 05 00 00 00 01 \n" + " 05 00 00 00 02 \n" + ); + CHECK_TRACE_CONTENTS( + "run: 0x00000001 opcode: 0f\n" + "run: jump 5\n" + "run: 0x0000000c opcode: 05\n" + ); + CHECK_TRACE_DOESNT_CONTAIN("run: 0x00000007 opcode: 05"); +} :(before "End Two-Byte Opcodes Starting With 0f") case 0x8f: { // jump disp32 if !SF and !ZF @@ -131,37 +167,49 @@ case 0x8f: { // jump disp32 if !SF and !ZF break; } -:(scenario jg_disp32_fail) -% ZF = false; -% SF = true; -% OF = false; -== 0x1 -# op ModR/M SIB displacement immediate - 0f 8f 05 00 00 00 # skip 1 instruction - 05 00 00 00 01 - 05 00 00 00 02 -+run: 0x00000001 opcode: 0f -+run: 0x00000007 opcode: 05 -+run: 0x0000000c opcode: 05 --run: jump 5 +:(code) +void test_jg_disp32_fail() { + ZF = false; + SF = true; + OF = false; + run( + "== 0x1\n" // code segment + // op ModR/M SIB displacement immediate + " 0f 8f 05 00 00 00 \n" // skip 1 instruction + " 05 00 00 00 01 \n" + " 05 00 00 00 02 \n" + ); + CHECK_TRACE_CONTENTS( + "run: 0x00000001 opcode: 0f\n" + "run: 0x00000007 opcode: 05\n" + "run: 0x0000000c opcode: 05\n" + ); + CHECK_TRACE_DOESNT_CONTAIN("run: jump 5"); +} //:: jump if greater or equal :(before "End Initialize Op Names") put_new(Name_0f, "8d", "jump disp32 bytes away if greater or equal, if SF == OF (jcc/jge/jnl)"); -:(scenario jge_disp32_success) -% SF = false; -% OF = false; -== 0x1 -# op ModR/M SIB displacement immediate - 0f 8d 05 00 00 00 # skip 1 instruction - 05 00 00 00 01 - 05 00 00 00 02 -+run: 0x00000001 opcode: 0f -+run: jump 5 -+run: 0x0000000c opcode: 05 --run: 0x00000007 opcode: 05 +:(code) +void test_jge_disp32_success() { + SF = false; + OF = false; + run( + "== 0x1\n" // code segment + // op ModR/M SIB displacement immediate + " 0f 8d 05 00 00 00 \n" // skip 1 instruction + " 05 00 00 00 01 \n" + " 05 00 00 00 02 \n" + ); + CHECK_TRACE_CONTENTS( + "run: 0x00000001 opcode: 0f\n" + "run: jump 5\n" + "run: 0x0000000c opcode: 05\n" + ); + CHECK_TRACE_DOESNT_CONTAIN("run: 0x00000007 opcode: 05"); +} :(before "End Two-Byte Opcodes Starting With 0f") case 0x8d: { // jump disp32 if !SF @@ -173,37 +221,49 @@ case 0x8d: { // jump disp32 if !SF break; } -:(scenario jge_disp32_fail) -% SF = true; -% OF = false; -== 0x1 -# op ModR/M SIB displacement immediate - 0f 8d 05 00 00 00 # skip 1 instruction - 05 00 00 00 01 - 05 00 00 00 02 -+run: 0x00000001 opcode: 0f -+run: 0x00000007 opcode: 05 -+run: 0x0000000c opcode: 05 --run: jump 5 +:(code) +void test_jge_disp32_fail() { + SF = true; + OF = false; + run( + "== 0x1\n" // code segment + // op ModR/M SIB displacement immediate + " 0f 8d 05 00 00 00 \n" // skip 1 instruction + " 05 00 00 00 01 \n" + " 05 00 00 00 02 \n" + ); + CHECK_TRACE_CONTENTS( + "run: 0x00000001 opcode: 0f\n" + "run: 0x00000007 opcode: 05\n" + "run: 0x0000000c opcode: 05\n" + ); + CHECK_TRACE_DOESNT_CONTAIN("run: jump 5"); +} //:: jump if lesser :(before "End Initialize Op Names") put_new(Name_0f, "8c", "jump disp32 bytes away if lesser, if SF != OF (jcc/jl/jnge)"); -:(scenario jl_disp32_success) -% ZF = false; -% SF = true; -% OF = false; -== 0x1 -# op ModR/M SIB displacement immediate - 0f 8c 05 00 00 00 # skip 1 instruction - 05 00 00 00 01 - 05 00 00 00 02 -+run: 0x00000001 opcode: 0f -+run: jump 5 -+run: 0x0000000c opcode: 05 --run: 0x00000007 opcode: 05 +:(code) +void test_jl_disp32_success() { + ZF = false; + SF = true; + OF = false; + run( + "== 0x1\n" // code segment + // op ModR/M SIB displacement immediate + " 0f 8c 05 00 00 00 \n" // skip 1 instruction + " 05 00 00 00 01 \n" + " 05 00 00 00 02 \n" + ); + CHECK_TRACE_CONTENTS( + "run: 0x00000001 opcode: 0f\n" + "run: jump 5\n" + "run: 0x0000000c opcode: 05\n" + ); + CHECK_TRACE_DOESNT_CONTAIN("run: 0x00000007 opcode: 05"); +} :(before "End Two-Byte Opcodes Starting With 0f") case 0x8c: { // jump disp32 if SF and !ZF @@ -215,52 +275,70 @@ case 0x8c: { // jump disp32 if SF and !ZF break; } -:(scenario jl_disp32_fail) -% ZF = false; -% SF = false; -% OF = false; -== 0x1 -# op ModR/M SIB displacement immediate - 0f 8c 05 00 00 00 # skip 1 instruction - 05 00 00 00 01 - 05 00 00 00 02 -+run: 0x00000001 opcode: 0f -+run: 0x00000007 opcode: 05 -+run: 0x0000000c opcode: 05 --run: jump 5 +:(code) +void test_jl_disp32_fail() { + ZF = false; + SF = false; + OF = false; + run( + "== 0x1\n" // code segment + // op ModR/M SIB displacement immediate + " 0f 8c 05 00 00 00 \n" // skip 1 instruction + " 05 00 00 00 01 \n" + " 05 00 00 00 02 \n" + ); + CHECK_TRACE_CONTENTS( + "run: 0x00000001 opcode: 0f\n" + "run: 0x00000007 opcode: 05\n" + "run: 0x0000000c opcode: 05\n" + ); + CHECK_TRACE_DOESNT_CONTAIN("run: jump 5"); +} //:: jump if lesser or equal :(before "End Initialize Op Names") put_new(Name_0f, "8e", "jump disp32 bytes away if lesser or equal, if ZF is set or SF != OF (jcc/jle/jng)"); -:(scenario jle_disp32_equal) -% ZF = true; -% SF = false; -% OF = false; -== 0x1 -# op ModR/M SIB displacement immediate - 0f 8e 05 00 00 00 # skip 1 instruction - 05 00 00 00 01 - 05 00 00 00 02 -+run: 0x00000001 opcode: 0f -+run: jump 5 -+run: 0x0000000c opcode: 05 --run: 0x00000007 opcode: 05 - -:(scenario jle_disp32_lesser) -% ZF = false; -% SF = true; -% OF = false; -== 0x1 -# op ModR/M SIB displacement immediate - 0f 8e 05 00 00 00 # skip 1 instruction - 05 00 00 00 01 - 05 00 00 00 02 -+run: 0x00000001 opcode: 0f -+run: jump 5 -+run: 0x0000000c opcode: 05 --run: 0x00000007 opcode: 05 +:(code) +void test_jle_disp32_equal() { + ZF = true; + SF = false; + OF = false; + run( + "== 0x1\n" // code segment + // op ModR/M SIB displacement immediate + " 0f 8e 05 00 00 00 \n" // skip 1 instruction + " 05 00 00 00 01 \n" + " 05 00 00 00 02 \n" + ); + CHECK_TRACE_CONTENTS( + "run: 0x00000001 opcode: 0f\n" + "run: jump 5\n" + "run: 0x0000000c opcode: 05\n" + ); + CHECK_TRACE_DOESNT_CONTAIN("run: 0x00000007 opcode: 05"); +} + +:(code) +void test_jle_disp32_lesser() { + ZF = false; + SF = true; + OF = false; + run( + "== 0x1\n" // code segment + // op ModR/M SIB displacement immediate + " 0f 8e 05 00 00 00 \n" // skip 1 instruction + " 05 00 00 00 01 \n" + " 05 00 00 00 02 \n" + ); + CHECK_TRACE_CONTENTS( + "run: 0x00000001 opcode: 0f\n" + "run: jump 5\n" + "run: 0x0000000c opcode: 05\n" + ); + CHECK_TRACE_DOESNT_CONTAIN("run: 0x00000007 opcode: 05"); +} :(before "End Two-Byte Opcodes Starting With 0f") case 0x8e: { // jump disp32 if SF or ZF @@ -272,16 +350,22 @@ case 0x8e: { // jump disp32 if SF or ZF break; } -:(scenario jle_disp32_greater) -% ZF = false; -% SF = false; -% OF = false; -== 0x1 -# op ModR/M SIB displacement immediate - 0f 8e 05 00 00 00 # skip 1 instruction - 05 00 00 00 01 - 05 00 00 00 02 -+run: 0x00000001 opcode: 0f -+run: 0x00000007 opcode: 05 -+run: 0x0000000c opcode: 05 --run: jump 5 +:(code) +void test_jle_disp32_greater() { + ZF = false; + SF = false; + OF = false; + run( + "== 0x1\n" // code segment + // op ModR/M SIB displacement immediate + " 0f 8e 05 00 00 00 \n" // skip 1 instruction + " 05 00 00 00 01 \n" + " 05 00 00 00 02 \n" + ); + CHECK_TRACE_CONTENTS( + "run: 0x00000001 opcode: 0f\n" + "run: 0x00000007 opcode: 05\n" + "run: 0x0000000c opcode: 05\n" + ); + CHECK_TRACE_DOESNT_CONTAIN("run: jump 5"); +} -- cgit 1.4.1-2-gfad0