4#include <unordered_set>
9using namespace Tempest;
17 std::vector<uint8_t> dbg{ins, ins+len};
21 if(exec1Byte(basePc, pc, ins, len))
23 else if(exec2Byte(basePc, pc, ins, len))
25 else if(exec3Byte(basePc, pc, ins, len))
28 auto op = readUInt32(ins, pc, len);
29 Log::e(
"ASMINT: unknown instruction: ", int32_t(op));
36bool Cpu32::exec1Byte(
const ptr32_t basePc,
ptr32_t& pc,
const uint8_t* ins,
size_t len) {
38 ASMINT_OP_movImToEAX = 184,
39 ASMINT_OP_movImToECX = 185,
40 ASMINT_OP_movImToEDX = 186,
41 ASMINT_OP_pushIm = 104,
48 ASMINT_OP_cmpsb = 166,
49 ASMINT_OP_pushEAX = 80,
50 ASMINT_OP_pushECX = 81,
51 ASMINT_OP_popEAX = 88,
52 ASMINT_OP_popECX = 89,
55 ASMINT_OP_movMemToEAX = 161,
56 ASMINT_OP_movALToMem = 162,
59 const Op1 op = Op1(readUInt8(ins, pc, len));
61 case ASMINT_OP_pushIm: {
62 auto imm = readUInt32(ins, pc+1, len);
67 case ASMINT_OP_movImToEAX:{
68 eax = readUInt32(ins, pc+1, len);
72 case ASMINT_OP_movImToECX: {
73 ecx = readUInt32(ins, pc+1, len);
77 case ASMINT_OP_movImToEDX: {
78 edx = readUInt32(ins, pc+1, len);
82 case ASMINT_OP_call: {
83 ptr32_t calle = readUInt32(ins, pc+1, len);
84 calle = basePc+pc+calle+5;
89 case ASMINT_OP_retn: {
96 case ASMINT_OP_movMemToEAX: {
97 ptr32_t ptr = readUInt32(ins, pc+1, len);
99 eax = uint32_t(mem32.
readInt(ptr));
102 case ASMINT_OP_pushEAX: {
103 stack.push_back(eax);
109 case ASMINT_OP_cmpsb:
110 case ASMINT_OP_pushECX:
111 case ASMINT_OP_popEAX:
112 case ASMINT_OP_popECX:
113 case ASMINT_OP_pusha:
115 case ASMINT_OP_movALToMem:
116 Log::e(
"ASMINT: unimplemented instruction: ", int32_t(op));
122bool Cpu32::exec2Byte(
const ptr32_t basePc,
ptr32_t& pc,
const uint8_t* ins,
size_t len) {
124 ASMINT_OP_movEAXToMem = 1417,
125 ASMINT_OP_movEAXToAL = 138,
126 ASMINT_OP_movCLToEAX = 2184,
127 ASMINT_OP_floatStoreToMem = 7641,
128 ASMINT_OP_addImToESP = 50307,
129 ASMINT_OP_movMemToECX = 3467,
130 ASMINT_OP_movMemToCL = 3466,
131 ASMINT_OP_movMemToEDX = 5515,
132 ASMINT_OP_movMemToEDI = 15755,
133 ASMINT_OP_movMemToESI = 13707,
134 ASMINT_OP_movECXtoEAX = 49547,
135 ASMINT_OP_movESPtoEAX = 50315,
136 ASMINT_OP_movEAXtoECX = 49545,
137 ASMINT_OP_movEBXtoEAX = 55433,
138 ASMINT_OP_movEBPtoEAX = 50571,
139 ASMINT_OP_movEDItoEAX = 51083,
140 ASMINT_OP_addImToEAX = 49283,
143 const Op2 op = Op2(readUInt16(ins, pc, len));
145 case ASMINT_OP_movEAXToMem: {
146 ptr32_t mem = readUInt32(ins, pc+2, len);
151 case ASMINT_OP_addImToESP: {
153 uint8_t imm = readUInt8(ins, pc+2, len);
158 case ASMINT_OP_movMemToECX: {
159 ptr32_t ptr = readUInt32(ins, pc+2, len);
161 ecx = uint32_t(mem32.
readInt(ptr));
164 case ASMINT_OP_movEAXToAL:
165 case ASMINT_OP_movCLToEAX:
166 case ASMINT_OP_floatStoreToMem:
167 case ASMINT_OP_movMemToCL:
168 case ASMINT_OP_movMemToEDX:
169 case ASMINT_OP_movMemToEDI:
170 case ASMINT_OP_movMemToESI:
171 case ASMINT_OP_movECXtoEAX:
172 case ASMINT_OP_movESPtoEAX:
173 case ASMINT_OP_movEAXtoECX:
174 case ASMINT_OP_movEBXtoEAX:
175 case ASMINT_OP_movEBPtoEAX:
176 case ASMINT_OP_movEDItoEAX:
177 case ASMINT_OP_addImToEAX:
178 Log::e(
"ASMINT: unimplemented instruction: ", int32_t(op));
184bool Cpu32::exec3Byte(
const ptr32_t basePc,
ptr32_t& pc,
const uint8_t* ins,
size_t len) {
186 ASMINT_OP_setzMem = 365583,
188 const Op3 op = Op3(readUInt24(ins, pc, len));
190 case ASMINT_OP_setzMem:
191 Log::e(
"ASMINT: unimplemented instruction: ", int32_t(op));
197uint8_t Cpu32::readUInt8(
const uint8_t* code,
size_t offset,
size_t len) {
201 std::memcpy(&ret, code+offset,
sizeof(uint8_t));
205uint16_t Cpu32::readUInt16(
const uint8_t* code,
size_t offset,
size_t len) {
209 std::memcpy(&ret, code+offset,
sizeof(uint16_t));
213uint32_t Cpu32::readUInt24(
const uint8_t* code,
size_t offset,
size_t len) {
217 std::memcpy(&ret, code+offset, 3);
221uint32_t Cpu32::readUInt32(
const uint8_t* code,
size_t offset,
size_t len) {
225 std::memcpy(&ret, code+offset,
sizeof(uint32_t));
229void Cpu32::register_stdcall_inner(
ptr32_t addr, std::function<
void (
Cpu32&)> f) {
230 stdcall_Overrides[addr] = std::move(f);
233void Cpu32::callFunction(
ptr32_t func) {
236 Log::d(
"ASMINT_OP_call: won't invoke function obtained by GetProcAddress ");
240 auto fn = stdcall_Overrides.find(func);
241 if(fn!=stdcall_Overrides.end()) {
246 static std::unordered_set<ptr32_t> once;
247 if(!once.insert(func).second)
252 Log::d(
"ASMINT_OP_call: unknown external function: \"", str,
"\"");
else
253 Log::d(
"ASMINT_OP_call: unknown external function: ", func);
256std::string Cpu32::popString() {
259 auto ptr = stack.back();
263 if(mem==
nullptr || mem->len<=0)
265 auto chr =
reinterpret_cast<const char*
>(mem32.
deref(mem->ptr, uint32_t(mem->len)));
268 std::string ret(chr,
size_t(mem->len));
void exec(const ptr32_t basePc, const uint8_t *code, size_t len)
Compatibility::ptr32_t ptr32_t
Cpu32(DirectMemory &owner, Mem32 &mem32)
auto demangleAddress(uint32_t addr) -> std::string_view
int32_t readInt(ptr32_t address)
auto deref(ptr32_t address) -> std::tuple< void *, uint32_t >
void writeInt(ptr32_t address, int32_t v)