https://github.com/akkartik/mu/blob/main/linux/bootstrap/019functions.cc
1
2
3 :(before "End Initialize Op Names")
4 put_new(Name, "e8", "call disp32 (call)");
5
6 :(code)
7 void test_call_disp32() {
8 Mem.push_back(vma(0xbd000000));
9 Reg[ESP].u = 0xbd000064;
10 run(
11 "== code 0x1\n"
12
13 " e8 a0 00 00 00 \n"
14
15 );
16 CHECK_TRACE_CONTENTS(
17 "run: call imm32 0x000000a0\n"
18 "run: decrementing ESP to 0xbd000060\n"
19 "run: pushing value 0x00000006\n"
20 "run: jumping to 0x000000a6\n"
21 );
22 }
23
24 :(before "End Single-Byte Opcodes")
25 case 0xe8: {
26 const int32_t offset = next32();
27 ++Callstack_depth;
28 trace(Callstack_depth+1, "run") << "call imm32 0x" << HEXWORD << offset << end();
29
30 push(EIP);
31 EIP += offset;
32 trace(Callstack_depth+1, "run") << "jumping to 0x" << HEXWORD << EIP << end();
33 break;
34 }
35
36
37
38 :(code)
39 void test_call_r32() {
40 Mem.push_back(vma(0xbd000000));
41 Reg[ESP].u = 0xbd000064;
42 Reg[EBX].u = 0x000000a0;
43 run(
44 "== code 0x1\n"
45
46 " ff d3 \n"
47
48 );
49 CHECK_TRACE_CONTENTS(
50 "run: call to r/m32\n"
51 "run: r/m32 is EBX\n"
52 "run: decrementing ESP to 0xbd000060\n"
53 "run: pushing value 0x00000003\n"
54 "run: jumping to 0x000000a0\n"
55 );
56 }
57
58 :(before "End Op ff Subops")
59 case 2: {
60 trace(Callstack_depth+1, "run") << "call to r/m32" << end();
61 const int32_t* offset = effective_address(modrm);
62 push(EIP);
63 EIP = *offset;
64 trace(Callstack_depth+1, "run") << "jumping to 0x" << HEXWORD << EIP << end();
65 ++Callstack_depth;
66 break;
67 }
68
69 :(code)
70 void test_call_mem_at_rm32() {
71 Mem.push_back(vma(0xbd000000));
72 Reg[ESP].u = 0xbd000064;
73 Reg[EBX].u = 0x2000;
74 run(
75 "== code 0x1\n"
76
77 " ff 13 \n"
78
79 "== data 0x2000\n"
80 "a0 00 00 00\n"
81 );
82 CHECK_TRACE_CONTENTS(
83 "run: call to r/m32\n"
84 "run: effective address is 0x00002000 (EBX)\n"
85 "run: decrementing ESP to 0xbd000060\n"
86 "run: pushing value 0x00000003\n"
87 "run: jumping to 0x000000a0\n"
88 );
89 }
90
91
92
93 :(before "End Initialize Op Names")
94 put_new(Name, "c3", "return from most recent unfinished call (ret)");
95
96 :(code)
97 void test_ret() {
98 Mem.push_back(vma(0xbd000000));
99 Reg[ESP].u = 0xbd000064;
100 write_mem_u32(Reg[ESP].u, 0x10);
101 run(
102 "== code 0x1\n"
103
104 " c3 \n"
105 "== data 0x2000\n"
106 "10 00 00 00\n"
107 );
108 CHECK_TRACE_CONTENTS(
109 "run: return\n"
110 "run: popping value 0x00000010\n"
111 "run: jumping to 0x00000010\n"
112 );
113 }
114
115 :(before "End Single-Byte Opcodes")
116 case 0xc3: {
117 trace(Callstack_depth+1, "run") << "return" << end();
118 --Callstack_depth;
119 EIP = pop();
120 trace(Callstack_depth+1, "run") << "jumping to 0x" << HEXWORD << EIP << end();
121 break;
122 }