One good idea I had recently was to implement a memory mapper.

I give it an address (typically when some binary is loaded into memory) and it recursively parses all the bytes from it.
When it points to an instruction, it tags the byte as an instruction and the following ones as operands as needed (inferring this information from the opcode and the addressing mode).

And depending on the instruction:
– if it is a BRA or a JMP it goes on the parsing from the resulting address
– if it is a conditional branch it both handles the destination address and also the next instruction
– if the addressing mode gets bytes from memory, it tags them as Data
– etc.

As a result:
– it knows exactly what the memory is made of (unless some technics are used such as auto-generated code)
– it can easily go back while stepping in the code (as it knows how the previous bytes are organized, it can then rewind to the previous instruction jumping over the detected operands)
– displaying the code while debugging gets clearer
– etc.

So I have added an additional row to the memory dump that displays ‘I’ for an instruction, ‘o’ for an operand, ‘d’ for data, … as you can see on the screenshot…

Pretty convenient!