enhanced ebc disassembler master
authorMartin Kustermann <kusterm@de.ibm.com>
Tue, 30 Aug 2011 20:11:59 +0000 (22:11 +0200)
committerBernhard Urban <lewurm@gmail.com>
Mon, 19 Sep 2011 07:28:41 +0000 (09:28 +0200)
enhancements:
* get jump/call targets
* print raw data and asm-instructions
* decode indices

todo:
* not all instructions use the index-decoding functionality
* ...

dis-ebc.c

index b96ec15e2cc9420c843cce58d90cbb1124cdfad6..a590972f44cbf110c9a1d747ac1ad9b2eb9c8825 100644 (file)
--- a/dis-ebc.c
+++ b/dis-ebc.c
@@ -6,6 +6,8 @@
 
 #include <stdio.h>
 #include <stdlib.h>
 
 #include <stdio.h>
 #include <stdlib.h>
+#include <stdarg.h>
+#include <stdint.h>
 #include <unistd.h>
 #include <sys/mman.h>
 #include <fcntl.h>
 #include <unistd.h>
 #include <sys/mman.h>
 #include <fcntl.h>
 
 #define PS "%-10s: "
 
 
 #define PS "%-10s: "
 
+
 typedef unsigned char u8;
 typedef unsigned char u8;
-typedef unsigned short u16;
-typedef unsigned int u32;
-typedef unsigned long long u64;
+typedef signed char s8;
+typedef uint16_t u16;
+typedef int16_t s16;
+typedef uint32_t u32;
+typedef int32_t s32;
+typedef uint64_t u64;
+typedef int64_t s64;
+
+
+#define MAX_STRING_LEN 100
+#define MAX_INSTRUCTION_LEN 40
+
+typedef struct _instruction {
+       int offsetInFile;
+       int offsetInCode;
+
+       u8 bytes[MAX_INSTRUCTION_LEN];
+       int bytePos;
+
+       char string[MAX_STRING_LEN];
+       int stringPos;
+
+       int isJump;
+       int jumpAddress;
+
+       int isCall;
+       int callAddress;
+
+       int isCallTarget;
+       int isJumpTarget;
+
+       int callLabel;
+       int jumpLabel;
+
+       struct _instruction *next;
+} instruction;
+
+typedef struct _statistics {
+       int maxInstructionLen;
+} statistics;
+
+static instruction* instruction_new(int offsetInFile, int offsetInCode) {
+       instruction *inst = malloc(sizeof(instruction));
+       assert(inst != NULL);
+
+       memset(inst, 0, sizeof(instruction));
+
+       inst->offsetInFile = offsetInFile;
+       inst->offsetInCode = offsetInCode;
+
+       return inst;
+}
+
+static void instruction_print(instruction *inst, const char *c) {
+       int len = strlen(c);
+       assert((inst->stringPos+len) < MAX_STRING_LEN);
+       for (int i=0; i<len; i++)
+               inst->string[inst->stringPos++] = c[i];
+}
+
+static void instruction_push_byte(instruction *inst, u8 byte) {
+       assert((inst->bytePos+1) < MAX_INSTRUCTION_LEN);
+       inst->bytes[inst->bytePos++] = byte;
+}
+
+static instruction *first_instruction;
+static instruction *current_instruction;
+static int current_call_label=0;
+static int current_jump_label=0;
+static statistics stat;
+static int entry_point;
+
+
+/* 
+ * BEGIN - interface functions
+ */
+static void i_begin(int offsetInFile, int offsetInCode) {
+       if (first_instruction == NULL) {
+               first_instruction = current_instruction = instruction_new(offsetInFile, offsetInCode);
+       } else {
+               assert(current_instruction->next == 0);
+               current_instruction->next = instruction_new(offsetInFile, offsetInCode);
+               current_instruction = current_instruction->next;
+       }
+}
+
+static void i_print(const char *fmt, ...) {
+       assert(current_instruction != NULL);
+
+       va_list args;
+       char str[MAX_STRING_LEN];
+
+       memset(str, 0, MAX_STRING_LEN);
+
+       va_start(args, fmt);
+       vsprintf(str, fmt, args);
+       instruction_print(current_instruction, str);
+       va_end(args);
+}
+
+static u8 i_push(u8 byte) {
+       assert(current_instruction != NULL);
+       instruction_push_byte(current_instruction, byte);
+       return byte;
+}
+
+static void i_set_relative_call(int relAddr) {
+       current_instruction->isCall=1;
+       current_instruction->callAddress = current_instruction->offsetInCode + current_instruction->bytePos + relAddr;
+       /*i_print("[call to 0x%08x] ", current_instruction->callAddress);*/
+}
+
+static void i_set_relative_jmp(int relAddr) {
+       current_instruction->isJump=1;
+       // FIXME: is this correct ?
+       current_instruction->jumpAddress = current_instruction->offsetInCode + current_instruction->bytePos + relAddr;
+       /*current_instruction->jumpAddress = current_instruction->offsetInCode + relAddr;*/
+       /*i_print("[jump to 0x%08x] ", current_instruction->jumpAddress);*/
+}
+
+static int i_get_jump_label(int absoluteCodeOffset) {
+       instruction *i = first_instruction;
+       while (i != NULL) {
+               if (i->offsetInCode == absoluteCodeOffset && i->isJumpTarget) 
+                       return i->jumpLabel;
+               i = i->next;
+       }
+       return -1;
+}
+static int i_get_call_label(int absoluteCodeOffset) {
+       instruction *i = first_instruction;
+       while (i != NULL) {
+               if (i->offsetInCode == absoluteCodeOffset && i->isCallTarget) 
+                       return i->callLabel;
+               i = i->next;
+       }
+       return -1;
+}
+
+static void i_dump() {
+       int k;
+
+       instruction *i = first_instruction;
+       while (i != NULL) {
+               if (i->offsetInCode == entry_point)
+                       printf("\n\nENTRY_POINT:\n");
+               if (i->isCallTarget) 
+                       printf("\n\nfunction%d:\n", i->callLabel);
+               if (i->isJumpTarget) 
+                       printf("label%d: \n", i->jumpLabel);
+
+               printf("\t0x%08x:", i->offsetInCode);
+               for (k=0; k<stat.maxInstructionLen; k++) {
+                       if (k<i->bytePos) 
+                               printf(" %02x", i->bytes[k]);
+                       else
+                               printf("   ");
+               }
+               if (i->isCall) 
+                       printf(" %s [call function%d]\n", i->string, i_get_call_label(i->callAddress));
+               else if (i->isJump)
+                       printf(" %s [jump label%d]\n", i->string, i_get_jump_label(i->jumpAddress));
+               else
+                       printf(" %s\n", i->string);
+               i = i->next;
+       }
+}
+
+static void i_mark_jump_target(int absoluteCodeOffset) {
+       // search in list for address and set isJumpTarget = true
+       instruction *i = first_instruction;
+       while (i != NULL) {
+               if (i->offsetInCode == absoluteCodeOffset) {
+                       i->isJumpTarget++;
+                       return;
+               }
+               i = i->next;
+       }
+       assert(0);
+}
+static void i_mark_call_target(int absoluteCodeOffset) {
+       // search in list for address and set isCallTarget = true
+       instruction *i = first_instruction;
+       while (i != NULL) {
+               if (i->offsetInCode == absoluteCodeOffset) {
+                       i->isCallTarget++;
+                       return;
+               }
+               i = i->next;
+       }
+       assert(0);
+}
+
+static void i_mark_jump_targets() {
+       // search the whole list for jumps and call
+       // i_mark_jump_target() for every of them 
+       instruction *i = first_instruction;
+       while (i != NULL) {
+               if (i->isJump) 
+                       i_mark_jump_target(i->jumpAddress);
+               i = i->next;
+       }
+}
+
+static void i_mark_call_targets() {
+       // search the whole list for calls and call
+       // i_mark_call_target() for every of them 
+       instruction *i = first_instruction;
+       while (i != NULL) {
+               if (i->isCall) 
+                       i_mark_call_target(i->callAddress);
+               i = i->next;
+       }
+}
+
+static void i_enumerate_jump_targets() {
+       instruction *i = first_instruction;
+       while (i != NULL) {
+               if (i->isJumpTarget) 
+                       i->jumpLabel = current_jump_label++;
+               i = i->next;
+       }
+}
+
+static void i_enumerate_call_targets() {
+       instruction *i = first_instruction;
+       while (i != NULL) {
+               if (i->isCallTarget) 
+                       i->callLabel = current_call_label++;
+               i = i->next;
+       }
+}
+
+static void i_make_statistics() {
+       instruction *i = first_instruction;
+       while (i != NULL) {
+               if (i->bytePos > stat.maxInstructionLen) {
+                       stat.maxInstructionLen = i->bytePos;
+               }
+               i = i->next;
+       }
+}
+
+static void i_end() {
+       i_mark_jump_targets();
+       i_mark_call_targets();
+
+       i_enumerate_jump_targets();
+       i_enumerate_call_targets();
+
+       i_make_statistics();
+}
+
+static void i_cleanup() {
+       instruction *current_inst = first_instruction;
+       instruction *next;
+
+       first_instruction = NULL;
+       while (current_inst != NULL) {
+               next = current_inst->next;
+               free(current_inst);
+               current_inst = next;
+       }
+}
+
+/* 
+ * END - interface functions
+ */
 
 static int file_len;
 static u8 *data, *data_start;
 
 static int file_len;
 static u8 *data, *data_start;
@@ -42,32 +310,32 @@ static void print_debug(const char *s)
                data - data_start);
 }
 
                data - data_start);
 }
 
-static void pspace(void) { printf(" "); }
-
-static void pcomma(void) { printf(", "); }
+static void pspace(void) { i_print(" "); }
+static void pcomma(void) { i_print(", "); }
 
 static void preg(u8 reg)
 {
        if (reg > 7) { assert(0); }
 
 static void preg(u8 reg)
 {
        if (reg > 7) { assert(0); }
-       printf("r%1d", reg);
+       i_print("r%1d", reg);
 }
 
 static void pvmreg(u8 reg)
 {
        if (reg > 7) { assert(0); }
 }
 
 static void pvmreg(u8 reg)
 {
        if (reg > 7) { assert(0); }
-       printf("%s", vm_reg[reg]);
+       i_print("%s", vm_reg[reg]);
 }
 
 static void pdref(u8 x)
 {
 }
 
 static void pdref(u8 x)
 {
-       printf("%s", x ? "@" : "");
+       i_print("%s", x ? "@" : "");
 }
 
 #define PIMM_READ(size) \
        static void pimm##size(void) \
        { \
 }
 
 #define PIMM_READ(size) \
        static void pimm##size(void) \
        { \
-               printf(size != 64 ? "%x" : "%llx", *((u##size *) data)); \
-               data += sizeof (u##size); \
+               i_print(size != 64 ? "%x" : "%llx", *((u##size *) data)); \
+               for (int i=0; i<size/8; i++) \
+                       i_push(*data++); \
        }
 
 PIMM_READ(8);
        }
 
 PIMM_READ(8);
@@ -85,20 +353,48 @@ static void pimm(u8 mod)
        }
 }
 
        }
 }
 
+#define PIDX_READ(size) \
+       static void pidx##size(void) \
+       { \
+               u##size d = *((u##size *)data); \
+               u##size sign = (d >> (size-1))&1; \
+               u##size nat_bits = ((d>>(size-4))&0x7) * (size/8);\
+               u##size c_bits = size - nat_bits - 4;\
+               u##size c = (d>>nat_bits)&((1ULL<<c_bits)-1);\
+               u##size n = d & ((1ULL<<nat_bits)-1);\
+               i_print(size != 64 ? "{%c %dn %dc}" : "{%c %lldn %lldc}", sign ? '-' : '+', n, c); \
+               for (int i=0; i<size/8; i++) \
+                       i_push(*data++); \
+       }
+
+PIDX_READ(8);
+PIDX_READ(16);
+PIDX_READ(32);
+PIDX_READ(64);
+static void pidx(u8 mod)
+{
+       switch (mod) {
+       case 1: pidx16(); break;
+       case 2: pidx32(); break;
+       case 3: pidx64(); break;
+       case 0: default: assert(0);
+       }
+}
+
 static void pimmc(u8 imm_type)
 {
        if (imm_type > 5) { assert(0); }
 static void pimmc(u8 imm_type)
 {
        if (imm_type > 5) { assert(0); }
-       printf("%s", imm_chw[imm_type]);
+       i_print("%s", imm_chw[imm_type]);
 }
 
 static void pflags(u8 flag)
 {
        switch (flag) {
 }
 
 static void pflags(u8 flag)
 {
        switch (flag) {
-       case 0x0: printf("eq"); break;
-       case 0x1: printf("lte"); break;
-       case 0x2: printf("gte"); break;
-       case 0x3: printf("ulte"); break;
-       case 0x4: printf("ugte"); break;
+       case 0x0: i_print("eq"); break;
+       case 0x1: i_print("lte"); break;
+       case 0x2: i_print("gte"); break;
+       case 0x3: i_print("ulte"); break;
+       case 0x4: i_print("ugte"); break;
        }
 }
 
        }
 }
 
@@ -114,24 +410,24 @@ static const char *breakopts[] = {
 
 static void pbreak(void)
 {
 
 static void pbreak(void)
 {
-       u8 i = *data++;
+       u8 i = i_push(*data++);
        pspace();
        pspace();
-       if (i > 6) { printf("unknown break!"); assert(0);
-       } else printf("\"%s\"", breakopts[i]);
+       if (i > 6) { fprintf(stderr, "unknown break!"); assert(0);
+       } else i_print("\"%s\"", breakopts[i]);
 }
 
 static void pinsn(void)
 {
 }
 
 static void pinsn(void)
 {
-       u8 insn = *data++;
+       u8 insn = i_push(*data++);
        u8 opc = insn & 0x3f;
 
        switch (opc) {
        u8 opc = insn & 0x3f;
 
        switch (opc) {
-       case 0x00: printf("BREAK"); pbreak(); break;
+       case 0x00: i_print("BREAK"); pbreak(); break;
        case 0x01: case 0x03:{
                        u8 opindex = insn & 0x80;
                        u8 c3264 = insn & 0x40;
 
        case 0x01: case 0x03:{
                        u8 opindex = insn & 0x80;
                        u8 c3264 = insn & 0x40;
 
-                       u8 b1 = *data++;
+                       u8 b1 = i_push(*data++);
                        u8 cond = b1 & 0x80;
                        u8 flag = b1 & 0x40;
                        u8 ebcnative = b1 & 0x20;
                        u8 cond = b1 & 0x80;
                        u8 flag = b1 & 0x40;
                        u8 ebcnative = b1 & 0x20;
@@ -140,43 +436,70 @@ static void pinsn(void)
                        u8 dref1 = b1 & 0x8;
 
                        if (opc == 0x01) {
                        u8 dref1 = b1 & 0x8;
 
                        if (opc == 0x01) {
-                               printf("JMP%d%s", c3264 ? 64 : 32,
+                               i_print("JMP%d%s", c3264 ? 64 : 32,
                                       cond ? (flag ? "cs" : "cc") : "");
                        } else if (opc == 0x03) {
                                       cond ? (flag ? "cs" : "cc") : "");
                        } else if (opc == 0x03) {
-                               printf("CALL%d%s", c3264 ? 64 : 32,
+                               i_print("CALL%d%s", c3264 ? 64 : 32,
                                       ebcnative ? "EX" : "");
                        }
                                       ebcnative ? "EX" : "");
                        }
-                       printf("%s", relabs ? "a" : ""); pspace();
+                       i_print("%s", relabs ? "a" : ""); pspace();
 
                        if (!c3264) {   // 32bit
                                pdref(dref1);
                                preg(op1);
                                if (opindex) {
 
                        if (!c3264) {   // 32bit
                                pdref(dref1);
                                preg(op1);
                                if (opindex) {
-                                       pspace(); pimm32();
+                                       pspace();
+                                       if (op1==0) { // relative/absolute call/jmp
+                                               u32 imm32 = *(u32*)data;
+                                               i_push(*data++);
+                                               i_push(*data++);
+                                               i_push(*data++);
+                                               i_push(*data++);
+                                               if (relabs) { // relative call
+                                                       if (opc == 0x03) 
+                                                               i_set_relative_call(imm32);
+                                                       else
+                                                               i_set_relative_jmp(imm32);
+                                               } else { // absolute call
+                                                       i_print("FIXME %s.%d", __FUNCTION__, __LINE__);
+                                               }
+                                       } else {
+                                               pidx32();
+                                               /*pimm32();*/
+                                       }
                                }
                        } else {        // 64bit
                                pimm64();
                        }
                                }
                        } else {        // 64bit
                                pimm64();
                        }
+                       /*i_print("   msk: offset=%d", (data-startOfInstruction));*/
                }
                break;
        case 0x02:{
                        u8 cond = insn & 0x80;
                        u8 flag = insn & 0x40;
                }
                break;
        case 0x02:{
                        u8 cond = insn & 0x80;
                        u8 flag = insn & 0x40;
-                       printf("JMP8%s", cond ? (flag ? "cs" : "cc") : "");
-                       pspace(); pimm8();
+                       i_print("JMP8%s", cond ? (flag ? "cs" : "cc") : "");
+                       pspace(); 
+                       //pimm8();
+                       int relOffset = 2*((int)(s8)i_push(*data++));
+
+                       i_set_relative_jmp(relOffset);
+            /*
+                        *i_print("   msk-offset=%x", 2*(*data) + (data-startOfInstruction));
+                        *i_print("   msk-offset=%08x", (startOfInstruction-data_start) + 2*(*data) + (data-startOfInstruction));
+             */
                }
                break;
                }
                break;
-       case 0x04: printf("RET"); data++; break;
+       case 0x04: i_print("RET"); i_push(*data++); break;
        case 0x05 ... 0x09:{
                        u8 opindex = insn & 0x80;
                        u8 c3264 = insn & 0x40;
 
        case 0x05 ... 0x09:{
                        u8 opindex = insn & 0x80;
                        u8 c3264 = insn & 0x40;
 
-                       u8 b1 = *data++;
+                       u8 b1 = i_push(*data++);
                        u8 op1 = b1 & 0x7;
                        u8 op2 = (b1 & 0x70) >> 4;
                        u8 dref2 = b1 & 0x80;
 
                        u8 op1 = b1 & 0x7;
                        u8 op2 = (b1 & 0x70) >> 4;
                        u8 dref2 = b1 & 0x80;
 
-                       printf("CMP%d", !c3264 ? 32 : 64);
+                       i_print("CMP%d", !c3264 ? 32 : 64);
                        pflags(opc - 0x05); pspace();
                        preg(op1); pcomma();
                        pdref(dref2); preg(op2);
                        pflags(opc - 0x05); pspace();
                        preg(op1); pcomma();
                        pdref(dref2); preg(op2);
@@ -189,33 +512,33 @@ static void pinsn(void)
                        u8 opindex = insn & 0x80;
                        u8 c3264 = insn & 0x40;
 
                        u8 opindex = insn & 0x80;
                        u8 c3264 = insn & 0x40;
 
-                       u8 b1 = *data++;
+                       u8 b1 = i_push(*data++);
                        u8 op1 = b1 & 0x7;
                        u8 dref1 = b1 & 0x8;
                        u8 op2 = (b1 & 0x70) >> 4;
                        u8 dref2 = b1 & 0x80;
                        switch (opc) {
                        u8 op1 = b1 & 0x7;
                        u8 dref1 = b1 & 0x8;
                        u8 op2 = (b1 & 0x70) >> 4;
                        u8 dref2 = b1 & 0x80;
                        switch (opc) {
-                       case 0x0a: printf("NOT"); break;
-                       case 0x0b: printf("NEG"); break;
-                       case 0x0c: printf("ADD"); break;
-                       case 0x0d: printf("SUB"); break;
-                       case 0x0e: printf("MUL"); break;
-                       case 0x0f: printf("MULU"); break;
-                       case 0x10: printf("DIV"); break;
-                       case 0x11: printf("DIVU"); break;
-                       case 0x12: printf("MOD"); break;
-                       case 0x13: printf("MODU"); break;
-                       case 0x14: printf("AND"); break;
-                       case 0x15: printf("OR"); break;
-                       case 0x16: printf("XOR"); break;
-                       case 0x17: printf("SHL"); break;
-                       case 0x18: printf("SHR"); break;
-                       case 0x19: printf("ASHR"); break;
+                       case 0x0a: i_print("NOT"); break;
+                       case 0x0b: i_print("NEG"); break;
+                       case 0x0c: i_print("ADD"); break;
+                       case 0x0d: i_print("SUB"); break;
+                       case 0x0e: i_print("MUL"); break;
+                       case 0x0f: i_print("MULU"); break;
+                       case 0x10: i_print("DIV"); break;
+                       case 0x11: i_print("DIVU"); break;
+                       case 0x12: i_print("MOD"); break;
+                       case 0x13: i_print("MODU"); break;
+                       case 0x14: i_print("AND"); break;
+                       case 0x15: i_print("OR"); break;
+                       case 0x16: i_print("XOR"); break;
+                       case 0x17: i_print("SHL"); break;
+                       case 0x18: i_print("SHR"); break;
+                       case 0x19: i_print("ASHR"); break;
                        default:
                        default:
-                               printf("\nopcode: %x\n", opc);
+                               fprintf(stderr, "\nopcode: %x\n", opc);
                                assert(0);
                        }
                                assert(0);
                        }
-                       printf("%d", c3264 ? 64 : 32); pspace();
+                       i_print("%d", c3264 ? 64 : 32); pspace();
                        pdref(dref1); preg(op1); pcomma();
                        pdref(dref2); preg(op2);
                        if (opindex) {
                        pdref(dref1); preg(op1); pcomma();
                        pdref(dref2); preg(op2);
                        if (opindex) {
@@ -228,14 +551,14 @@ static void pinsn(void)
                        u8 c3264 = insn & 0x40;
                        u8 opmod = opc - 0x1a;  // 0b, 1w, 2d
 
                        u8 c3264 = insn & 0x40;
                        u8 opmod = opc - 0x1a;  // 0b, 1w, 2d
 
-                       u8 b1 = *data++;
+                       u8 b1 = i_push(*data++);
                        u8 op1 = b1 & 0x7;
                        u8 dref1 = b1 & 0x8;
                        u8 op2 = (b1 & 0x70) >> 4;
                        u8 dref2 = b1 & 0x80;
 
                        u8 op1 = b1 & 0x7;
                        u8 dref1 = b1 & 0x8;
                        u8 op2 = (b1 & 0x70) >> 4;
                        u8 dref2 = b1 & 0x80;
 
-                       printf("EXTND"); pimmc(opmod);
-                       printf("%d", c3264 ? 64 : 32); pspace();
+                       i_print("EXTND"); pimmc(opmod);
+                       i_print("%d", c3264 ? 64 : 32); pspace();
                        pdref(dref1); preg(op1); pcomma();
                        pdref(dref2); preg(op2);
                        if (opindex) {
                        pdref(dref1); preg(op1); pcomma();
                        pdref(dref2); preg(op2);
                        if (opindex) {
@@ -244,11 +567,11 @@ static void pinsn(void)
                }
                break;
        case 0x2a:{
                }
                break;
        case 0x2a:{
-                       u8 b1 = *data++;
+                       u8 b1 = i_push(*data++);
                        u8 op1 = b1 & 0x7;
                        u8 op2 = (b1 & 0x70) >> 4;
 
                        u8 op1 = b1 & 0x7;
                        u8 op2 = (b1 & 0x70) >> 4;
 
-                       printf("STORESP"); pspace();
+                       i_print("STORESP"); pspace();
                        preg(op1); pcomma(); pvmreg(op2);
                }
                break;
                        preg(op1); pcomma(); pvmreg(op2);
                }
                break;
@@ -256,12 +579,12 @@ static void pinsn(void)
                        u8 c3264 = insn & 0x40;
                        u8 i1632 = !!(insn & 0x80);
 
                        u8 c3264 = insn & 0x40;
                        u8 i1632 = !!(insn & 0x80);
 
-                       u8 b1 = *data++;
+                       u8 b1 = i_push(*data++);
                        u8 op1 = b1 & 0x7;
                        u8 dref1 = b1 & 0x8;
                        u8 op1index = b1 & 0x10;
 
                        u8 op1 = b1 & 0x7;
                        u8 dref1 = b1 & 0x8;
                        u8 op1index = b1 & 0x10;
 
-                       printf("CMPI%d", !c3264 ? 32 : 64);
+                       i_print("CMPI%d", !c3264 ? 32 : 64);
                        pimmc(i1632 + 1);
                        pflags(opc - 0x2d); pspace();
                        pdref(dref1); preg(op1);
                        pimmc(i1632 + 1);
                        pflags(opc - 0x2d); pspace();
                        pdref(dref1); preg(op1);
@@ -302,36 +625,36 @@ static void pinsn(void)
                        u8 op1index = mod & 0x2;
                        u8 op2index = mod & 0x1;
 
                        u8 op1index = mod & 0x2;
                        u8 op2index = mod & 0x1;
 
-                       u8 b1 = *data++;
+                       u8 b1 = i_push(*data++);
                        u8 op1 = b1 & 0x7;
                        u8 dref1 = b1 & 0x8;
                        u8 op2 = (b1 & 0x70) >> 4;
                        u8 dref2 = b1 & 0x80;
 
                        u8 op1 = b1 & 0x7;
                        u8 dref1 = b1 & 0x8;
                        u8 op2 = (b1 & 0x70) >> 4;
                        u8 dref2 = b1 & 0x80;
 
-                       printf("MOV"); pimmc(op1mod); pimmc(op2mod); pspace();
+                       i_print("MOV"); pimmc(op1mod); pimmc(op2mod); pspace();
                        pdref(dref1); preg(op1);
                        // op2mod defines index width for *both* indexes
                        if (op1index) {
                        pdref(dref1); preg(op1);
                        // op2mod defines index width for *both* indexes
                        if (op1index) {
-                               pspace(); pimm(op2mod);
+                               pspace(); pidx(op2mod);
                        }
                        pcomma(); pdref(dref2); preg(op2);
                        if (op2index) {
                        }
                        pcomma(); pdref(dref2); preg(op2);
                        if (op2index) {
-                               pspace(); pimm(op2mod);
+                               pspace(); pidx(op2mod);
                        }
                }
                break;
        case 0x37:{
                        u8 mod = (insn & 0xc0) >> 6;
                        }
                }
                break;
        case 0x37:{
                        u8 mod = (insn & 0xc0) >> 6;
-                       u8 b1 = *data++;
+                       u8 b1 = i_push(*data++);
                        u8 op1 = b1 & 0x7;
                        u8 dref = b1 & 0x8;
                        u8 width = (b1 & 0x30) >> 4;
                        u8 op1index = b1 & 0x40;
 
                        u8 op1 = b1 & 0x7;
                        u8 dref = b1 & 0x8;
                        u8 width = (b1 & 0x30) >> 4;
                        u8 op1index = b1 & 0x40;
 
-                       printf("MOVI"); pimmc(width); pimmc(mod); pspace();
+                       i_print("MOVI"); pimmc(width); pimmc(mod); pspace();
                        pdref(dref); preg(op1);
                        if (op1index) {
                        pdref(dref); preg(op1);
                        if (op1index) {
-                               pspace(); pimm16();
+                               pspace(); pidx16();
                        }
                        pcomma(); pimm(mod);
                }
                        }
                        pcomma(); pimm(mod);
                }
@@ -339,30 +662,30 @@ static void pinsn(void)
        case 0x38:{
                        u8 mod = (insn & 0xc0) >> 6;
 
        case 0x38:{
                        u8 mod = (insn & 0xc0) >> 6;
 
-                       u8 b1 = *data++;
+                       u8 b1 = i_push(*data++);
                        u8 op1 = b1 & 0x7;
                        u8 dref = b1 & 0x8;
                        u8 op1index = (b1 & 0x40) >> 6;
 
                        u8 op1 = b1 & 0x7;
                        u8 dref = b1 & 0x8;
                        u8 op1index = (b1 & 0x40) >> 6;
 
-                       printf("MOVIn"); pimmc(mod); pspace();
+                       i_print("MOVIn"); pimmc(mod); pspace();
                        pdref(dref); preg(op1);
                        if (op1index) {
                        pdref(dref); preg(op1);
                        if (op1index) {
-                               pspace(); pimm16();
+                               pspace(); pidx16();
                        }
                        pcomma(); pimm(mod);
                }
                break;
        case 0x39:{
                        u8 mod = (insn & 0xc0) >> 6;
                        }
                        pcomma(); pimm(mod);
                }
                break;
        case 0x39:{
                        u8 mod = (insn & 0xc0) >> 6;
-                       u8 b1 = *data++;
+                       u8 b1 = i_push(*data++);
                        u8 op1 = b1 & 0x7;
                        u8 dref = b1 & 0x8;
                        u8 op1index = b1 & 0x40;
 
                        u8 op1 = b1 & 0x7;
                        u8 dref = b1 & 0x8;
                        u8 op1index = b1 & 0x40;
 
-                       printf("MOVREL"); pimmc(mod); pspace();
+                       i_print("MOVREL"); pimmc(mod); pspace();
                        pdref(dref); preg(op1);
                        if (op1index) {
                        pdref(dref); preg(op1);
                        if (op1index) {
-                               pspace(); pimm16();
+                               pspace(); pidx16();
                        }
                        pcomma(); pimm(mod);
                }
                        }
                        pcomma(); pimm(mod);
                }
@@ -375,7 +698,8 @@ static void pinsn(void)
 
 static void pheader(void)
 {
 
 static void pheader(void)
 {
-       printf("\n%08x: ", data - data_start);
+       /*printf("\n%08x: ", data - data_start);*/
+       /*i_print("\n");*/
 }
 
 int main(int argc, const char **argv)
 }
 
 int main(int argc, const char **argv)
@@ -444,7 +768,8 @@ int main(int argc, const char **argv)
        fprintf(stderr, PS "0x%08x\n", "size_code", size_code);
        data += 4 + 4 + 4;      //u32, u32, u32
 
        fprintf(stderr, PS "0x%08x\n", "size_code", size_code);
        data += 4 + 4 + 4;      //u32, u32, u32
 
-       fprintf(stderr, PS "0x%08x\n", "entry_point", *((u32 *) data));
+       entry_point = *((u32 *) data) - *((u32 *)(data+4));
+       fprintf(stderr, PS "0x%08x\n", "entry_point", entry_point);
        data += 4;              //u32
 
        base_code = *((u32 *) data);
        data += 4;              //u32
 
        base_code = *((u32 *) data);
@@ -459,11 +784,17 @@ int main(int argc, const char **argv)
        fprintf(stderr, PS "0x%08x\n", "???", *((u32 *) data));
 
        data = data_start + base_code;
        fprintf(stderr, PS "0x%08x\n", "???", *((u32 *) data));
 
        data = data_start + base_code;
-       while (data <= (data_start + size_code)) {
+       while (data <= (data_start + base_code + size_code)) {
+               i_begin((int)(data-data_start), (int)(data-data_start-base_code));
+
                pheader();
                pinsn();
        }
        printf("\n");
                pheader();
                pinsn();
        }
        printf("\n");
+       i_end();
+       i_dump();
+       i_cleanup();
 
        return 0;
 }
 
        return 0;
 }
+