Enviado em 18/02/2016 - 20:08h
Olá !!!OP_HALT OP_NOP OP_PUSH_LONG OP_PUSH_FLOAT OP_PUSH_VAR OP_SET_VAR OP_INC OP_PRINT
/* **------------------------------------------------------------------- ** ** Simples VM: ** ** COMPILE: ** gcc vm.c -o vm -O2 -Wall ** ou ** g++ vm.c -o vm -O2 -Wall ** **------------------------------------------------------------------- */ #include <stdio.h> #include <stdlib.h> #define NEXT goto *(++vm->ip)->jmp #define GTABLE_SIZE 255 #define GVAR_SIZE 255 #define STACK_SIZE 1024 typedef struct VM VM; typedef union VALUE VALUE; typedef struct VAR VAR; typedef struct OPCODE OPCODE; typedef struct LABEL LABEL; struct VM { OPCODE *ip; OPCODE *code; LABEL *label; int pos; }; union VALUE { long l; float f; char *s; void *p; }; struct VAR { char *name; int type; VALUE value; }; struct OPCODE { void *jmp; VALUE arg; // argumento 1 }; struct LABEL { char *text; int pos; LABEL *next; }; enum { // opcodes: OP_HALT = 0, // para sair da VM OP_NOP, // no opcode OP_PUSH_LONG, // da um "push" ... e seta o topo da pilha ( *sp ) com um valor long OP_PUSH_FLOAT, // da um "push" ... e seta o topo da pilha ( *sp ) com um valor float OP_PUSH_VAR, // da um "push" ... e seta o topo da pilha ( *sp ) com uma variavel //------------------------------------------- // OBS: Essa instrucao utiliza 2 argumentos: // 1: short = o index de Gvar [ ] // 2: long = o valor da variavel //------------------------------------------- OP_SET_VAR, // seta um valor de uma variavel ... somente tipo long OP_INC, // incrementa uma variavel ( Gvar[] ) OP_PRINT // imprime o valor de uma variavel }; void *Gtable [ GTABLE_SIZE ]; VAR Gvar [ GVAR_SIZE ]; VALUE stack [ STACK_SIZE ]; // a pilha base VALUE *sp; // o topo da pilha int flag_long; float flag_float; void vm_run (VM *vm) { if (Gtable[0] == NULL) { Gtable [ OP_HALT ] = && op_halt; Gtable [ OP_NOP ] = && op_nop; Gtable [ OP_PUSH_LONG ] = && op_push_long; Gtable [ OP_PUSH_FLOAT ] = && op_push_float; Gtable [ OP_PUSH_VAR ] = && op_push_var; Gtable [ OP_SET_VAR ] = && op_set_var; Gtable [ OP_INC ] = && op_inc; Gtable [ OP_PRINT ] = && op_print; sp = stack; return; } if (!vm) return; vm->ip = vm->code; goto *vm->ip->jmp; // pula para a primeira "inctrucao" //--------------------------------------------- //########## OPCODES implementacao ########## //--------------------------------------------- // op_halt: printf ("Instrucao OP_HALT ... saindo da VM\n"); return; op_nop: // sem opcode ... NEXT; op_push_long: { sp++; sp->l = vm->ip->arg.l; } NEXT; op_push_float: { sp++; sp->f = vm->ip->arg.f; } NEXT; op_push_var: { sp++; // somente tipo long por enquanto sp->l = Gvar [ vm->ip->arg.l ].value.l; } NEXT; op_set_var: { // somente tipo long por enquanto Gvar [ *(short*)vm->ip->arg.s ].value.l = *(long*)(vm->ip->arg.s+2); } NEXT; op_inc: { // somente tipo long por enquanto Gvar [ vm->ip->arg.l ].value.l++; } NEXT; op_print: { // somente tipo long por enquanto printf ("Gvar[ %ld ] = %ld\n", vm->ip->arg.l, Gvar [ vm->ip->arg.l ].value.l); } NEXT; } VM *vm_new (int size) { VM *vm = (VM*) malloc (sizeof(VM)); if (vm) { if ( (vm->code = (OPCODE*) malloc (sizeof(OPCODE)*size)) == NULL) return NULL; vm->ip = vm->code; vm->label = NULL; vm->pos = 0; } return vm; } //------------------------------------------------------------------- //########################### gen/emit ############################ //------------------------------------------------------------------- // void g_halt (VM *vm) { vm->code[vm->pos++].jmp = Gtable [ OP_HALT ]; } void g_nop (VM *vm) { vm->code[vm->pos++].jmp = Gtable [ OP_NOP ]; } void g_set_var (VM *vm, short index, long value) { vm->code[vm->pos].jmp = Gtable [ OP_SET_VAR ]; vm->code[vm->pos].arg.s = (char*)malloc ((sizeof(short)+sizeof(long))+1); *(short*)(vm->code[vm->pos].arg.s) = index; *(long*)(vm->code[vm->pos].arg.s+2) = value; vm->pos++; } void g_inc (VM *vm, int index) { vm->code[vm->pos].jmp = Gtable [ OP_INC ]; vm->code[vm->pos].arg.l = index; vm->pos++; } void g_print (VM *vm, int index) { vm->code[vm->pos].jmp = Gtable [ OP_PRINT ]; vm->code[vm->pos].arg.l = index; vm->pos++; } int main (int argc, char *argv[]) { VM *vm; //----------------------------------------- // cria uma VM com maximo de 100 instrucoes //----------------------------------------- // if ((vm = vm_new(100)) != NULL) { vm_run (NULL); // setup Gtable [ ] //------------------------- //******* gen/emit ******* //------------------------- // g_set_var (vm, 10, 1500); // seta ( Gvar[10].arg.l ) com o valor 1500 g_inc (vm, 10); // incrementa ( Gvar[10].arg.l ) g_print (vm, 10); // imprime ( Gvar[10].arg.l ) ... 1501 g_halt (vm); // o OPCODE mais importante para sair da VM vm_run (vm); // agora executa a VM // aqui: falta liberar memoria ... fica para a proxima // ... } printf ("Saindo Com Sucesso !!!\n"); return 0; }
Enviado em 19/02/2016 - 20:29h
Criar entrada (menuentry) ISO no Grub
Como gerar qualquer emoji ou símbolo unicode a partir do seu teclado
Instalar o VIM 9.1 no Debian 12
Como saber o range de um IP público?
Muitas dificuldades ao instalar distro Linux em Notebook Sony Vaio PCG-6131L (VPCEA24FM)
Slackpkg+ (Slackpkg Plus) está de volta!
Como dividir duas janelas igualmente e lado-a-lado na sua tela
instalar o Linux em computadores Acer novos (2)
compilação samba 4.22 rock linux 9.5 (4)