#8086 disassembler in (just a bit over) 2K of 8086 code and data

1 messages · Page 1 of 1 (latest)

fervent cove
worn slate
#

nice

fervent cove
#

and i just spotted a bug, shl ax, cl should've been shl ax, 1 :^)

worn slate
#

I've done something similar

#

and it took a bit more than 8 kiB

#

though it was a debugger with assembly/disassembly function

fervent cove
#

yeah i was at first thinking of making a whole debug.com clone

#

but i got bored, then decided to visit the disassembler part as it's own thing since i got the idea for the implementation

#

namely the decode table with the upper nibble representing the operation

worn slate
#

but yeah, seems like you have a much better opcode table than I have

fervent cove
#

the only problem with it is that it imposes a limit that the offset is >4K (so it must be in it's own segment)

worn slate
#

wait does it have to be in its own segment because the offset is >4K or the offset is >4K because it must be in its own segment?

fervent cove
#

if you were to put it in a larger program then you'd have to position it so all offsets within the disassembler opcode table are <4K

#

since the highest nibble determines the index into the subroutine pointer table

worn slate
#

ah

#

my opcode table is a bit more bloated and it was probably a bad idea to embed the opcode strings in hindsight

fervent cove
#

i was thinking of making the opcode table a sparse array (is that the term?) by having a count byte before each entry

#

so for example all the push/pop reg16 would be encoded with 2 entries instead of 16

#

although idk if the savings in the big blocks would outweigh the decoding cost and all the one off opcodes being one byte longer

#

there's also a quirk with in imm8, al/ax, namely that it's represented as in al/ax, imm8

#

to save on a bit of space by reusing the operation for decoding mnemonic imm8

worn slate
#

yeah, the special cases are kinda annoying

#

ended up with a lot of spaghetti code

#

though my lack of use of jump tables might also have contributed :^)

fervent cove
#

although the decoder becomes a bit bigger

worn slate
#

well, except if the same string occurs multiple times

#

tbf, this doesn't happen a lot

fervent cove
#

well it happens a bit

#

8 push, >8 pop, >8 inc, >8 dec at least

#

and also the arithmetic and bit ops

#

and they're also common between GRP1/3/4 and the main opcodes

worn slate
#

I only have 3 of each

#

the most I have is 5 movs

fervent cove
#

i have a bunch of redundant strings that include the register

#
adc_al_str: db "ADC AL,", 0
push_ss_str: db "PUSH SS", 0
sbb_al_str: db "SBB AL,", 0
push_ds_str: db "PUSH DS", 0
pop_ds_str: db "POP DS", 0
and_al_str: db "AND AL,", 0
worn slate
#

oh

fervent cove
#

but the base ones only appear once

#

the ones with the registers in them are for encodings that use a fixed register

cinder nymph
#

nice job qooke

keen cape
#

its a native binary translator, that can do x86->arm for example

but it solves the problem of writing an x86 parser, by just reusing the TCG parser in qemu

#

so it uses qemu to parse _ to TCG-IR, then converts TCG-IR to LLVM-IR, then LLVM-IR to _

#

so it can accept anything qemu supports as an input
and anything llvm supports as an output