Disassembler

This chapter describes the Watcom Disassembler. It takes as input an object file (a file with extension .o) and produces, as output, the Intel assembly language equivalent. The Watcom compilers don't produce an assembly language listing directly from a source program. Instead, the Watcom Disassembler can be used to generate an assembly language listing from the object file generated by the compiler.

This chapter includes the following sections:

Disassembler command-line syntax

The Watcom Disassembler command-line syntax is as follows:

wdisasm [options] filespec [options]

The square brackets [ ] denote items that are optional.

filespec
is the filename specification of the object file to be disassembled. A default filename extension of .o is assumed when no extension is specified.
options
is a list of valid Watcom Disassembler options, each preceded by a dash (-). Options may be specified in any order.

The options supported by the Watcom Disassembler are:

l[=list_file]
create a listing file
s[=source_file]
using object file source line information, imbed original source lines into the output file
c=code_name
name of additional segments that contain executable code
i=char
redefine the initial character of internal labels (default: L)
a
write assembly instructions only to the listing file
au
write assembly instructions only to the listing file using UNIX-style assembly syntax
b
generate alternate form of based or indexed addressing modes
e
include list of external names
p
include list of public names
r
display register names in upper case
u
display instruction opcode mnemonics in upper case
m
leave C++ names mangled

The sections that follow describe the options.

Listing option - l[=list_file]

By default, the Watcom Disassembler sends its output to the terminal. The l (``el'') option instructs the Watcom Disassembler to put the output in a listing file. The default file name of the listing file is the same as the file name of the object file. The default file extension of the listing file is .lst.

For example,

wdisasm calendar -l

In the above example, the Watcom Disassembler is instructed to disassemble the contents of the file calendar.o, and put the output in a listing file called calendar.lst.

An alternate form of this option is

l=list_file

With this form, you can specify the name of the listing file. When specifying a listing file, a file extension of .lst is assumed if none is specified.

For example,

wdisasm calendar -l=calendar.lis

In the above example, the Watcom Disassembler is instructed to disassemble the contents of the file calendar.o, and place the output in a listing file called calendar.lis.

Source option - s[=source_file]

The s option causes the source lines corresponding to the assembly language instructions to be placed in the listing file. The object file must contain line numbering information. That is, the d1 or d2 option must have been specified when the source file was compiled. If no line numbering information is present in the object file, the s option is ignored.

When the s option is specified, the order in which the source file name is determined is as follows:

  1. If present, the source file name specified on the command line
  2. The name from the module header record
  3. The object file name

In the following example, we have compiled the source file mysrc.c with d1 debugging information. We then disassemble it as follows:

wdisasm mysrc -s -l

In the above example, the Watcom Disassembler is instructed to disassemble the contents of the file mysrc.o and place the output in the listing file mysrc.lst. The source lines are extracted from the file mysrc.c.

An alternate form of this option is

s=source_file

With this form, you can specify the name of the source file. For example,

wdisasm mysrc -s=myprog.c-l

The above example produces the same result as in the previous example, except the source lines are extracted from the file myprog.c.

Identifying code segments option - c=code_name

The c option permits you to specify one additional segment name or pattern for segments that contain executable code. Valid forms of the c option are:

where string is any sequence of characters, with letters treated in a case-insensitive manner. The ``*'' character is a wildcard character. You must protect the ``*'' with quotation marks to prevent the shell from attempting to expand it.

By default, the following segments are assumed to contain executable code:

Consider the following example:

wdisasm myprog "-c=T@*"

All segments whose name starts with the characters ``T@'' (in addition to those ending in CODE or TEXT) are assumed to contain executable code.

It isn't possible to instruct the Watcom Disassembler to interpret segments whose name ends in CODE or TEXT as data.

Changing the internal label character - i=char

The i option permits you to specify the first character to be used for internal labels. Internal labels take the form Ln, where n is one or more digits. The default character L can be changed using the i option. The replacement character must be a letter (a-z, A-Z). A lowercase letter is converted to uppercase.

For example,

wdisasm calendar -i=x

Assembly format option - a, au

The a option controls the format of the output produced to the listing file. When specified, the Watcom Disassembler produces a listing file that can be used as input to an assembler. When au is specified, the assembly syntax is that employed by UNIX systems.

For example,

wdisasm calendar -a -l=calendar.asm

In the above example, the Watcom Disassembler is instructed to disassemble the contents of the file calendar.o, and place the output in the file calendar.asm, so that it can be assembled by an assembler.

Alternate addressing form option - b

The b option causes an alternate form of the based or indexed addressing mode to be used in an instruction. By default, the following form is used:

mov ax,-2[bp]

If the b option is specified, the following form is used:

mov ax,[bp-2]

External symbols option - e

The e option controls the amount of information produced in the listing file. When specified, a list of all externally defined symbols is produced in the listing file.

For example,

wdisasm calendar -e

In the above example, the Watcom Disassembler is instructed to disassemble the contents of the file calendar.o and display the output, with a list of all external symbols, on the screen. A sample list of external symbols is shown below:

List of external symbols

Symbol
----------------
___iob        0000032f 00000210 000001f4 00000158 00000139
__CHK         00000381 00000343 000002eb 00000237 000000cb
Box_          000000f2
Calendar_     000000a7 00000079 00000049
ClearScreen_  00000016
fflush_       00000334 00000215 000001f9 0000015d 0000013e
int386_       000003af 00000372
Line_         000002db 000002b5 00000293 00000274 0000025a
localtime_    00000028
memset_       00000308
PosCursor_    0000031e 000001e1 00000148 00000123 000000b6
printf_       00000327 00000208 000001ec 00000150 00000131
strlen_       00000108
time_         0000001d
----------------------------------------------------------

Each externally defined symbol is followed by a list of location counter values indicating where the symbol is referenced.

The e option is ignored when the a option is specified.

Public symbols option - p

The p option controls the amount of information produced in the listing file. When specified, a list of all public symbols is produced in the listing file.

For example,

wdisasm calendar -p

In the above example, the Watcom Disassembler is instructed to disassemble the contents of the file calendar.o and display the output, with a list of all exported symbols, on the screen. A sample list of public symbols is shown below.

List of public symbols

SYMBOL        GROUP        SEGMENT       ADDRESS
--------------------------------------------------
Box_                       _TEXT         00000231
Calendar_                  _TEXT         000000c5
ClearScreen_               _TEXT         0000037b
Line_                      _TEXT         000002e5
main_                      _TEXT         00000000
PosCursor_                 _TEXT         0000033d

---------------------------------------------------
The p option is ignored when the a option is specified.

Uppercase register option - r

The r option instructs the Watcom Disassembler to display register names in uppercase. The default is to display them in lowercase.

Uppercase opcode option - u

The u option instructs the Watcom Disassembler to display instruction opcode mnemonics in uppercase. The default is to display them in lowercase.

Retain C++ mangled names - m

The m option instructs the Watcom Disassembler to retain C++ mangled names, rather than displaying their demangled form. The default is to interpret mangled C++ names, and display them in a somewhat more intelligible form.

Example

Consider the following program contained in the file hello.c.

#include <stdio.h>

void main()
{
    printf( "Hello world\n" );
}

Compile it with the d1 option. An object file called hello.o is produced. The d1 option causes line numbering information to be generated in the object file. We can use the Watcom Disassembler to disassemble the contents of the object file by issuing the following command:

wdisasm hello -l -e -p -s -r

The output is written in a listing file called hello.lst (the l option was specified). The output contains the following:

  • a list of external symbols (the e option was specified)
  • a list of public symbols (the p option was specified)
  • the source lines corresponding to the assembly language instructions (the s option was specified).

The source input file is called hello.c. The register names are displayed in upper case (the r option was specified). The output, shown below, is the result of using the Watcom disassembler.

Module: hello.c
Group: 'DGROUP' CONST,CONST2,_DATA,_BSS

Segment: _TEXT    BYTE USE32  00000018 bytes

#include <stdio.h>

void main()
{
 0000  68 08 00 00 00     main_    push     00000008H
 0005  e8 00 00 00 00              call     __CHK

    printf( "Hello world\n" );
 000a  68 00 00 00 00              push     offset L1
 000f  e8 00 00 00 00              call     printf_
 0014  83 c4 04                    add     ESP,00000004H
 
}
 0017  c3                          ret

No disassembly errors

List of external symbols

Symbol
----------------
__CHK        00000006
printf_      00000010
------------------------------------------------------------

Segment: CONST    DWORD USE32  0000000d bytes
 0000  48 65 6c 6c 6f 20 77 6f L1           - Hello wo
 0008  72 6c 64 0a 00                       - rld..

No disassembly errors

------------------------------------------------------------
List of public symbols

SYMBOL        GROUP        SEGMENT      ADDRESS
---------------------------------------------------------
main_                      _TEXT        00000000

------------------------------------------------------------

Let's create a form of the listing file that can be used as input to an assembler:

wdisasm hello -l=hello.asm -r -a

The output is placed in the file hello.asm. The output, shown below, is the result of using the Watcom Disassembler.

.386
          NAME    hello
          EXTRN   _cstart_ :BYTE
          EXTRN   printf_ :BYTE
          EXTRN   __CHK :BYTE
DGROUP    GROUP   CONST,CONST2,_DATA,_BSS
_TEXT     SEGMENT BYTE PUBLIC USE32 'CODE'
          ASSUME  CS:_TEXT ,DS:DGROUP,SS:DGROUP
          PUBLIC  main_
main_     push    00000008H
          call    near ptr __CHK
          push    offset DGROUP:L1
          call    near ptr printf_
          add     ESP,00000004H
          ret
_TEXT     ENDS

CONST     SEGMENT DWORD PUBLIC USE32 'DATA'
L1        DB      48H,65H,6cH,6cH,6fH,20H,77H,6fH
          DB      72H,6cH,64H,0aH,00H
CONST     ENDS

CONST2    SEGMENT DWORD PUBLIC USE32 'DATA'
CONST2    ENDS

_DATA     SEGMENT DWORD PUBLIC USE32 'DATA'
_DATA     ENDS

_BSS      SEGMENT DWORD PUBLIC USE32 'BSS'
_BSS      ENDS

          END