引言
前些时候写了一套CrackMe,纯手工古法编程,不用额外插件和第三方库,各种人肉混淆和花指令,结果还是被IDA+MCP秒了,甚是心痛,可是直接上VMP的话,就太不讲武德了,毕竟只是一个玩具,不至于上这种商业化的保护壳。
何为虚拟机
这里的虚拟机并非是qemu、virtual box、vmware、hyper-v这样的虚拟机,况且我也做不出来呀,emmm。
这里的虚拟机指的是模拟出来一套CPU,自己写寄存器、缓存、栈、指令集,相当于写了一套中间层,最后还是要宿主机进行计算的。
举个例子:
我要计算1+1,那么CPU内部执行大概是这样的。
mov eax,1
mov ebx,1
add eax,ebx
vm中间层呢
我定义一个CPU结构体
struct CPU
{
int CURR_POS; // 当前选中的寄存器,这是我新引入的一个概念
int STORAGE[BASE_STORAGE_SIZE]; // 寄存器
int DATA_STACK[BASE_STACK_SIZE]; // 栈空间
int DATA_STACK_POS; // 栈指针
} cpu;
然后制定指令集
typedef enum
{
OP_MOV
OP_ADD
}
定义实现方法
void op_mov(int arg, int *pc, int code[])
{
cpu.STORAGE[cpu.CURR_POS] = arg;
}
void op_add(int arg, int *pc, int code[])
{
cpu.STORAGE[cpu.CURR_POS] += arg;
}
这时候,我执行op_mov,op_add即可实现加法计算。
指令集的定义
这里需要大概了解一下CPU的实际指令集是什么,然后模拟出来一套自己的指令集,也可以自己diy指令集,混淆指令集,定义多个指令集名称,实现方法不通但是效果相同的等等,提高破解难度。
举个例子:
typedef enum
{
OP_INIT, // 初始化寄存器, 从num开始往后赋值0
OP_SEL, // 选择当前指向寄存器
OP_MOV, // 把值赋给选中的寄存器
OP_ADD, // 选中的寄存器值+给的值
OP_SUB, // 选中的寄存器值-给的值
OP_IMUL, // 选中的寄存器值乘以给的值
OP_MOV_REG, // 给定寄存器的值赋值给选中的寄存器
OP_ADD_REG, // 选中的寄存器加上给定寄存器的值
OP_SUB_REG, // 选中的寄存器减去给定寄存器的值
OP_MUL_REG, // 选中的寄存器乘以给定寄存器的值
OP_BIT_MOV, // 选中的寄存器位移给定的值
OP_JMP, // 跳转到指定行
OP_JZ, // 如果选中的寄存器是0,那么跳转到指定地址
OP_JNZ, // 如果选中的寄存器不是0,那么跳转到指定地址
OP_INC, // 选中的寄存器自增
OP_DEC, // 选中的寄存器自减
OP_AND, // 选中的寄存器与运算
OP_XOR, // 选中的寄存器异或运算
OP_OR, // 选中的寄存器或运算
OP_PUSH, // 给定的寄存器序列推入栈
OP_POP, // 推出栈中最后一个元素到给定的寄存器序列
OP_NOP, // 啥也不做
OP_NOP_N, // 作废后面N个指令
OP_END, // 处理器结束标识
DBG_CPU, // 输出寄存器和栈空间
OP_PRINT, // 输出指定寄存器的值
OP_STORE_CACHE, // 存储缓存
OP_DEC_CACHE, // 解密缓存
OP_CACHE_LEN, // 获取缓存有多少个,并且把结果写道当前选中的寄存器中
OP_CACHE_LEN_ID, // 获取指定ID的缓存有多长,并且放到当前选中的寄存器中
OP_CACHE_START, // 获取缓存的开始索引,并且放到当前选中的寄存器中
OP_CACHE_GET, // 获取缓存中当前寄存器中的索引,到指定寄存器中
OP_JMP_P, // 跳转到当前PC+参数行
OP_JZ_P, // 如果当前选中的寄存器是0,跳转到当前PC+参数行
OP_JNZ_P, // 如果当前选中的寄存器不是0,跳转到当前PC+参数行
OP_JE_P, // 如果当前选中的寄存器等于指定的寄存器,跳转到当前PC+参数行
OP_INT3, // 调试断点
} COMMAND;
当然这个指令集还是有缺陷的,并且不完整的,写到哪儿就加到哪儿吧。
代码怎么写?
这是我比较头痛的事情,因为你制定了指令集,那么你成功的把高级语言转换成了低级语言(仿汇编)
这时候你的代码是这样的
code[CMD_MAX_SIZE] = {
OP_INIT, 0,
OP_SEL, 0,
OP_ADD, 5,
OP_IMUL, 20,
OP_SUB, 13,
OP_ADD_REG, 1,
OP_SEL, 0x01,
OP_ADD, 14,
维护成本极高,逻辑跳转非常复杂
完整代码
指令集的实现没有经过完全确认和测试!
#include <stdio.h>
#include "hardware.h"
#include <stdlib.h>
void vm_run(int* code, const size_t len)
{
int pc = 0;
while (pc >= 0 && pc < len)
{
const int op = code[pc++] ^ ((VM_KEY2 ^ VM_KEY) + 2 * (VM_KEY2 & VM_KEY) - (VM_KEY2 + VM_KEY));
const int arg = code[pc++];
printf("[%d] %s %d\n", pc - 2, command_name[op], arg);
handlers[op](arg, &pc, code);
}
}
int main()
{
int magic = 114514;
int magic2 = 1919810;
int code[CMD_MAX_SIZE] = {
OP_INIT, 0,
OP_SEL, 0,
OP_ADD, 5,
OP_NOP_N, 3, 123, 456, 789, //
OP_IMUL, 20,
OP_SUB, 13,
OP_ADD_REG, 1,
OP_SEL, 0x01,
OP_ADD, 14,
OP_IMUL, 52,
OP_BIT_MOV, -2,
OP_SEL, 0,
OP_MUL_REG, 1,
OP_BIT_MOV, 2,
OP_IMUL, 2,
OP_JZ, 2,
OP_NOP, 0xFF12B8,
OP_NOP_N, 3, 2, 1, 0,
OP_STORE_CACHE, 26, 'A' ^ VM_KEY, 'B' ^ VM_KEY, 'C' ^ VM_KEY, 'D' ^ VM_KEY, 'E' ^ VM_KEY, 'F' ^ VM_KEY,
'G' ^ VM_KEY, 'H' ^ VM_KEY, 'I' ^ VM_KEY, 'J' ^ VM_KEY, 'K' ^ VM_KEY, 'L' ^ VM_KEY, 'M' ^ VM_KEY, 'N' ^ VM_KEY,
'O' ^ VM_KEY, 'P' ^ VM_KEY, 'Q' ^ VM_KEY, 'R' ^ VM_KEY, 'S' ^ VM_KEY, 'T' ^ VM_KEY, 'U' ^ VM_KEY, 'V' ^ VM_KEY,
'W' ^ VM_KEY, 'X' ^ VM_KEY, 'Y' ^ VM_KEY, 'Z' ^ VM_KEY, //
OP_STORE_CACHE, 26, 'a' ^ VM_KEY, 'b' ^ VM_KEY, 'c' ^ VM_KEY, 'd' ^ VM_KEY, 'e' ^ VM_KEY, 'f' ^ VM_KEY,
'g' ^ VM_KEY, 'h' ^ VM_KEY, 'i' ^ VM_KEY, 'j' ^ VM_KEY, 'k' ^ VM_KEY, 'l' ^ VM_KEY, 'm' ^ VM_KEY, 'n' ^ VM_KEY,
'o' ^ VM_KEY, 'p' ^ VM_KEY, 'q' ^ VM_KEY, 'r' ^ VM_KEY, 's' ^ VM_KEY, 't' ^ VM_KEY, 'u' ^ VM_KEY, 'v' ^ VM_KEY,
'w' ^ VM_KEY, 'x' ^ VM_KEY, 'y' ^ VM_KEY, 'z' ^ VM_KEY,
OP_NOP,0X1000400,
OP_SUB, 0x2F00,
OP_SEL, 1,
OP_ADD_REG, 0,
OP_IMUL, 0x1BF,
OP_BIT_MOV, 0x5,
OP_SEL, 2,
OP_ADD_REG, 0,
OP_ADD, 0xFB1,
OP_XOR, 0x520,
OP_IMUL, 0xF,
OP_ADD_REG, 0,
OP_ADD, 0x43C0,
OP_SEL, 1,
OP_BIT_MOV, 6,
OP_ADD, 0x40A,
OP_ADD_REG, 2,
OP_SEL, 2,
OP_SEL, 0,
OP_ADD, -0x7E,
OP_SEL, 3,
OP_MOV, 0,
OP_CACHE_LEN_ID, 1, // R3 存储的是mem长度
OP_SEL, 4,
OP_CACHE_START, 1, // R4 存储的是mem的开始位置
OP_SEL, 5,
OP_ADD_REG, 3,
OP_ADD_REG, 4, // R5 存储的是结束位
OP_SEL, 4,
OP_INT3,0,
OP_CACHE_GET, 6,
OP_PRINT, 6,
OP_INC, 0,
OP_JE_P, 5, 2, // 往下不算本身,往上算本身,指的是跳转参数开始计数
OP_JMP_P, -11, // 同上
OP_MOV, '\n',
OP_PRINT,-1,
DBG_CPU, 1,
OP_END, 0,
};
vm_run(code, CMD_MAX_SIZE);
// int cur_pos = 0; // 已知的初始化位置
// char name[16];
// scanf("%s", name);
// for (int i = 0; i < name[i] != '\0'; i++)
// {
// code[cur_pos++] = OP_ADD;
// code[cur_pos++] = name[i];
// code[cur_pos++] = OP_SEL;
// code[cur_pos++] = (i + 1) % BASE_STORAGE_SIZE;
// }
// code[cur_pos++] = DBG_CPU; // 调试输出cpu
// code[cur_pos++] = 0;
// code[cur_pos++] = OP_END; // 结束虚拟机
// code[cur_pos++] = 0;
// vm_run(code, CMD_MAX_SIZE);
return 0;
}
//
// Created by 36083 on 2026/4/22.
//
#pragma once
#define BASE_STORAGE_SIZE 16
#define BASE_STACK_SIZE 64
#define BASE_MEM_SIZE 65536
#define CMD_MAX_SIZE 10240
typedef void (*op_handler)(int arg, int *pc, int code[]);
#define TEA_MAGIC 0x9E3779B9
#define MAGIC_SBOX(x) ((x ^ 0x6a09e667) + 0xbb67ae85)
int VM_KEY = 0xF3;
int VM_KEY2 = 0x1911F;
struct CPU
{
int CURR_POS;
int STORAGE[BASE_STORAGE_SIZE];
int DATA_STACK[BASE_STACK_SIZE];
int DATA_STACK_POS;
} cpu;
struct CACHE
{
int cache[BASE_MEM_SIZE];
int cache_size; // 已经占用的空间
int cache_pos; // 当前缓存的索引,也就是接下来要写入时数据的位置
int cache_start[BASE_MEM_SIZE - 1]; // 开始索引
int cache_data_len[BASE_MEM_SIZE - 1]; // 数据长度长度
int cache_len; // 有多少个数据
} cache;
typedef enum
{
OUT_OF_STORAGE_INDEX,
OUT_OF_STACK_INDEX,
PC_NUM_EXCEPT,
OUT_OF_CACHE_INDEX,
OUT_OF_CACHE_SIZE,
} EXCEPTION;
char command_name[1000][1000] = {
"OP_INIT",
"OP_SEL",
"OP_MOV",
"OP_ADD",
"OP_SUB",
"OP_IMUL",
"OP_MOV_REG",
"OP_ADD_REG",
"OP_SUB_REG",
"OP_MUL_REG",
"OP_BIT_MOV",
"OP_JMP",
"OP_JZ",
"OP_JNZ",
"OP_INC",
"OP_DEC",
"OP_AND",
"OP_XOR",
"OP_OR",
"OP_PUSH",
"OP_POP",
"OP_NOP",
"OP_NOP_N",
"OP_END",
"DBG_CPU",
"OP_PRINT",
"OP_STORE_CACHE",
"OP_DEC_CACHE",
"OP_CACHE_LEN",
"OP_CACHE_LEN_ID",
"OP_CACHE_START",
"OP_CACHE_GET",
"OP_JMP_P",
"OP_JZ_P",
"OP_JNZ_P",
"OP_JE_P",
"OP_INT3"};
typedef enum
{
OP_INIT, // 初始化寄存器, 从num开始往后赋值0
OP_SEL, // 选择当前指向寄存器
OP_MOV, // 把值赋给选中的寄存器
OP_ADD, // 选中的寄存器值+给的值
OP_SUB, // 选中的寄存器值-给的值
OP_IMUL, // 选中的寄存器值乘以给的值
OP_MOV_REG, // 给定寄存器的值赋值给选中的寄存器
OP_ADD_REG, // 选中的寄存器加上给定寄存器的值
OP_SUB_REG, // 选中的寄存器减去给定寄存器的值
OP_MUL_REG, // 选中的寄存器乘以给定寄存器的值
OP_BIT_MOV, // 选中的寄存器位移给定的值
OP_JMP, // 跳转到指定行
OP_JZ, // 如果选中的寄存器是0,那么跳转到指定地址
OP_JNZ, // 如果选中的寄存器不是0,那么跳转到指定地址
OP_INC, // 选中的寄存器自增
OP_DEC, // 选中的寄存器自减
OP_AND, // 选中的寄存器与运算
OP_XOR, // 选中的寄存器异或运算
OP_OR, // 选中的寄存器或运算
OP_PUSH, // 给定的寄存器序列推入栈
OP_POP, // 推出栈中最后一个元素到给定的寄存器序列
OP_NOP, // 啥也不做
OP_NOP_N, // 作废后面N个指令
OP_END, // 处理器结束标识
DBG_CPU, // 输出寄存器和栈空间
OP_PRINT, // 输出指定寄存器的值
OP_STORE_CACHE, // 存储缓存
OP_DEC_CACHE, // 解密缓存
OP_CACHE_LEN, // 获取缓存有多少个,并且把结果写道当前选中的寄存器中
OP_CACHE_LEN_ID, // 获取指定ID的缓存有多长,并且放到当前选中的寄存器中
OP_CACHE_START, // 获取缓存的开始索引,并且放到当前选中的寄存器中
OP_CACHE_GET, // 获取缓存中当前寄存器中的索引,到指定寄存器中
OP_JMP_P, // 跳转到当前PC+参数行
OP_JZ_P, // 如果当前选中的寄存器是0,跳转到当前PC+参数行
OP_JNZ_P, // 如果当前选中的寄存器不是0,跳转到当前PC+参数行
OP_JE_P, // 如果当前选中的寄存器等于指定的寄存器,跳转到当前PC+参数行
OP_INT3, // 调试断点
} COMMAND;
void op_init(int arg, int *pc, int code[]);
void op_sel(int arg, int *pc, int code[]);
void op_mov(int arg, int *pc, int code[]);
void op_add(int arg, int *pc, int code[]);
void op_sub(int arg, int *pc, int code[]);
void op_imul(int arg, int *pc, int code[]);
void op_mov_reg(int arg, int *pc, int code[]);
void op_add_reg(int arg, int *pc, int code[]);
void op_sub_reg(int arg, int *pc, int code[]);
void op_mul_reg(int arg, int *pc, int code[]);
void op_bit_mov(int arg, int *pc, int code[]);
void op_jmp(int arg, int *pc, int code[]);
void op_jz(int arg, int *pc, int code[]);
void op_jnz(int arg, int *pc, int code[]);
void op_inc(int arg, int *pc, int code[]);
void op_dec(int arg, int *pc, int code[]);
void op_and(int arg, int *pc, int code[]);
void op_xor(int arg, int *pc, int code[]);
void op_or(int arg, int *pc, int code[]);
void op_push(int arg, int *pc, int code[]);
void op_pop(int arg, int *pc, int code[]);
void op_nop(int arg, int *pc, int code[]);
void op_nop_n(int arg, int *pc, int code[]);
void op_end(int arg, int *pc, int code[]);
void dbg_cpu(int arg, int *pc, int code[]);
void op_print(int arg, int *pc, int code[]);
void op_store_cache(int arg, int *pc, int code[]);
void op_dec_cache(int arg, int *pc, int code[]);
void op_cache_len(int arg, int *pc, int code[]);
void op_cache_len_id(int arg, int *pc, int code[]);
void op_cache_start(int arg, int *pc, int code[]);
void op_cache_get(int arg, int *pc, int code[]);
void op_jmp_p(int arg, int *pc, int code[]);
void op_jz_p(int arg, int *pc, int code[]);
void op_jnz_p(int arg, int *pc, int code[]);
void op_je_p(int arg, int *pc, int code[]);
void op_int3(int arg, int *pc, int code[]);
void HALT(EXCEPTION expect, int *pc);
op_handler handlers[] = {
op_init,
op_sel,
op_mov,
op_add,
op_sub,
op_imul,
op_mov_reg,
op_add_reg,
op_sub_reg,
op_mul_reg,
op_bit_mov,
op_jmp,
op_jz,
op_jnz,
op_inc,
op_dec,
op_and,
op_xor,
op_or,
op_push,
op_pop,
op_nop,
op_nop_n,
op_end,
dbg_cpu,
op_print,
op_store_cache,
op_dec_cache,
op_cache_len,
op_cache_len_id,
op_cache_start,
op_cache_get,
op_jmp_p,
op_jz_p,
op_jnz_p,
op_je_p,
op_int3,
};
void op_init(int arg, int *pc, int code[])
{
cpu.DATA_STACK_POS = 0;
cache.cache_size = 0;
cache.cache_pos = 0;
cache.cache_len = 0;
for (int i = arg; i < BASE_STORAGE_SIZE; i++)
{
op_sel(i, pc, code);
op_mov(0, pc, code);
}
}
void op_sel(int arg, int *pc, int code[])
{
if (arg < BASE_STORAGE_SIZE && arg >= 0)
cpu.CURR_POS = arg;
else
HALT(OUT_OF_STORAGE_INDEX, pc);
}
void op_mov(int arg, int *pc, int code[])
{
cpu.STORAGE[cpu.CURR_POS] = arg;
}
void op_add(int arg, int *pc, int code[])
{
cpu.STORAGE[cpu.CURR_POS] += arg;
}
void op_sub(int arg, int *pc, int code[])
{
cpu.STORAGE[cpu.CURR_POS] -= arg;
}
void op_imul(int arg, int *pc, int code[])
{
cpu.STORAGE[cpu.CURR_POS] *= arg;
}
void op_mov_reg(int arg, int *pc, int code[])
{
cpu.STORAGE[cpu.CURR_POS] = cpu.STORAGE[arg];
}
void op_add_reg(int arg, int *pc, int code[])
{
cpu.STORAGE[cpu.CURR_POS] += cpu.STORAGE[arg];
}
void op_sub_reg(int arg, int *pc, int code[])
{
cpu.STORAGE[cpu.CURR_POS] -= cpu.STORAGE[arg];
}
void op_mul_reg(int arg, int *pc, int code[])
{
cpu.STORAGE[cpu.CURR_POS] *= cpu.STORAGE[arg];
}
void op_bit_mov(int arg, int *pc, int code[])
{
if (arg > 0)
cpu.STORAGE[cpu.CURR_POS] >>= arg;
else
cpu.STORAGE[cpu.CURR_POS] <<= -arg;
}
void op_jmp(int arg, int *pc, int code[])
{
*pc = arg;
}
void op_jz(int arg, int *pc, int code[])
{
if (!cpu.STORAGE[cpu.CURR_POS])
*pc = arg;
}
void op_jnz(int arg, int *pc, int code[])
{
if (cpu.STORAGE[cpu.CURR_POS])
*pc = arg;
}
void op_inc(int arg, int *pc, int code[])
{
cpu.STORAGE[cpu.CURR_POS]++;
}
void op_dec(int arg, int *pc, int code[])
{
cpu.STORAGE[cpu.CURR_POS]--;
}
void op_and(int arg, int *pc, int code[])
{
cpu.STORAGE[cpu.CURR_POS] = cpu.STORAGE[cpu.CURR_POS] & arg;
}
void op_xor(int arg, int *pc, int code[])
{
cpu.STORAGE[cpu.CURR_POS] = cpu.STORAGE[cpu.CURR_POS] ^ arg;
}
void op_or(int arg, int *pc, int code[])
{
cpu.STORAGE[cpu.CURR_POS] = cpu.STORAGE[cpu.CURR_POS] | arg;
}
void op_push(int arg, int *pc, int code[])
{
if (cpu.DATA_STACK_POS < 0 || cpu.DATA_STACK_POS >= BASE_STACK_SIZE)
HALT(OUT_OF_STACK_INDEX, pc);
if (arg >= BASE_STORAGE_SIZE || arg < -1)
HALT(OUT_OF_STORAGE_INDEX, pc);
cpu.DATA_STACK[cpu.DATA_STACK_POS++] = cpu.STORAGE[arg == -1 ? cpu.CURR_POS : arg];
}
void op_pop(int arg, int *pc, int code[])
{
if (cpu.DATA_STACK_POS <= 0 || cpu.DATA_STACK_POS >= BASE_STACK_SIZE)
HALT(OUT_OF_STACK_INDEX, pc);
if (arg >= BASE_STORAGE_SIZE || arg < -1)
HALT(OUT_OF_STORAGE_INDEX, pc);
cpu.STORAGE[arg == -1 ? cpu.CURR_POS : arg] = cpu.DATA_STACK[--cpu.DATA_STACK_POS];
}
void op_nop(int arg, int *pc, int code[])
{
*pc ^= VM_KEY;
*pc ^= VM_KEY;
}
void op_nop_n(int arg, int *pc, int code[])
{
arg = arg > 0 ? arg : -arg;
op_nop(arg, pc, code);
*pc += arg;
}
void op_end(int arg, int *pc, int code[])
{
*pc = 0xFFFFFF;
}
void dbg_cpu(int arg, int *pc, int code[])
{
printf("==================================STORAGE================================\n");
for (int i = 0; i < BASE_STORAGE_SIZE; i++)
{
printf("=R=%2d : %d\t", i, cpu.STORAGE[i]);
if (i % 6 == 0 && i != 0)
printf("\n");
}
printf("\n==================================STACK==================================\n");
for (int i = 0; i < BASE_STORAGE_SIZE; i++)
{
printf("=S=%2d : %d\t", i, cpu.DATA_STACK[i]);
if (i % 6 == 0 && i != 0)
printf("\n");
}
printf("\n=========================================================================\n");
}
void HALT(EXCEPTION expect, int *pc)
{
switch (expect)
{
case OUT_OF_STACK_INDEX:
printf("Out of stack index\n");
break;
case OUT_OF_STORAGE_INDEX:
printf("Out of storage index\n");
break;
case PC_NUM_EXCEPT:
printf("PC num except\n");
break;
case OUT_OF_CACHE_SIZE:
printf("Out of cache size\n");
break;
case OUT_OF_CACHE_INDEX:
printf("Out of cache index\n");
break;
}
*pc = -1;
printf("====================EXCEPT====================\n");
printf("=PC= : %d\n", *pc);
printf("=CPOS= : %d\n", cpu.CURR_POS);
printf("=SPOS= : %d\n", cpu.DATA_STACK_POS);
printf("==============================================\n");
}
void op_print(int arg, int *pc, int code[])
{
if (arg < -1 || arg >= BASE_STORAGE_SIZE)
HALT(OUT_OF_STORAGE_INDEX, pc);
putchar(cpu.STORAGE[arg == -1 ? cpu.CURR_POS : arg]);
}
void op_store_cache(int arg, int *pc, int code[])
{
if (cache.cache_size + arg > BASE_MEM_SIZE)
HALT(OUT_OF_CACHE_SIZE, pc);
cache.cache_start[cache.cache_len] = cache.cache_pos ^ 0;
cache.cache_data_len[cache.cache_len] = arg;
for (int i = 0; i < arg; i++)
{
cache.cache_size++;
cache.cache[cache.cache_pos++] = code[(*pc)++] ^ VM_KEY;
}
cache.cache_len++;
}
void op_dec_cache(int arg, int *pc, int code[])
{
if (arg >= cache.cache_len)
HALT(OUT_OF_CACHE_INDEX, pc);
for (int i = cache.cache_start[arg]; i < cache.cache_start[arg] + cache.cache_data_len[arg]; i++)
{
cache.cache[i] = cache.cache[i] ^ VM_KEY;
}
}
void op_cache_len(int arg, int *pc, int code[])
{
cpu.STORAGE[cpu.CURR_POS] = cache.cache_len;
}
void op_cache_len_id(int arg, int *pc, int code[])
{
if (arg >= cache.cache_len)
HALT(OUT_OF_CACHE_INDEX, pc);
cpu.STORAGE[cpu.CURR_POS] = cache.cache_data_len[arg];
}
void op_cache_start(int arg, int *pc, int code[])
{
if (arg >= cache.cache_len)
HALT(OUT_OF_CACHE_INDEX, pc);
cpu.STORAGE[cpu.CURR_POS] = cache.cache_start[arg];
}
void op_cache_get(int arg, int *pc, int code[])
{
cpu.STORAGE[arg] = cache.cache[cpu.STORAGE[cpu.CURR_POS]];
}
void op_jmp_p(int arg, int *pc, int code[])
{
*pc = *pc + arg;
}
void op_jnz_p(int arg, int *pc, int code[])
{
if (cpu.STORAGE[cpu.CURR_POS])
{
*pc = *pc + arg;
}
}
void op_jz_p(int arg, int *pc, int code[])
{
if (!cpu.STORAGE[cpu.CURR_POS])
{
*pc = *pc + arg;
}
}
void op_je_p(int arg, int *pc, int code[])
{
if (cpu.STORAGE[cpu.CURR_POS] == cpu.STORAGE[arg])
{
*pc = *pc + code[(*pc)];
}
*pc += 1;
}
void op_int3(int arg, int *pc, int code[])
{
printf("");
}
示例输出:
[0] OP_INIT 0
[2] OP_SEL 0
[4] OP_ADD 5
[6] OP_NOP_N 3
[11] OP_IMUL 20
[13] OP_SUB 13
[15] OP_ADD_REG 1
[17] OP_SEL 1
[19] OP_ADD 14
[21] OP_IMUL 52
[23] OP_BIT_MOV -2
[25] OP_SEL 0
[27] OP_MUL_REG 1
[29] OP_BIT_MOV 2
[31] OP_IMUL 2
[33] OP_JZ 2
[35] OP_NOP 16716472
[37] OP_NOP_N 3
[42] OP_STORE_CACHE 26
[70] OP_STORE_CACHE 26
[98] OP_NOP 16778240
[100] OP_SUB 12032
[102] OP_SEL 1
[104] OP_ADD_REG 0
[106] OP_IMUL 447
[108] OP_BIT_MOV 5
[110] OP_SEL 2
[112] OP_ADD_REG 0
[114] OP_ADD 4017
[116] OP_XOR 1312
[118] OP_IMUL 15
[120] OP_ADD_REG 0
[122] OP_ADD 17344
[124] OP_SEL 1
[126] OP_BIT_MOV 6
[128] OP_ADD 1034
[130] OP_ADD_REG 2
[132] OP_SEL 2
[134] OP_SEL 0
[136] OP_ADD -126
[138] OP_SEL 3
[140] OP_MOV 0
[142] OP_CACHE_LEN_ID 1
[144] OP_SEL 4
[146] OP_CACHE_START 1
[148] OP_SEL 5
[150] OP_ADD_REG 3
[152] OP_ADD_REG 4
[154] OP_SEL 4
[156] OP_INT3 0
[158] OP_CACHE_GET 6
[160] OP_PRINT 6
a[162] OP_INC 0
[164] OP_JE_P 5
[167] OP_JMP_P -11
[158] OP_CACHE_GET 6
[160] OP_PRINT 6
b[162] OP_INC 0
[164] OP_JE_P 5
[167] OP_JMP_P -11
[158] OP_CACHE_GET 6
[160] OP_PRINT 6
c[162] OP_INC 0
[164] OP_JE_P 5
[167] OP_JMP_P -11
[158] OP_CACHE_GET 6
[160] OP_PRINT 6
d[162] OP_INC 0
[164] OP_JE_P 5
[167] OP_JMP_P -11
[158] OP_CACHE_GET 6
[160] OP_PRINT 6
e[162] OP_INC 0
[164] OP_JE_P 5
[167] OP_JMP_P -11
[158] OP_CACHE_GET 6
[160] OP_PRINT 6
f[162] OP_INC 0
[164] OP_JE_P 5
[167] OP_JMP_P -11
[158] OP_CACHE_GET 6
[160] OP_PRINT 6
g[162] OP_INC 0
[164] OP_JE_P 5
[167] OP_JMP_P -11
[158] OP_CACHE_GET 6
[160] OP_PRINT 6
h[162] OP_INC 0
[164] OP_JE_P 5
[167] OP_JMP_P -11
[158] OP_CACHE_GET 6
[160] OP_PRINT 6
i[162] OP_INC 0
[164] OP_JE_P 5
[167] OP_JMP_P -11
[158] OP_CACHE_GET 6
[160] OP_PRINT 6
j[162] OP_INC 0
[164] OP_JE_P 5
[167] OP_JMP_P -11
[158] OP_CACHE_GET 6
[160] OP_PRINT 6
k[162] OP_INC 0
[164] OP_JE_P 5
[167] OP_JMP_P -11
[158] OP_CACHE_GET 6
[160] OP_PRINT 6
l[162] OP_INC 0
[164] OP_JE_P 5
[167] OP_JMP_P -11
[158] OP_CACHE_GET 6
[160] OP_PRINT 6
m[162] OP_INC 0
[164] OP_JE_P 5
[167] OP_JMP_P -11
[158] OP_CACHE_GET 6
[160] OP_PRINT 6
n[162] OP_INC 0
[164] OP_JE_P 5
[167] OP_JMP_P -11
[158] OP_CACHE_GET 6
[160] OP_PRINT 6
o[162] OP_INC 0
[164] OP_JE_P 5
[167] OP_JMP_P -11
[158] OP_CACHE_GET 6
[160] OP_PRINT 6
p[162] OP_INC 0
[164] OP_JE_P 5
[167] OP_JMP_P -11
[158] OP_CACHE_GET 6
[160] OP_PRINT 6
q[162] OP_INC 0
[164] OP_JE_P 5
[167] OP_JMP_P -11
[158] OP_CACHE_GET 6
[160] OP_PRINT 6
r[162] OP_INC 0
[164] OP_JE_P 5
[167] OP_JMP_P -11
[158] OP_CACHE_GET 6
[160] OP_PRINT 6
s[162] OP_INC 0
[164] OP_JE_P 5
[167] OP_JMP_P -11
[158] OP_CACHE_GET 6
[160] OP_PRINT 6
t[162] OP_INC 0
[164] OP_JE_P 5
[167] OP_JMP_P -11
[158] OP_CACHE_GET 6
[160] OP_PRINT 6
u[162] OP_INC 0
[164] OP_JE_P 5
[167] OP_JMP_P -11
[158] OP_CACHE_GET 6
[160] OP_PRINT 6
v[162] OP_INC 0
[164] OP_JE_P 5
[167] OP_JMP_P -11
[158] OP_CACHE_GET 6
[160] OP_PRINT 6
w[162] OP_INC 0
[164] OP_JE_P 5
[167] OP_JMP_P -11
[158] OP_CACHE_GET 6
[160] OP_PRINT 6
x[162] OP_INC 0
[164] OP_JE_P 5
[167] OP_JMP_P -11
[158] OP_CACHE_GET 6
[160] OP_PRINT 6
y[162] OP_INC 0
[164] OP_JE_P 5
[167] OP_JMP_P -11
[158] OP_CACHE_GET 6
[160] OP_PRINT 6
z[162] OP_INC 0
[164] OP_JE_P 5
[169] OP_MOV 10
[171] OP_PRINT -1
[173] DBG_CPU 1
==================================STORAGE================================
=R= 0 : 114514 =R= 1 : 1919810 =R= 2 : 1893119 =R= 3 : 26 =R= 4 : 10 =R= 5 : 52 =R= 6 : 122
=R= 7 : 0 =R= 8 : 0 =R= 9 : 0 =R=10 : 0 =R=11 : 0 =R=12 : 0
=R=13 : 0 =R=14 : 0 =R=15 : 0
==================================STACK==================================
=S= 0 : 0 =S= 1 : 0 =S= 2 : 0 =S= 3 : 0 =S= 4 : 0 =S= 5 : 0 =S= 6 : 0
=S= 7 : 0 =S= 8 : 0 =S= 9 : 0 =S=10 : 0 =S=11 : 0 =S=12 : 0
=S=13 : 0 =S=14 : 0 =S=15 : 0
=========================================================================
[175] OP_END 0


评论 0
还没有评论,来说点什么吧。