Skip to content

Instantly share code, notes, and snippets.

@r2p2
Created August 29, 2010 08:27
Show Gist options
  • Save r2p2/556107 to your computer and use it in GitHub Desktop.
Save r2p2/556107 to your computer and use it in GitHub Desktop.
#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 &reg_a,
uint32_t &reg_b,
uint32_t &reg_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