Basic disasm engine -- an .so for the bastard

FILES
-----
i386.c     : All the library code :)
i386.h     : Support header file for the above
dislib.h   : Header to be used for linking to the .so
opcode.map : as it says; included in i386.h
quikdis.c  : a quick & dirty tester for the library
make.sh    : poor man's Makefile

opcode.map.base : 'Known-good' opcode map before instr typing
op-conv.pl		 : Perl script to convert opcode.base into opcode.map


FP, MMX, and other weird instructions are not yet supported.


COMPILATION
-----------
To compile the basic object file:
   gcc -fPIC -c i386.c -o i386.o

To turn the obj file into a shared library:
   gcc -shared -Wl,-soname,libi386.so -o libi386.so.1 i386.o -lc
...into a static library:
   ar rcs libi386.a i386.o

For testing, 
   gcc quikdis.c libi386.a -o quikdis
will make the test program using the static library, while
   gcc quikdis.c -li386 -L./ -o quikdis
will make the tets program using the shared library.


OPERATION
---------

The tester iterates through a buffer and calls DisasmAddr for each 'address'.
DisasmAddr looks up the current byte in the opcode tables and recurses if more 
than one byte is needed; it calls InstDecode once the instruction is identified.
InstDecode checks the flags of the opcode map for an modR/M byte and calls 
ModRMDecode [and then SIBDecode if applicable] to parse it, parses any 
displacement bytes, then iterates through the operands [0-3 per inst, based on 
opcode map flags] creating a string for the operand and identifying any 
immediate data. InstDecode prints the disassembly to STDOUT, though this will 
be changed so that it fills a CODE structure instead.

This is the 'library revision', though it needs much refinement. Consider this
the 'Foundation Is Coded And Now We Need To Make It Work' phase of development;
in particular I want to work on the flags & opcode tables to make them more
reliable and less redundant[/confusing].

Again, comments and flames welcome ;)


BUGS
----
Decoding immediate values loses sign:
  + in i386.c:InstDecode(), immediate values are sprintf()'d into the operand
    buffer using the %X format conversion; this treats the value as unsigned.
    As a result, lines such as
       mov eax, -1
    will be disassembled as
       mov eax, FFFFFFFF
    Replacing %X with %i, however causes addressing problems like
       call -731
    ...which are even more unacceptable than the unsigned values. Some logic
    must be added to the Imm decoding which checks the instruction type, and
    treats the Imm as an address(%X) or a value (%i) based on the inst type.
