Created
August 29, 2010 08:27
-
-
Save r2p2/556107 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdint.h> | |
#include <stdio.h> | |
#include <cstring> | |
#include <fstream> | |
#include <map> | |
#include <arpa/inet.h> | |
uint32_t* load_code(char *file, uint32_t &filesize) | |
{ | |
uint32_t *p_code = NULL; | |
std::ifstream code_file(file, std::ios::in | std::ios::binary | std::ios::ate); | |
filesize = code_file.tellg(); | |
code_file.seekg(0); | |
p_code = new uint32_t[filesize/sizeof(uint32_t)]; | |
for(uint32_t i=0; i<filesize/sizeof(uint32_t); ++i) | |
{ | |
code_file.read(reinterpret_cast<char*>(&p_code[i]), sizeof(uint32_t)); | |
p_code[i] = ntohl(p_code[i]); | |
} | |
return p_code; | |
} | |
void extract_instruction(uint32_t instruction, | |
uint32_t &op, | |
uint32_t ®_a, | |
uint32_t ®_b, | |
uint32_t ®_c) | |
{ | |
reg_a = (instruction&0x1C0)>>6; | |
reg_b = (instruction&0x38)>>3; | |
reg_c = instruction&7; | |
op = (instruction&static_cast<uint32_t>(0xF0000000))>>28; | |
} | |
int main(int argc, char** argv) | |
{ | |
uint32_t *p_code = NULL; | |
uint32_t *p_ip = NULL; | |
uint32_t *p_source = NULL; | |
uint32_t *p_target = NULL; | |
uint32_t tmp_address = 0; | |
uint32_t code_size = 0; | |
uint32_t um_register[8]; | |
uint32_t reg_a, reg_b, reg_c, op; | |
std::map<uint32_t, uint32_t> mem_size; | |
for(uint16_t i=0; i<8; ++i) | |
um_register[i] = 0; | |
p_code = load_code(argv[1], code_size); | |
p_ip = p_code; | |
mem_size[reinterpret_cast<uint32_t>(p_code)] = code_size; | |
while(1) | |
{ | |
extract_instruction(*p_ip, op, reg_a, reg_b, reg_c); | |
switch(op) | |
{ | |
case 0: | |
if(um_register[reg_c] != 0) | |
um_register[reg_a] = um_register[reg_b]; | |
break; | |
case 1: | |
if(um_register[reg_b]) | |
um_register[reg_a] = reinterpret_cast<uint32_t*>(um_register[reg_b])[um_register[reg_c]]; | |
else | |
um_register[reg_a] = p_code[um_register[reg_c]]; | |
break; | |
case 2: | |
if(um_register[reg_a]) | |
reinterpret_cast<uint32_t*>(um_register[reg_a])[um_register[reg_b]] = um_register[reg_c]; | |
else | |
p_code[um_register[reg_b]] = um_register[reg_c]; | |
break; | |
case 3: | |
um_register[reg_a] = um_register[reg_b]+um_register[reg_c]; | |
break; | |
case 4: | |
um_register[reg_a] = um_register[reg_b]*um_register[reg_c]; | |
break; | |
case 5: | |
if(um_register[reg_c]) | |
um_register[reg_a] = um_register[reg_b]/um_register[reg_c]; | |
break; | |
case 6: | |
um_register[reg_a] = ~(um_register[reg_b]&um_register[reg_c]); | |
break; | |
case 7: | |
return 0; | |
break; | |
case 8: | |
tmp_address = reinterpret_cast<uint32_t>(new uint32_t[um_register[reg_c]]); | |
mem_size[tmp_address] = um_register[reg_c]; | |
memset(reinterpret_cast<uint32_t*>(tmp_address), 0, mem_size[tmp_address]*sizeof(uint32_t)); | |
um_register[reg_b] = tmp_address; | |
break; | |
case 9: | |
delete[] reinterpret_cast<uint32_t*>(um_register[reg_c]); | |
break; | |
case 10: | |
printf("%c", um_register[reg_c]); | |
break; | |
case 11: | |
char c[2]; | |
fgets(&c[0], 2, stdin); | |
if(c[0] != 4) | |
um_register[reg_c] = static_cast<uint32_t>(c[0]); | |
else | |
um_register[reg_c] = 0xffffffff; | |
break; | |
case 12: | |
p_source = reinterpret_cast<uint32_t*>(um_register[reg_b]); | |
if(p_source) | |
{ | |
p_target = new uint32_t[mem_size[um_register[reg_b]]]; | |
memcpy(p_target, p_source, mem_size[um_register[reg_b]]*sizeof(uint32_t)); | |
delete[] p_code; | |
p_code = p_target; | |
} | |
p_ip = p_code + um_register[reg_c]; | |
continue; | |
break; | |
case 13: | |
uint32_t special_reg_a = (*p_ip&0xE000000)>>25; | |
uint32_t special_value = *p_ip&0x1FFFFFF; | |
um_register[special_reg_a] = special_value; | |
break; | |
} | |
++p_ip; | |
} | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment