Beispiel #1
0
static unsigned disassemble(unsigned seg, unsigned off, int count)
{
    char buffer1[80];
    char buffer2[80];
    char buffer3[3];
    unsigned newoff;

    for (; !debug_abort && count > 0; count--)
    {
        do
        {
            printf("%04X:%04X ", seg, off);
            buffer1[0] = '\0';
            newoff = disasm(seg, off, buffer1);
            buffer2[0] = '\0';
            for (; off < newoff; off++)
            {
                sprintf(buffer3,"%02X", GetMemB(&memory[seg << 4], off));
                strcat(buffer2,buffer3);
            }
            printf("%-14s%s\n", buffer2,buffer1);
        } while (disasm_table[instruction_byte].flags & DF_PREFIX);
    }
    return off;
}
Beispiel #2
0
void elf_disasm_x86_64(Elf64_Ehdr *ehdr, Elf64_Shdr *shdr, char *str_table, uint8_t *data)
{
    uint32_t offset = get_section_offset_64(ehdr, shdr, str_table, ".text");
    size_t size = get_section_size_64(ehdr, shdr, str_table, ".text");

    disasm(ehdr->e_entry, offset, size, CS_ARCH_X86, CS_MODE_64, data);
}
Beispiel #3
0
void OfflineX86Code::printDisasm(TCA startAddr, uint32_t len,
                                 const vector<TransBCMapping>& bcMap,
                                 const PerfEventsMap<TCA>& perfEvents) {
  TCRegion tcr = findTCRegionContaining(startAddr);
  disasm(tcRegions[tcr].file, tcRegions[tcr].baseAddr, startAddr, len,
         perfEvents, BCMappingInfo(tcr, bcMap));
}
Beispiel #4
0
/*
 * main -- standard C main program.
 */
int main(int argc, char **argv)
{
    int i;

    /* Parse command line arguments */
    i = 1;
    while((i<argc) && (argv[i][0]=='-'))
    {
        if(!strcmp(argv[i], "--")) { i++; break; }
        else if(!strcmp(argv[i], "-v")) verbose = 1;
        else if(!strcmp(argv[i], "-h")) usage();
        else usage();
        i++;
    }
    if(i != argc-1) usage();
    file = argv[i];

    /* Engage the simulator! */
    parsefile(file);
    if(verbose)
    {
        printf("Disassembly of code area at program start:\n");
        disasm(mem, codeoff, codesize);
        printf("\n");
        printf("Running program:\n");
    }
    simulate();
    if(verbose)
    {
        printf("\n");
        printf("Data area symbols at program halt:\n");
        printsymtab();
    }
    return(0);
}
Beispiel #5
0
int main(int, char*[]) {
    std::vector<ui16> program {{
        0x7c01, 0x0030, 0x7fc1, 0x0020, 0x1000, 0x7803, 0x1000, 0xc413,
        0x7f81, 0x0019, 0xacc1, 0x7c01, 0x2000, 0x22c1, 0x2000, 0x88c3,
        0x84d3, 0xbb81, 0x9461, 0x7c20, 0x0017, 0x7f81, 0x0019, 0x946f,
        0x6381, 0xeb81
    }};

    TDisasembler disasm(program);
    disasm.Process();
    disasm.Save(&std::cout);

#if 0
    NDCPU::TEmulator emulator(program);
    NDCPU::TDebugViewer view(&emulator);

    // dump initial state
    view.Dump();

    for (size_t i = 0; i < 4; ++i) {
        emulator.Step();
        view.Dump();
    }
#endif

    return 0;
}
Beispiel #6
0
void AutoDisassembly(u16 start_addr, u16 end_addr)
{
	AssemblerSettings settings;
	settings.show_pc = true;
	settings.show_hex = true;
	DSPDisassembler disasm(settings);

	u16 addr = start_addr;
	const u16 *ptr = (start_addr >> 15) ? g_dsp.irom : g_dsp.iram;
	while (addr < end_addr)
	{
		line_to_addr[line_counter] = addr;
		addr_to_line[addr] = line_counter;

		std::string buf;
		if (!disasm.DisassembleOpcode(ptr, 0, 2, &addr, buf))
		{
			ERROR_LOG(DSPLLE, "disasm failed at %04x", addr);
			break;
		}

		//NOTICE_LOG(DSPLLE, "Added %04x %i %s", addr, line_counter, buf.c_str());
		lines.push_back(buf);
		line_counter++;
	}
}
Beispiel #7
0
void elf_disasm_arm32(Elf32_Ehdr *ehdr, Elf32_Shdr *shdr, char *str_table, uint8_t *data)
{
    uint32_t offset = get_section_offset_32(ehdr, shdr, str_table, ".text");
    size_t size = get_section_size_32(ehdr, shdr, str_table, ".text");

    disasm(ehdr->e_entry, offset, size, CS_ARCH_ARM, CS_MODE_ARM, data);
}
void dumpCpuState()
{
  char buf[1024];
  static long long prev_cycle_clock = 0;
  long long diff_cycle_clock = cycle_clock - prev_cycle_clock;
  prev_cycle_clock = cycle_clock;
  printf("cpu state: Cycle=%Ld (%+Ld) A=%02x X=%02x Y=%02x S=%02x P=%02x PC=%04x ii=%x\n", cycle_clock, diff_cycle_clock, A, X, Y, S, P, emPC, inside_interrupt );
  disasm (buf, emPC, 10, 0);
  printf("%04x %s\n", emPC, buf);
}
Beispiel #9
0
void test() {
  funptr f = (funptr) gen->cp;

  printf("hello = %p  &hello = %p  size = %d\n", hello, &hello, (int)sizeof(&hello));

  CALL(gen, (funptr)hello );
  RET(gen);

  disasm(gen);

  printf("Execute...\n");
  printf( "f() returned: %ld\n", f() );  // should say 123
}
Beispiel #10
0
void record_cpu_cycle() {
    record_t record;

    record.pc = PC;
    last_recorded_pc = PC;

    records[records_cursor] = record;

    records_cursor++;
    records_cursor %= RECORDS_BUFFER_SIZE;

    records_count++;

    if (current_block) {
        if (PC > current_block->end || PC < current_block->begin) {
            current_block = NULL;
        }
    }

    if(!current_block) {
        u16 pc = PC;

        int index = block_index(pc);
        if (index > 0) {
            current_block = &blocks[index];
            //printf("Entered block %i\n", index);
        }
        else {
            current_block = &blocks[block_cursor];
            current_block->begin = pc;

            block_cursor++;
            block_cursor %= BLOCK_BUFFER_SIZE;

            //printf("Entered block %i\n", block_cursor);

            for (;;) {
                op_t op = disasm(pc);

                if (is_branch(op)) {
                    current_block->end = pc;
                    break;
                }

                assert (pc + op_length(op) <= 0xFFFF);

                pc += op_length(op);
            }
        }
    }
}
Beispiel #11
0
static PyObject *
disnasm_disassemble(PyObject *self, PyObject *args)
{
	char mnemonic[MAX_MNEMONIC];
	const char *data;
	long datalen, len, bits;

	if(!PyArg_ParseTuple(args, "s#I", &data, &datalen, &bits))
		return NULL;
	
	len = disasm(data, mnemonic, MAX_MNEMONIC, bits, 0, 0, 0);

	return Py_BuildValue("ls", len, mnemonic);
}
Beispiel #12
0
int main(int argc, char **argv)
{
	char *buffer; 
	long num ; 
	if (argc > 1)
	{
		if (strlen(argv[1]) < 255)
		{
			buffer = read_file(argv[1], &num) ;
			disasm(buffer, num) ;
		}
	}
	return 0 ;
}
Beispiel #13
0
void cg_disasm_window::ShowDisasm()
{
	if (QFileInfo(m_path_last).isFile())
	{
		CgBinaryDisasm disasm(sstr(m_path_last));
		disasm.BuildShaderBody();
		m_disasm_text->setText(qstr(disasm.GetArbShader()));
		m_glsl_text->setText(qstr(disasm.GetGlslShader()));
	}
	else if (!m_path_last.isEmpty())
	{
		LOG_ERROR(LOADER, "CgDisasm: Failed to open %s", sstr(m_path_last));
	}
}
Beispiel #14
0
int oplen ( BYTE *opcode )
{
	disasm_struct	diza;
	memset( &diza, 0, sizeof(diza) );

	disasm( (BYTE *)opcode, &diza );

	if ( (diza.disasm_flag == C_ERROR)
	 ||	 ((diza.disasm_flag & C_STOP) == C_STOP)
	 ||	 ((diza.disasm_flag & C_REL) == C_REL)
	 ||	 ((diza.disasm_flag & C_BAD) == C_BAD) ) return -1;

	return diza.disasm_len;
}
Beispiel #15
0
char *Disassembler::Proper(word32 v, int &len)
{
    char unasm_buf[1000];
    word8 buf[20];
    char *p;

    read_child(v, buf, 20);
    len = disasm(buf, unasm_buf, 32, v, 0, 0);
    ubufp = ubuf;
    p = unasm_buf;
    while(*p)
	uputchar(*p++);
    return ubuf;
}
Beispiel #16
0
/*
 * Wrapper to call LLVMDisasmInstruction().
 */
__private_extern__
size_t
llvm_disasm_instruction(
LLVMDisasmContextRef DC,
uint8_t *Bytes,
uint64_t BytesSize,
uint64_t Pc,
char *OutString,
size_t OutStringSize)
{

	if(disasm == NULL)
	    return(0);
	return(disasm(DC, Bytes, BytesSize, Pc, OutString, OutStringSize));
}
Beispiel #17
0
void CompiledMethod::print_code_on(Stream* st, jint start, jint end) {
  // Warning this is not safe for garbage collection
  address pc = entry() + start;
  while (*pc != 0x00 && pc < entry() + end) {
    DisassemblerEnv env(this);
    address instruction_start = pc;
    st->print(" %4d: ", instruction_start - entry());
    pc = disasm(instruction_start, &env);
    st->print("%s", env.buffer());
    if (env.has_comment()) { 
      st->print("  // ");
      env.print_comment(st);
    }
    st->cr();
  }
}
Beispiel #18
0
BOOL
PrintOneInstruction(
    HANDLE  hProcess,
    ULONG   Address
    )
{
    CHAR    DisBuf[512];


    if (disasm( hProcess, &Address, DisBuf, TRUE )) {
        printf( "%s\n", DisBuf );
    } else {
        printf( "*** error in disassembly\n" );
    }

    return TRUE;
}
Beispiel #19
0
int main(int argc, char *argv[])
{
	smn8_rom rom;
	const char *filename;
	FILE *fp;
	int ret;

	if(argc > 1)
	{
		if(*argv[1] == '-')
			return print_version_or_usage((const char **) argv);

		filename = argv[1];
	}
	else
	{
#ifdef __EMSCRIPTEN__
		filename = "roms/TETRIS";
#else
		filename = NULL;
#endif
	}

	if(filename != NULL)
	{
		fp = fopen(filename, "rb");

		if(fp == NULL)
		{
			fprintf(stderr, "Could not open ROM '%s'.\n", filename);
			return EXIT_FAILURE;
		}
	}
	else
	{
		fp = stdin;
	}

	ret = smn8_rom_load(&rom, fp) ? disasm(&rom) : EXIT_FAILURE;

	if(argc > 1 && fp != NULL)
		fclose(fp);

	return ret;
}
Beispiel #20
0
bool Disassemble(const std::vector<u16> &code, bool line_numbers, std::string &text)
{
	if (code.empty())
		return false;

	AssemblerSettings settings;

	// These two prevent roundtripping.
	settings.show_hex = true;
	settings.show_pc = line_numbers;
	settings.ext_separator = '\'';
	settings.decode_names = true;
	settings.decode_registers = true;

	DSPDisassembler disasm(settings);
	bool success = disasm.Disassemble(0, code, 0x0000, text);
	return success;
}
Beispiel #21
0
void
step(Mach *m)
{
	Word inst;
	Inst ip;

	disasm(&ip, m, m->pc);
	if (m->halt)
		return;

	if (ip.mode & AMEM)
		m->sym[ip.addr] = 0xffffffff;

	/* printf("%04x %s", m->pc, ip.str); */
	inst = memread(m, m->pc++);
	if (exec(m, inst))
		m->halt |= 0x1;
}
Beispiel #22
0
int compile_test() {
  funptr f = (funptr) gen->cp;

  printf("Compiling...\n");
  d1(gen, 0xB8);	// MOV EAX, 1234
  d1(gen, 0xD2);
  d1(gen, 0x04);
  d1(gen, 0x00);
  d1(gen, 0x00);
  d1(gen, 0xB8);	// MOV EAX, 0x12345678
  d4(gen, 0x12345678);
  d1(gen, 0xC3);	// RET

  disasm(gen);

  printf("Execute...\n");
  printf( "f() returned: %ld\n", f() );  // should say 305419896
  return 0;
}
Beispiel #23
0
void
do_disasm64(void *input, uint32_t size, uint64_t offset)
{
    int32_t lendis;
    char *p = (char *)input, *end = (char *)input + size;
    char outbuf[256];

    while (p < end)
    {
        lendis = disasm((uint8_t *) p, outbuf, sizeof(outbuf), 64,
                        offset, false, 0);

        if (!lendis || p + lendis > end)
            lendis = eatbyte((uint8_t *) p, outbuf, sizeof(outbuf), 64);

        output_ins64(offset, (uint8_t *) p, lendis, outbuf);

        p += lendis;
        offset += lendis;
    }
}
Beispiel #24
0
int main(int argc, char* argv[]) {
	const char* program = argv[0];
	if (argc >= 2) {
		int i = 1;
		bool verbose = false;
		if (strcmp(argv[1], "-v") == 0) { verbose = true; i ++; }
		if (argc > i) { 
			const char* filename = argv[i];
			File file(filename);
			if (file.InitCheck()) {
				Disasm disasm(&file);
				disasm.SetVerbose(verbose);
				disasm.Print();
				return 0;
			} else {
				fprintf(stderr, "%s error: could not open file '%s'\n", program, filename);
				return 0;
			}
		}
	}
	fprintf(stderr, "%s [-v] pcl6_filename\n", program);
}
Beispiel #25
0
bool DumpDSPCode(const u8 *code_be, int size_in_bytes, u32 crc)
{
	char binFile[MAX_PATH];
	char txtFile[MAX_PATH];
	sprintf(binFile, "%sDSP_UC_%08X.bin", File::GetUserPath(D_DUMPDSP_IDX).c_str(), crc);
	sprintf(txtFile, "%sDSP_UC_%08X.txt", File::GetUserPath(D_DUMPDSP_IDX).c_str(), crc);

	File::IOFile pFile(binFile, "wb");
	if (pFile)
	{
		pFile.WriteBytes(code_be, size_in_bytes);
		pFile.Close();
	}
	else
	{
		PanicAlert("Cant open file (%s) to dump UCode!!", binFile);
		return false;
	}

	// Load the binary back in.
	std::vector<u16> code;
	LoadBinary(binFile, code);

	AssemblerSettings settings;
	settings.show_hex = true;
	settings.show_pc = true;
	settings.ext_separator = '\'';
	settings.decode_names = true;
	settings.decode_registers = true;

	std::string text;
	DSPDisassembler disasm(settings);

	if (!disasm.Disassemble(0, code, 0x0000, text))
		return false;

	return File::WriteStringToFile(true, text, txtFile);
}
Beispiel #26
0
BOOL
CmdDisplayCode(
    LPSTR             CmdBuf,
    HANDLE            hProcess,
    HANDLE            hThread,
    PEXCEPTION_RECORD ExceptionRecord
    )
{
    static ULONG Address = 0;
    ULONG   ThisAddress;
    CHAR    DisBuf[512];
    ULONG   i;


    //
    // skip any command modifiers & white space that may follow
    //
    SKIP_NONWHITE( CmdBuf );
    SKIP_WHITE( CmdBuf );

    GetAddress( CmdBuf, &ThisAddress );
    if (ThisAddress) {
        Address = ThisAddress;
    }

    printf( "\n" );

    for (i=0; i<20; i++) {
        if (!disasm( hProcess, &Address, DisBuf, TRUE )) {
            break;
        }
        printf( "%s\n", DisBuf );
    }

    printf( "\n" );

    return TRUE;
}
Beispiel #27
0
Value SuFunction::call(Value self, Value member, short nargs, short nargnames,
	short* argnames, int each) {
	static Value Disasm("Disasm");
	static Value Source("Source");

	if (member == CALL) {
		args(nargs, nargnames, argnames, each);

		if (flags)
			dotParams(self);

		Framer frame(this, self);
		return tls().proc->fp->run();
	} else if (member == Disasm) {
		NOARGS("function.Disasm()");
		OstreamStr oss;
		disasm(oss);
		return new SuString(oss.str());
	} else if (member == Source) {
		return new SuString(src);
	} else
		return Func::call(self, member, nargs, nargnames, argnames, each);
}
Beispiel #28
0
int step(int flag, Emulator *emul)
{
	int r = 0;
	word in = get_word(emul->reg[15], emul->map);
	Instruction *out = init_ins();




	
	r = disasm(in, out, emul); // retourne l'offset (2 : instruction 16 bits, 4 : 32 bits)

	if (r == 3)
		return r;

	else if (r == 2 || r == 4)
	{
		printf("\n");
		if(out->run != NULL)
		{
			out->run(*out, emul);
			printf("\033[00;32m");
		}
		else
		{
			printf("\033[00;31m");
		}
		if( breakpoint_exist( emul->breaklist, emul->reg[15] ) )
			display(*out, DECODED, emul);
		printf("\033[0m");
	}
	
	emul->reg[15] += r;
	
	return r;
}
Beispiel #29
0
__declspec(dllexport) DWORD DoRspCycles ( DWORD Cycles )
{
    OSTask_t *task = (OSTask_t*)(rsp.DMEM + 0xFC0);
    unsigned int i, sum=0;
#ifdef __WIN32__
    if(firstTime)
    {
        firstTime=FALSE;
        if (SpecificHle)
            loadPlugin();
    }
#endif

    if( task->type == 1 && task->data_ptr != 0 && GraphicsHle) {
        if (rsp.ProcessDlistList != NULL) {
            rsp.ProcessDlistList();
        }
        *rsp.SP_STATUS_REG |= 0x0203;
        if ((*rsp.SP_STATUS_REG & 0x40) != 0 ) {
            *rsp.MI_INTR_REG |= 0x1;
            rsp.CheckInterrupts();
        }

        *rsp.DPC_STATUS_REG &= ~0x0002;
        return Cycles;
    } else if (task->type == 2 && AudioHle) {
#ifdef __WIN32__
        if (SpecificHle)
            processAList();
        else
#endif
            if (rsp.ProcessAlistList != NULL) {
                rsp.ProcessAlistList();
            }
        *rsp.SP_STATUS_REG |= 0x0203;
        if ((*rsp.SP_STATUS_REG & 0x40) != 0 ) {
            *rsp.MI_INTR_REG |= 0x1;
            rsp.CheckInterrupts();
        }
        return Cycles;
    } else if (task->type == 7) {
        rsp.ShowCFB();
    }

    *rsp.SP_STATUS_REG |= 0x203;
    if ((*rsp.SP_STATUS_REG & 0x40) != 0 )
    {
        *rsp.MI_INTR_REG |= 0x1;
        rsp.CheckInterrupts();
    }

    if (task->ucode_size <= 0x1000)
        for (i=0; i<(task->ucode_size/2); i++)
            sum += *(rsp.RDRAM + task->ucode + i);
    else
        for (i=0; i<(0x1000/2); i++)
            sum += *(rsp.IMEM + i);


    if (task->ucode_size > 0x1000)
    {
        switch(sum)
        {
        case 0x9E2: // banjo tooie (U) boot code
        {
            int i,j;
            memcpy(rsp.IMEM + 0x120, rsp.RDRAM + 0x1e8, 0x1e8);
            for (j=0; j<0xfc; j++)
                for (i=0; i<8; i++)
                    *(rsp.RDRAM+((0x2fb1f0+j*0xff0+i)^S8))=*(rsp.IMEM+((0x120+j*8+i)^S8));
        }
        return Cycles;
        break;
        case 0x9F2: // banjo tooie (E) + zelda oot (E) boot code
        {
            int i,j;
            memcpy(rsp.IMEM + 0x120, rsp.RDRAM + 0x1e8, 0x1e8);
            for (j=0; j<0xfc; j++)
                for (i=0; i<8; i++)
                    *(rsp.RDRAM+((0x2fb1f0+j*0xff0+i)^S8))=*(rsp.IMEM+((0x120+j*8+i)^S8));
        }
        return Cycles;
        break;
        }
    }
    else
    {
        switch(task->type)
        {
        case 2: // audio
            if (audio_ucode(task) == 0)
                return Cycles;
            break;
        case 4: // jpeg
            switch(sum)
            {
            case 0x278: // used by zelda during boot
                *rsp.SP_STATUS_REG |= 0x200;
                return Cycles;
                break;
            case 0x2e4fc: // uncompress
                jpg_uncompress(task);
                return Cycles;
                break;
            default:
            {
                char s[1024];
                sprintf(s, "unknown jpeg:\n\tsum:%x", sum);
#ifdef __WIN32__
                MessageBox(NULL, s, "unknown task", MB_OK);
#else
                printf("%s\n", s);
#endif
            }
            }
            break;
        }
    }

    {
        char s[1024];
        FILE *f;
        sprintf(s, "unknown task:\n\ttype:%d\n\tsum:%x\n\tPC:%x", (int)task->type, sum, (int)rsp.SP_PC_REG);
#ifdef __WIN32__
        MessageBox(NULL, s, "unknown task", MB_OK);
#else
        printf("%s\n", s);
#endif

        if (task->ucode_size <= 0x1000)
        {
            f = fopen("imem.dat", "wb");
            fwrite(rsp.RDRAM + task->ucode, task->ucode_size, 1, f);
            fclose(f);

            f = fopen("dmem.dat", "wb");
            fwrite(rsp.RDRAM + task->ucode_data, task->ucode_data_size, 1, f);
            fclose(f);

            f = fopen("disasm.txt", "wb");
            memcpy(rsp.DMEM, rsp.RDRAM+task->ucode_data, task->ucode_data_size);
            memcpy(rsp.IMEM+0x80, rsp.RDRAM+task->ucode, 0xF7F);
            disasm(f, (unsigned int*)(rsp.IMEM));
            fclose(f);
        }
        else
        {
            f = fopen("imem.dat", "wb");
            fwrite(rsp.IMEM, 0x1000, 1, f);
            fclose(f);

            f = fopen("dmem.dat", "wb");
            fwrite(rsp.DMEM, 0x1000, 1, f);
            fclose(f);

            f = fopen("disasm.txt", "wb");
            disasm(f, (unsigned int*)(rsp.IMEM));
            fclose(f);
        }
    }

    return Cycles;
}
Beispiel #30
0
/*
 * simulate -- execute the program one CPU instruction at a time until HALT
 */
void simulate(void)
{
    struct insn *insn;
    size_t reg;
    ssize_t tmp;

    /* Before starting to run the program, establish a stack */
    setreg(FP, memsize ? (memsize-1) : 0); /* initialize frame pointer */
    setreg(SP, memsize); /* initialize stack pointer */
    addmem(64); /* reserve memory for the stack at end of address space */

    /* Each iteration of this loop executes one instruction */
    while(!halted)
    {
        /* Fetch the instruction word */
        ir = getmem(pc);
        if(verbose)
        {
            printf("Executing ");
            disasm(mem, pc, 1);
        }
        pc++;

        /* Decode the instruction word */
        insn = decode(ir);
        reg = insn->reg;

        tmp = (ssize_t)(int16_t)insn->imm;
        if(insn->idxreg) tmp += (ssize_t)getreg(insn->idxreg);
        tr = (size_t)tmp;

        switch(insn->mode)
        {
        case 0: break;
        case 1: tr = getmem(tr); break;
        case 2: tr = getmem(getmem(tr)); break;
        }

        /* Execute the instruction */
        switch(insn->opcode)
        {
        case 0x00: /*NOP*/
            break;
        case 0x01: /*STORE*/
            setmem(tr, getreg(reg)); 
            break;
        case 0x02: /*LOAD*/
            setreg(reg, tr);
            break;
        case 0x03: /*IN*/
            if((tr >= COUNTOF(intab)) || !intab[tr]) die("no such input device");
            setreg(reg, intab[tr]());
            break;
        case 0x04: /*OUT*/
            if((tr >= COUNTOF(outtab)) || !outtab[tr]) die("no such output device");
            outtab[tr](getreg(reg));
            break;
        case 0x11: setreg(reg, getreg(reg) + tr); break; /*ADD*/
        case 0x12: setreg(reg, getreg(reg) - tr); break; /*SUB*/
        case 0x13: setreg(reg, getreg(reg) * tr); break; /*MUL*/
        case 0x14: setreg(reg, getreg(reg) / tr); break; /*DIV*/
        case 0x15: setreg(reg, getreg(reg) % tr); break; /*MOD*/
        case 0x16: setreg(reg, getreg(reg) & tr); break; /*AND*/
        case 0x17: setreg(reg, getreg(reg) | tr); break; /*OR*/
        case 0x18: setreg(reg, getreg(reg) ^ tr); break; /*XOR*/
        case 0x19: setreg(reg, getreg(reg) << tr); break; /*SHL*/
        case 0x1A: setreg(reg, size_shr(getreg(reg), tr)); break; /*SHR*/
        case 0x1B: setreg(reg, size_sar(getreg(reg), tr)); break; /*SHRA*/
        case 0x1F: compare(getreg(reg), tr); break; /*COMP*/
        case 0x20: pc=tr; break; /*JUMP*/
        case 0x21: if((ssize_t)getreg(reg) < 0) pc=tr; break; /*JNEG*/
        case 0x22: if((ssize_t)getreg(reg) == 0) pc=tr; break; /*JZER*/
        case 0x23: if((ssize_t)getreg(reg) > 0) pc=tr; break; /*JPOS*/
        case 0x24: if((ssize_t)getreg(reg) >= 0) pc=tr; break; /*JNNEG*/
        case 0x25: if((ssize_t)getreg(reg) != 0) pc=tr; break; /*JNZER*/
        case 0x26: if((ssize_t)getreg(reg) <= 0) pc=tr; break; /*JNPOS*/
        case 0x27: if(getsrbit(SR_L)) pc=tr; break; /*JLES*/
        case 0x28: if(getsrbit(SR_E)) pc=tr; break; /*JEQU*/
        case 0x29: if(getsrbit(SR_G)) pc=tr; break; /*JGRE*/
        case 0x2A: if(!getsrbit(SR_L)) pc=tr; break; /*JNLES*/
        case 0x2B: if(!getsrbit(SR_E)) pc=tr; break; /*JNEQU*/
        case 0x2C: if(!getsrbit(SR_G)) pc=tr; break; /*JNGRE*/
        case 0x31: /*CALL*/ 
            push(reg, pc);
            push(reg, getreg(FP));
            setreg(FP, getreg(SP));
            pc=tr;
            break;
        case 0x32: /*EXIT*/
            setreg(FP, pop(reg));
            pc = pop(reg);
            for(; tr; tr--) pop(reg);
            break;
        case 0x33: /*PUSH*/
            push(reg, tr);
            break;
        case 0x34: /*POP*/
            setreg(insn->idxreg, pop(reg));
            break;
        case 0x35: /*PUSHR*/
            push(reg, getreg(0));
            push(reg, getreg(1));
            push(reg, getreg(2));
            push(reg, getreg(3));
            push(reg, getreg(4));
            push(reg, getreg(5));
            break;
        case 0x36: /*POPR*/
            setreg(5, pop(reg));
            setreg(4, pop(reg));
            setreg(3, pop(reg));
            setreg(2, pop(reg));
            setreg(1, pop(reg));
            setreg(0, pop(reg));
            break;
        case 0x70: /*SVC*/
            if((tr >= COUNTOF(svctab)) || !svctab[tr]) die("no such supervisor call");
            svctab[tr](reg);
            break;
        default:
            die("bad instruction");
        }
    }
}