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