home *** CD-ROM | disk | FTP | other *** search
- CHAPTER 13 ASSOCIATED TOOLS
-
-
- XREF Cross-reference and Symbol Listing Facility
-
-
- XREF is a tool that creates a cross-referenced symbol table
- listing of your program.
-
- To invoke XREF, you must provide a program invocation line,
- either typed to the console when the DOS command prompt appears,
- or included in a batch file. The program invocation line
- consists of the program name XREF, followed by the name of a .SYM
- symbol table file produced by A86 when you assembled your
- program. You do not need to give the .SYM extension. Note that
- if you follow normal methodology, the name of the symbol table
- file is the same as the name of the program.
-
- XREF will obtain the list of source files from the symbols file,
- read those source files, and create a listing file with the same
- name as the .SYM file, but with a .XRF extension.
-
- Prior to V3.12, XREF required the list of source files to be
- explicitly given, and allowed you to specify the name of the
- output file. To retain compatibility with batch files invoking
- the old XREF, the current version ignores anything on the command
- tail after the symbols file name. This means you can no longer
- specify a different output file name. Sorry about that-- I
- couldn't think of any other way to be compatible without
- overwriting somebody's source files with XREF output. You can
- always rename the file after XREF is completed.
-
- For example, you can type XREF myprog to obtain the cross-
- reference for the assembly that produced myprog.SYM. The output
- will be in the file myprog.XRF.
-
- The output of XREF is an alphabetical listing of all the
- non-local symbols in your program. For each symbol, XREF gives
- its type, the file in which it was defined, its value, and a list
- of all procedures in which the file was used. If you print this
- file, you typically use the TCOLS tool to obtain a multi-column
- listing from XREF's single-column output.
-
- Note the use of procedure names to identify references -- this is
- unique to the A86 package, and makes the cross-reference listing
- truly readable. Other cross-reference listings give either line
- numbers, which are meaningless unless you go find the associated
- line; or a file name, which doesn't give you as much useful
- information.
-
- Here is a more detailed description of the various pieces of
- information provided for each symbol:
-
- 1. TYPE. Labels are indicated by a colon immediately following
- the symbol name. Special symbols such as macro names are
- denoted by an appropriate word such as "macro" in place of the
- value on the following line. Other symbol types are described
- by one or two characters, following the symbol name.
- Possibilities for the first character are:
- 13-2
-
- m for a simple memory variable
- + for an index memory quantity
- c for a constant
- i for an interrupt-equate
- s for a structure
-
- If there is a second letter, it is a size attribute: b for
- byte, w for word, f for far (or doubleword).
-
- 2. FILE in which the symbol was defined. The name is stripped of
- its extension, which is presumably the same for all your
- source files. The name is preceded by = or period, which
- denotes a definition of, not a reference to the symbol.
-
- 3. VALUE, given as 4 hex digits, on the line following the
- symbol. For memory variables, this is the location of the
- variable. For indexed quantities, this is the constant-
- displacement part of the quantity. For structures, it is the
- size of the structure. For interrupt equates, it is the
- number of the interrupt.
-
- 4. REFERENCES, given on indented lines following the symbol name.
- All occurrences of the symbol in your program produce a
- reference. If the symbol is the first thing on a line, it is
- considered a "definition" of that symbol, the reference listed
- is the source file name. The name is preceded by a period if
- the definition was via a colon (i.e., a label); it is preceded
- by an equals sign otherwise. If the symbol is not the first
- thing on the line, then it is not a definition. The reference
- listing consists of the name of the last definition that XREF
- scanned (which, if your program is organized in a standard
- way, will be the name of the procedure in which the reference
- occurred.
-
- Observe that you must use the local-label facility of A86 to
- make this work. If you don't use local labels as your "place-
- marker" symbols, the symbol XREF gives you will often be the
- name of the last "place-marker" symbol, not the name of the
- last procedure.
-
- To save space, duplicate reference entries are denoted by a
- single entry, followed by "*n", where n is the decimal number
- of occurrences of that entry.
-
-
- EXMAC Macro Expansion Tool
-
- There is a tool called EXMAC which will help you troubleshoot A86
- program lines that call macros. If you are not sure about what
- code is being generated by your macro calls, EXMAC will tell you.
-
- To use this tool, you must first assemble your macro definitions,
- to produce a symbol table file. A86 will produce a .SYM file
- even if there were errors. If the errors weren't too
- catastrophic, the SYM file should be good enough to enable EXMAC
- to do its job.
- 13-3
-
- EXMAC can be used in two different ways. First, it can be used
- as an interactive program. You invoke the program in this way by
- typing just "EXMAC myprog", where myprog.SYM is the name of the
- symbols file. Then you can type in any number of macro-call
- lines. After each line, the program will display the expanded
- program text it produces. If the program does not think your
- line is a macro call, it will simply echo the line back to you.
- In this mode, you exit the program by typing control-Z at the
- beginning of a line, then terminating the line with the ENTER
- (RETURN on some computers) key. On most IBM-compatible
- computers, the control-Z code is also generated by the F6 key,
- for convenience.
-
- The second way of using EXMAC is to feed a source file to it. It
- will output the equivalent source file with the macros expanded.
- You may then, if you wish, rename the new file as the original
- source file, and assemble the new file. This method is useful if
- you get an error on a macro expansion line, and you don't know
- where the error came from. To use EXMAC in this second way, you
- simply redirect standard input and output: "EXMAC myprog <infile
- >outfile". With the redirection, EXMAC will take its input from
- the file "infile" instead of the keyboard; and it will send its
- output to the file "outfile" instead of the screen. (If you are
- not familiar with redirection of standard input and output, you
- might want to read about it in Chapter 6, "Standard Input and
- Standard Output", of the MS-DOS reference manual.)
-
-
- A86LIB Source File Library Tool
-
- There is a tool, A86LIB.COM, available only if you are
- registered, that lets you build libraries of source files. To
- use A86LIB, you must first code and debug the A86 source files
- that you wish to include in your library. Then you issue the
- command A86LIB followed by the names of the source files.
- Wildcards are accepted; so you will typically want to gather the
- source files into a single directory, and use the wildcard
- specification. For example, if you use the filename extension .8
- for your source files, you can issue the command A86LIB *.8 to
- create the library.
-
- The library created consists of a catalog file, always named
- A86.LIB, together with the source files that you fed to A86LIB to
- create the catalog.
-
- The following observations about A86LIB are in order:
-
- 1. Unlike object-code libraries, A86.LIB contains only symbol
- names and file names; it does not contain the code itself. You
- MUST retain the source files used to create A86.LIB, because
- A86 will read those files that it needs after consulting
- A86.LIB to read their names.
-
- 2. A86LIB records all non-local symbols that start a line, and
- are followed by a colon or an EQU. (Recall that local symbols
- are those names consisting of a single letter followed by one
- or more decimal digits.) A86LIB also records all symbols
- appearing on lines starting with the word PUBLIC.
- 13-4
-
- 3. If a symbol appears in more than one library source file, it
- will be logged for the first file A86LIB sees, and not the
- subsequent ones. No error will be reported, unless and until
- A86 tries to assemble both files in one assembly, and sees a
- conflict.
-
- 4. A86LIB is simple-minded. A86LIB does NOT recognize or expand
- macros; nor does it recognize conditional-assembly directives.
- This is because the library files do not stand by themselves;
- the macros and conditional-assembly variables being used might
- well be defined in the main program of the programs accessing
- the library files.
-
- You may update A86.LIB by running A86LIB again; either with new
- files or previously-recorded ones. If A86LIB is given a file it
- had already read in a previous run, then A86LIB marks all the
- symbols it had logged for the file as deleted, before rereading
- the file. Those symbols that are still in the file are then
- "unmarked". Thus, symbols that have been deleted from the file
- disappear functionally from A86.LIB, but still occupy space
- within A86.LIB. What I'm getting at is this: A86LIB will
- tolerate alterations in library files quite nicely; but for
- optimum storage efficiency you should delete A86.LIB and rebuild
- it from scratch any time you delete anything from the library.
- A86LIB is so fast that this is never very painful.
-
-
- Using A86.LIB in A86 Assemblies
-
- Once you have created a library with A86LIB, you access it simply
- by calling the procedures in it from your A86 program. When A86
- finishes an assembly and sees that there are undefined symbols in
- your program, it will automatically look for copies of A86.LIB in
- the current directory (then in other directories, as described in
- the next section). If any of the undefined symbols are found in
- the A86.LIB catalog, the files containing them are assembled.
- You see this in the list of files output to the console by A86.
-
- The subroutines in your library or libraries are effectively a
- permanent part of the A86 language. They can be called up
- effortlessly in your A86 programs. In time you can build up an
- impressive arsenal of library modules, making A86 as easy to
- program in as most high-level languages.
-
-
- Environment Variable A86LIB
-
- You can set an environment variable A86LIB to specify which
- drives or subdirectories contain A86.LIB files. The variable
- consists of a sequence of path names separated by semicolons,
- just like the PATH variable used by the operating system. For
- example, if you include in your AUTOEXEC.BAT file the line
-
- SET A86LIB=C:\bin\lib;\tools\a86lib
- 13-5
-
- then A86 will look for A86.LIB in the current directory, then it
- will look for C:\bin\lib\A86.LIB, then \tools\a86lib\A86.LIB. A86
- will keep looking in all three catalog files, assembling the
- appropriate source files from any or all of them, until there are
- no more undefined symbols, or there are no more source files to
- assemble.
-
- For every symbol in an A86.LIB catalog, there is recorded the
- name of the library file containing the symbol. The library file
- is assumed to be in the same directory as its A86.LIB file,
- unless a complete path name (starting with \ or a drive
- specifier) was fed to A86.LIB when A86.LIB was created.
-
-
- Forcing a Library Search
-
- You may force A86 to assemble library files before moving on to
- more of your program's source files. You do this by placing a
- hash sign # (hex code 23) between file names in your invocation
- line. For example, suppose your program has two modules FIRST.8
- and LAST.8. FIRST.8 calls subroutines from your library; but you
- need the library files assembled before LAST.8 is assembled. (You
- might want this because LAST.8 allocates memory space beyond the
- end of your program, which would be the end of LAST.8 if it were
- truly the last module.) You accomplish this by the invocation
- line:
-
- A86 FIRST.8 # LAST.8
-
- Note that there is never any need to force a library search at
- the end of your program modules: A86 always makes a library
- search there, if you have any undefined symbols.
-
-
- Listings with A86
-
- A86 does not produce a .LST file, or anything similar to it! (We
- now pause, to allow traditionalists to recover from their
- swooning shock.) OK, everybody back to consciousness? Good.
- Now let's all try to strip away our preconceptions, and look at
- things with a fresh viewpoint.
-
- In particular, let's consider what we use a listing file for, and
- see how A86 meets those needs. I've been programming for 20
- years; I have generated literally tons of listings. Historically,
- here's what I have used listings for:
- 13-6
-
- 1. To find out what my error messages are. In the early days of
- Intel, the text editor was so bad that it was actually faster
- to march across the building and physically print the list
- file, than it was to use an editor to find error messages! But
- even with a fast editor, what a pain it is to go into the list
- file, enduring its 120-column wide format on your 80- column
- screen, copy down the errors on paper, then go back to the
- source file to find where the errors were. Why doesn't the
- assembler just stick the messages directly into your source
- file, where you can view them and edit the source
- simultaneously? That's what A86, and only A86, does, if you
- want it to.
-
- 2. To see what code was generated; those hexadecimal bytes at the
- left of the listing. That was a real necessity, back in the
- days of hexadecimal debuggers. There we were, furiously
- patching those hex object bytes. We needed the listings to
- find our way around the program, while debugging. Today, we
- have symbolic, disassembling debuggers, such as D86. The
- power of today's debuggers means that you seldom need to look
- at hex object bytes. If you do, the debugger can show them to
- you.
-
- 3. To get a symbol-table listing. The necessity of this
- diminishes a great deal when you have a SYMBOLIC debugger; but
- I still like to have a listing from time to time. So I have
- devised a separate program, XREF, that goes through another
- pass of the source file, and creates the world's finest cross-
- reference listing for assemblers.
-
- You may ask, "Why am I being forced to essentially re-assemble
- my code to get a symbol table, when other assemblers will give
- it to me in the original assembly?" Don't be fooled. Those
- other assemblers go through all your source files twice, or
- even three times. They just do it behind your back, every
- time you want an assembly. That's one reason why my assembler
- is so much faster than everyone else's.
-
- 4. To just look at the code. I have often in the past needed to
- see that program, spread out on paper, just to get a handle on
- what the program is doing. But I have needed this less and
- less lately. Why? For two reasons. First, text editors have
- improved. It's much, much easier than it was before to cruise
- through a file on the screen. Second, my programs have
- adapted to the screen-viewing methodology. Almost
- subconsciously, I have started making the conceptual "chunks"
- of my code fit into 1 or 2 24-line screens, rather than 1 or 2
- 60-line pages. This, of course, makes better, more modular
- programs. (Spaghetti tends to untangle when you chop it up.)
- It's gotten to the point where I can develop (and have
- developed) a 5000-line application, fully debugged, without
- ever making a listing!
- 13-7
-
- 5. For archival purposes. I still do this; you should never put
- 100% trust in magnetic media. But I've stripped away the
- reasons for having anything but the source code and the symbol
- table. So I just copy the source files and the cross-
- reference listing to the printer. I haven't looked at the
- listings too much; so I haven't bothered with pagination
- control. If you want to, you can insert form feeds into your
- source; A86 will ignore them. Or, you can write a simple
- listing tool that recognizes the PAGE directive; A86 ignores
- that directive, also.
-
- As a partial remedy to those who have not been convinced by the
- above arguments, I now have a D86 command that sends a
- disassembly to a file. The disassembly is formatted in the style
- of an assembler listing file, with locations and hex codes at the
- left. See the D86 manual for details.
-
-
- Mimicking Tool: FAKE.EXE
-
- As of this writing, Turbo C is aware only of the existence of
- Microsoft's MASM for assembling source files it generates. I
- hope to persuade Borland to provide a switch to Turbo C that
- causes it to invoke A86 directly. Until that happens, I offer
- the tool FAKE.EXE, that convinces Turbo C that A86 is really
- MASM.
-
- To use FAKE.EXE, it must be renamed MASM.EXE in your disk system.
- I would have named it MASM myself, except that
-
- 1. Bill Gates would probably get mad at me if I did, and
-
- 2. You need to decide what to do with your real MASM if you have
- it, before installing FAKE. You could either place FAKE
- (named MASM.EXE) into the individual directories containing
- Turbo C programs, or you can rename MASM to something like
- MSM.EXE or REALMASM.EXE.
-
- Having renamed FAKE.EXE to MASM.EXE, you may now use the Turbo
- C's switch, -B, that allows you to place A86 statements into your
- C program. You don't need to worry about the gory details of
- what FAKE does.
-
- If you like gory details, here they are: FAKE filters the command
- line handed to it, replacing switches:
-
- /D becomes =
- /ml becomes +c
- /mx becomes +C
- /E becomes +f
-
- FAKE also eliminates the semicolon, appends .ASM to the source
- file name, and turns on the O and S switches. It then feeds the
- resulting filtered command line to A86 for assembly.
-
-