1
2
3
4
5 :(scenario warn_on_jump_offset)
6 == 0x1
7 7e/jump-if 1/disp8
8 +warn: '7e/jump-if 1/disp8': using raw offsets for jumps is not recommended; use labels instead
9
10 :(scenarios transform)
11 :(scenario warn_on_call_offset)
12 == 0x1
13 e8/call 1/disp32
14 +warn: 'e8/call 1/disp32': using raw offsets for calls is not recommended; use labels instead
15 :(scenarios run)
16
17 :(before "Rewrite Labels(segment code)")
18 recommend_labels(code);
19 if (trace_contains_errors()) return;
20 :(code)
21 void recommend_labels(const segment& code) {
22 trace(99, "transform") << "-- check for numeric labels" << end();
23 for (int i = 0; i < SIZE(code.lines); ++i)
24 recommend_labels(code.lines.at(i));
25 }
26
27 void recommend_labels(const line& inst) {
28 int idx = first_operand(inst);
29 if (idx >= SIZE(inst.words)) return;
30 if (!is_number(inst.words.at(idx).data)) return;
31 if (is_jump(inst))
32 warn << "'" << inst.original << "': using raw offsets for jumps is not recommended; use labels instead\n" << end();
33 else if (is_call(inst))
34 warn << "'" << inst.original << "': using raw offsets for calls is not recommended; use labels instead\n" << end();
35 }
36
37 bool is_jump(const line& inst) {
38 string op1 = preprocess_op(inst.words.at(0)).data;
39 if (op1 == "0f") {
40 string op2 = preprocess_op(inst.words.at(1)).data;
41 return Jump_opcodes_0f.find(op1) != Jump_opcodes_0f.end();
42 }
43 if (op1 == "ff") return subop(inst) == 4;
44 return Jump_opcodes.find(op1) != Jump_opcodes.end();
45 }
46
47 bool is_call(const line& inst) {
48 string op1 = preprocess_op(inst.words.at(0)).data;
49 if (op1 == "e8") return true;
50 if (op1 == "ff") return subop(inst) == 2;
51 return false;
52 }
53
54 int subop(const line& inst) {
55 int idx = first_operand(inst);
56 assert(idx < SIZE(inst.words));
57 return (parse_int(inst.words.at(idx).data)>>3) & 0x7;
58 }
59
60 :(before "End Globals")
61 set<string> Jump_opcodes;
62 set<string> Jump_opcodes_0f;
63 :(before "End One-time Setup")
64 init_jump_opcodes();
65 :(code)
66 void init_jump_opcodes() {
67 Jump_opcodes.insert("74");
68 Jump_opcodes.insert("75");
69 Jump_opcodes.insert("7c");
70 Jump_opcodes.insert("7d");
71 Jump_opcodes.insert("7e");
72 Jump_opcodes.insert("7f");
73 Jump_opcodes_0f.insert("84");
74 Jump_opcodes_0f.insert("85");
75 Jump_opcodes_0f.insert("8c");
76 Jump_opcodes_0f.insert("8d");
77 Jump_opcodes_0f.insert("8e");
78 Jump_opcodes_0f.insert("8f");
79 Jump_opcodes.insert("e9");
80 Jump_opcodes.insert("eb");
81 }