This is my multi-machine disassembler. This is a usage document; for a compilation document, see INSTALL. This disassembler is specifically intended for humans to pick apart binary-only programs to figure out what they do and how they do it. Basic usage: disas -machine This will start the disassembler, disassembling the contents of , where is the machine name. At this writing, the recognized machine names are G65SC802 g65sc802 tempest Tempest 68k M68k m68k MC68k mc68k MIPSEB mipseb MIPSEL mipsel SPARC Sparc sparc VAX Vax vax 80386 386 z80 Z80 z-80 Z-80 Machine names on the same line are equivalent. Most of them are self-explanatory, but two probably need note: the G65SC802 is a slightly modified 6502, and Tempest is a plain 6502 but with additional support for the Tempest vector-generator instruction set. Basic operation: move the active line up and down with j and k. Use commands like i, l, ", b, to direct the disassembler how to disassemble various pieces (the full list is below). Use S to save your work, T to write out a text file of disassembled code, R to read in a save on a future run, Q to quit. Depending on which machine you're disassembling for, there may be machine-specific commands as well. In more detail.... The command line consists of disas -machine where is the machine name, contains the data to disassemble, and gives the address that the first byte of the file should be taken to be at. You can also specify -file before the and -base before the if you want. There are a number of important concepts to fully understanding operation. At any moment there is an active address and an active line. Every line is either a disassembly line or an annotation line (except for the overhead lines at the bottom, and blank lines if the file ends before the end of the screen); every address has a flag indicating how it is to be treated. Many, probably most, addresses will be flagged as "this byte belongs with a previous address"; for example, this is used for the second and later bytes of multi-byte instructions. Normally, the active address is the first byte of the line, but this is not always so; for example, if you use the go-to-address command to go to an address in the middle of an instruction, it won't be. This unusual condition is indicated by a + in the left-hand margin; moving "up" from this condition moves the active address to the address of the line. When you use commands that change the disassembly, they affect the byte at the active address, and, for most of them, some number of following bytes as well (depending on the type of object, and, sometimes, the data). If you use this to change a byte in the middle of something else, the "something else" is disrupted - usually, everything before the point of change is disassembled as ".byte"s. If the disassembler is called on to disassemble a byte that is marked as belonging to something earlier when the preceding thing doesn't want it (for example, if you have a seven-byte instruction and you disassemble it as a .long, which claims only four bytes, the former fifth byte will fall into this category), the disassembler disassembles it as an instruction. For more on annotation lines, see the description of the ; command. Instruction disassembly has two additional bits which can be set per-instruction: parallel mode and literals-are-pointers mode. Parallel mode instruction disassembly is just like ordinary instruction disassembly except for two things: first, each such instruction claims only one byte, even if it's a multi-byte instruction, so the next disassembly line will be only one byte further along, and second, the address immediately after the whole instruction is noted in { }. For example, on the VAX, if memory contains 1000 d0 1001 56 1002 50 1003 6a 1004 9f then ordinary disassembly beginning at 1000 would start with 1000: movl r6,r0 1003: cvtdl *$.... whereas if address 1000 is marked parallel, we instead see 1000: movl r6,r0 {1003} 1001: cvtfd r0,(r10) 1004: pushab .... Literals-are-pointers mode is used when a literal value in the instruction is semantically a pointer, but this is not discernible from the instruction form. To use the VAX as example again, if we see 1000: movl $00001009,r0 1007: bsbb 0x1060 1009: movtuc $2a,$20,r4,(r8),(r9),-(r3) 1010: addp4 (r9),-(r3),$20,(fp) 1015: muld3 (r3),(r8),(r1) 1019: cvtld (r9),(r3) .... where 1060 is known to treat the value in r0 as the address of a string, then we tell it to disassemble 1009 as a string and get, say, 1000: movl $00001009,r0 1007: bsbb 0x1060 1009: .string "/* This is mechanically generated */\n" Then we define a symbol, "hdrstring", say, as 1009, 1000: movl $00001009,r0 1007: bsbb 0x1060 hdrstring: .string "/* This is mechanically generated */\n" But we'd like the movl to indicate that the value it's moving is hdrstring. Turning on literals-are-pointers for the movl will do that; we then get 1000: movl $00001009,r0 1007: bsbb 0x1060 hdrstring: .string "/* This is mechanically generated */\n" There is no way to turn on literals-are-pointers for some but not all of the literals in an instruction. (This is not usually a problem.) Here are the operating commands. ^G In general, ^G will abort any multi-character operation in progress. For example, if you type S by mistake, ^G at the filename prompt will abort the save. ! Scroll the screen up until the active line is the first line on the screen. " Disassemble as a 0x00-terminated string. * Take whatever the active line is and convert it into as many .byte lines as necessary to use up the same number of bytes. : Enter an extended command (see below). ; Manipulate comments (see below). < Pop the address stack. > Push the address stack. @ Read a file of keystrokes. A Disassemble as a block of ASCII characters (you must specify the block's size). B Collapse blank space (0x00 bytes) into a single line. This collapses bytes only when they are disassembled as the same thing; for example, a ".long 00000000" amid an otherwise unbroken series of ".byte 00" lines will cause a B command to stop collapsing. The presence of symbols will also stop collapsing. This produces .space directives; two adjacent .space directives can be collapsed by typing B on the first one. C Collapse a chunk of not-necessarily-blank data into a single line. H Make the first line of the screen the active line. I If the current line is already being disassembled as an instruction, toggle literals-are-pointers for it; otherwise, disassemble it as an instruction with literals-are-pointers turned on. L Make the last line of the screen the active line. Q Quit the program. There are no checks to make sure you've saved. R Read in a save. The save must match the current settings (base, machine, and size of data file, mostly). If the S command has no file name saved, the name given here is saved for later S commands. S Save your work. The save file format is not documented here and is not intended for anything but reading with the R command. Once you've used this command once, you can repeat it with the same filename by typing return immediately after S; this is indicated by the previous filename appearing at the prompt if you haven't typed any characters. T Create a text file containing the disassembly. This is the normal way of getting useful output from the disassembler. Text files cannot be read back in; use S to create a save that can be read back in. T has the same "repeat last file name" feature that S does. Y Create a symbol list file. This is a text file listing the symbols defined at the time. They are not in any particular order. Z Scroll the screen one line down. Refuses to work if the active line is at the bottom of the screen or if the top line of the screen is already the beginning of the file. a Move the active line to an arbitrary address. (The address must be within the file.) This is the usual way to move large distances within the file quickly. b Disassemble as a byte (displayed in hex). c Disassemble as a character. i Disassemble as an instruction. j Move the active line down one line. If you're at the bottom of the screen, recenters the screen on the (new) active line. k Move the active line up one line. If you're at the top of the screen, recenters the screen on the (new) active line. l Disassemble as a long (4 bytes). o Define a symbol, overriding others at the address. This is just like s (qv), except that it first undefines any other symbols that have the same value. p Disassemble as a pointer. s Define a symbol. You must specify the symbol's name and value. You can give . for the value to indicate the current address. u Undefine a symbol. Give the symbol's name and it is forgotten. w Disassemble as a word (2 bytes). x Exchange the current location with the location on top of the address stack. z Scroll the screen up one line. Refuses to work if the active line is the first line of the screen. | Disassemble as a parallel instruction. The : command allows you to enter an extended command. At present the extended commands are: relocate This allows you to change the disassembly's base address. It's like using a different value for -base on the command line, except that runs with different -base values are savefile-incompatible; using relocate changes the base value and also relocates everything that depends on it, including the values of all symbols. (This can be a problem if some symbols' values are absolute addresses rather than being related to the base address. At present there is no typing for symbol values, so there is no way to deal with this automatically.) stack This allows you to perform more complex manipulations of the location stack than the <, >, and x commands permit. The stack is displayed with a cursor, represented by [ ], on one of the stack items. You can move the cursor with h or k, to move it left (towards the top of the stack), or l or j, to move it right (towards the bottom of the stack). You can press space to pick up the current element, so that it moves with the cursor, or to drop it if you have it picked up (so the cursor moves without affecting the order). You can use > to duplicate the element under the cursor or < to delete the element under the cursor (except that you cannot use < if there is only one element in the stack, because the current location is represented as an extra element at the top of the stack). Use ^G to abort the operation without affecting anything, or RETURN to accept the new stack and have it replace the current stack. The ; command allows you to manipulate annotations, which are displayed as assembler comments marked off by ;. Every annotation is attached to some address and appears on the line which has that address. (If no line has that address - if it's included as part of some other line - the annotation is not printed anywhere, though it is retained and will become visible again if and when the address has its own line again.) An address can have three kinds of annotations: `before' annotations, `on' annotations, and `after' annotations. There is at most one `on' annotation for an address; there can be any number of `before' and `after' annotations. `Before' annotations appear as comment lines before the line they are attached to, `on' winged to the right of the line they're attached to, and `after' as comment lines after the line they're attached to. To use one of the above disassembly examples, here are some annotations attached to address 1001: 1000: movl r6,r0 {1003} ; This is a before annotation. 1001: cvtfd r0,(r10) ; This is an on annotation. ; This is an after annotation. ; This is another after annotation. 1004: pushab .... The difference between an after annotation on one line and a before annotation on the following line is which address it's attached to; this can matter if the disassembly changes so that one address but not the other no longer has its own line. When the active line is an annotation line, the status bar display changes from "Addr NNN" to "Before NNN (M)" or "After NNN (M)", where M is the line number of the annotation (0 is the topmost, 1 next, etc). When such locations appear deeper in the address stack, "Before NNN (M)" turns into "NNNM". When you type ;, the next character indicates what operation you want to perform: d Deletes the line, if it's an annotation line, or deletes any `on' annotation on the line, if not. ; Replaces the line, if it's an annotation line, or replaces any `on' annotation on the line, if not. o Inserts a new annotation line below this one. The new line is a `before' annotation, if this line is a `before' annotation, or an `after' annotation, if this line is a disassembly line or an `after' annotation. O Inserts a new annotation line before this one. The new line is a `before' annotation, if this line is a `before' annotation or a disassembly line, or an `after' annotation, if this line is an `after' annotation. For ;, o, and O, the new text is prompted for. Some machines provide machine-specific commands as well. These are not expected to make sense to people who do not know the relevant machine. Machine "Tempest": v Disassemble as vector-generator code. J Disassemble as jump tables. This is like disassembling as pointers, except the address pointed to is one more than the address found in the data. Machine "SPARC": r Disassemble as a symbol-table relocation item. y Disassemble as a symbol table entry. Machine "VAX": d Disassemble as a D-float value. e Disassemble as a calls/callg entry mask. f Disassemble as an F-float value. g Disassemble as an G-float value. h Disassemble as an H-float value. :debug Toggle floating-point conversion debugging output. When enabled, this is written to "vax-float.dbg" in the current directory. /~\ The ASCII der Mouse \ / Ribbon Campaign X Against HTML mouse@rodents.montreal.qc.ca / \ Email! 7D C8 61 52 5D E7 2D 39 4E F1 31 3E E8 B3 27 4B