# i386 Disassembler

The unit at asm/i386d decodes byte streams containing i386 code into listings
where each line contains an operation.

The disassembler is used mainly through "dis ( a -- )", which spits a list of
"listingsz" (default 20) lines. Because i386 is a variable width encoding, not
all listing will cover the same memory area. To continue listing, use
"disn ( -- )", which continues where the last "dis" left off.

## Listing format

Each line in the listing has this format:

  addr mnemonic arguments rawbytes

Example:

  cafe1234 MOV  ESI,[EBX+04]       8b 73 04

Columns have a fixed width and are thus aligned with each other.

Register names are displayed as expected: the "E" prefix indicates 32-bit, the
"L" and "H" registers are the 8-bit ones.

All numbers are in hexadecimal format, their display width determining their
encoding with. For example, "[EBX+04]" refers to the "disp8" mod/rm form whereas
"[EBX+00000004]" refers to the "disp32" one.

Brackets such as "[]" denote indirection and the type of bracket indicates the
width of the indirection. "[]" is for 32-bit, "()" is for 16-bit, "{}" is for
8-bit.

Jump and call targets are displayed in absolute target address.

The "rawbytes" column is a dump of the raw bytes that were decoded on that line.

## Shortened mnemonics

Mnemonics are limited to 4 characters, which means that we lack space for some
of them. New mnemonics have thus been created:

ENTR ENTER
LEAV LEAVE
BOUN BOUND
MVSX MOVSX
MVZX MOVZX

## Arguments spillover

Some arguments form are really, really long (for example, modrm+disp32 combined
with a 32bit immediate) and will spill over the number of columns allocated to
the arguments.

When that happens, we let the arguments spill over, but insert a newline before
spitting the last column, making this listing 2 lines long.

Too many of those could make a listing overflow a screen, but these argument
forms are rather rare so the chances of this happening is slim.

## Word labels

When listing a jump or a call, we check wether the target address is a word,
that is, a payload to a dictionary entry. We do so with the help of "?w>e"
[doc/mem/dict]. If it is, we replace the "raw bytes" printing with the name of
the associated word.
