SYMBOLS AND SOURCE DEBUG

NoICE allows the definition and use of symbols during debugging. Symbols may be defined via manual command, or automatically through the use of the symbol processing utilities.

Symbolic information may also be loaded from IEEE 695 format files, and from other types of loadable files.

Symbols may be used by the operator to specify commonly used addresses or values, and are displayed by the disassembler when an address, jump destination, or instruction argument has a value exactly equal to the value of the symbol.

NoICE symbol names may contain letters, digits, and the special characters underbar (_), period (.), dollar sign ($), or question mark (?). The first character of a name cannot be a digit. Names cannot contain period (.) if CASE has been set to 2, or "C-style", because period is used in C to denote structure and union members.

NoICE defines three types of symbols: global, base, and scoped. These may be defined by the DEFINE, DEFBASE, and DEFSCOPED commands, respectively.

Scoped symbols differ from global and base symbols in that they are active only within a certain program scope, such as within a function or a source file. For example, variables declared within a C function are considered to have "function scope". Variables declared as "static" within a C file, but not within a function; are considered to have "file scope". When debugging assembly programs, one might define all non-global symbols as "file scope" symbols.

When a symbol name is specified, NoICE will search for the symbol using C scoping rules: if the symbol is defined in the current function scope, then that value will be used. If the symbol is not defined in the current function scope, then the current file scope is searched. If the symbol is not defined in the current file scope, then the global scope is searched. Thus, the same symbol name may be defined with the same or a different value in more than one function, or in more than one file. Only one global definition of a symbol name is allowed.

The scope to be used when evaluating a symbol may be specified in one of the following ways

Under the control of a check box, the symbol list box may show all symbols, or only those which are valid in the current scope.

The value of a symbol may be defined by any expression. Of particular interest are register-relative expressions ("SP+nnn"), which are useful for declaring symbols for stack or frame based variables.


DEFINE symbol

	DEFINE name {value} {%type}

Defines a symbol called "name" with value "value", and data type "type".

"Value" is an expression, which may contain a page number, if supported by the target processor.

"Type" is the name of a data type. It specifies the data type to be used when the symbol is specified by a WATCH or EDIT command. Either a pre-defined or a user-defined type may be specified. See DEFTYPE and subsequent commands for more information about data types.

Either "value" or "type", or both, must be specified. If no type is specified during an initial definition, a default of X08 (hex byte) is used. If no value is specified during an initial definition, a default of zero is used.

A symbol may be given a new value or data type by a subsequent DEFINE command. The ability to omit either the type or value parameter allows simpler generation of symbols by source file processors: the symbol name and type may be derived from one file (for example, a C source file), while the value may be derived from a different file (for example, an assembly list or map file).

Examples:

Define "loopy" at address 1000. The default data type (hex byte) is assumed.

	DEF loopy 1000

Define "i" as a signed 16 bit integer at address 123.

	DEF i 123 %S16

Define "buff" as an array of 128 ASCII characters at address 100.

	DEF buff 100 %ASCII[128]

Define "pI" as a pointer at address 180 to an unsigned 32 bit integer.

	DEF pI 180 %*U32

Define the data type of symbol "loopy" to be IEEE floating point.

	DEF main %float

The symbol "name" may be deleted by entering

	DEFINE -name

"DEF" is an abbreviation of "DEFINE".

The command alias "SET" is provided for the convenience of users of certain Motorola/Freescale freeware assemblers, which can output symbols to a file in the form "SET name hex_value". The symbols in such a file can be defined by "executing" the file using the command

	PLAY file.ext

Utilities are provided for automated symbol definition using other assemblers.


DEFBASE: Define base symbol

	DEFBASE name {value} {%type}

Defines a symbol called "name" with value "value", and data type "type".

Base symbols differ from standard symbols in that they are used by the disassembler to show addresses in the form

	BASE+1234

where "BASE" denotes the name of the nearest base symbol whose value is less than or equal to the address in question, and "1234" is a non-negative hex integer which denotes the offset from the value of BASE.

A common usage of base symbols is to define one for each module of a program being debugged. The value of each base symbol is set equal to the address of the first byte of the code segment in the associated module. Thus, the disassembly listing will show offsets which match the offsets in the assembly listing file for the module.

A base symbol may be given a new value or data type by a subsequent DEFBASE command.

The symbol "name" may be deleted by entering

	DEFBASE -name

"DEFB" is an abbreviation of "DEFBASE".

Utilities are provided for automated symbol definition with various assemblers and compilers.


DEFSCOPED: Define scoped symbol

	DEFSCOPE name {value} {%type}

Defines a scoped symbol called "name" with value "value", and data type "type".

The value of a scoped symbol in a high-level language will often be a register-relative expression ("SP+nnnn"), if the symbol describes a stack or frame based variable.

A scoped symbol may be given a new value or data type by a subsequent DEFSCOPED command.

"DEFS" is an abbreviation of "DEFSCOPED".

Utilities are provided for automated symbol definition with various assemblers and compilers.


SCOPE: Set symbol scope

	SCOPE {name}

Sets the current scope to "name". "Name" may be the name of a file, the name of a function defined in the current file scope, the name of a global function, or a file name and a function name separated by #. If "name" is omitted, a dialog box is displayed which shows the current function and file scope, and which allows the scope to be changed.


FILE: Declare source file

	FILE filename {base}

Declares "filename" to be the current file for line number definitions using the LINE command, and for the declaration of scoped symbols.

"Base" is an optional address expression. If "base" is specified, subsequent LINE commands will add the base value to the offset contained in the LINE command. It is also considered to be the lowest code address in the file when determining symbol scope from a program address.

Multiple FILE commands may be issued for the same file. Typically, such commands will contain different base values.

If no parameters are specified, a dialog box is displayed which shows the current function and file scope, and which allows the scope to be changed.

In most cases, FILE commands will not be issued manually, but will be included within command files. Utilities are provided for automated file and line number definition with various assemblers and compilers.


ENDFILE: Declare end of a source file

	ENDFILE {endaddress}

Declares the end of the current file for the declaration of scoped symbols.

"Endaddress" is an optional address expression. If "endaddress" is specified, it is considered to be the highest code address in the file when determining symbol scope from a program address.

Multiple ENDFILE commands may be issued for the same file.

In most cases, ENDFILE commands will not be issued manually, but will be included within command files. Utilities are provided for automated file and line number definition with various assemblers and compilers.


FUNCTION: Declare a function

	FUNCTION funcname {address}

Declares "funcname" to be the current function for the declaration of scoped symbols. Functions declared with the FUNCTION command have global scope.

"Address" is an optional address expression. If "address" is specified, it is considered to be the lowest code address in the function when determining symbol scope from a program address.

If no parameters are specified, a dialog box is displayed which shows the current function and file scope, and which allows the scope to be changed.

In most cases, FUNCTION commands will not be issued manually, but will be included within command files. Utilities are provided for automated symbol definition with various assemblers and compilers.


STATICFUNCTION: Declare a function with file scope

	STATICFUNCTION funcname {address}

Declares "funcname" to be the current function for the declaration of scoped symbols. Functions declared with the STATICFUNCTION command have file scope in the current file, as if they had been declared using the C keyword "static".

"Address" is an optional address expression. If "address" is specified, it is considered to be the lowest code address in the function when determining symbol scope from a program address.

The STATICFUNCTION command with no parameters will list the currently defined functions.

In most cases, STATICFUNCTION commands will not be issued manually, but will be included within command files. Utilities are provided for automated symbol definition with various assemblers and compilers.

"SFUNC" is an abbreviation of "STATICFUNCTION".


ENDFUNCTION: Declare end of a function

	ENDFUNCTION {endaddress}

Declares the end of the current global or scoped function for the declaration of scoped symbols.

"Endaddress" is an optional address expression. If "endaddress" is specified, it is considered to be the highest code address in the function when determining symbol scope from a program address.

In most cases, ENDFUNCTION commands will not be issued manually, but will be included within command files. Utilities are provided for automated symbol definition with various assemblers and compilers.

"ENDF" is an abbreviation of "ENDFUNCTION".


LINE: Define line number

	LINE linenumber offset

Associates the specified line of the current source file (as specified by the most recent FILE command) with the specified address offset. If the most recent FILE command specified a base, then the line number is associated with the sum of the base address plus the offset given in the LINE command.

In most cases, LINE commands will not be issued manually, but will be included within command files. Utilities are provided for automated file and line number definition with various assemblers and compilers.

	LINE linenumber

If the viewer is open and the LINE command is issued with a line number but no address, the viewer will display a page beginning with the specified line of the current view file.

The LINE command with no parameters will show the number of source lines currently defined, along with the amount of line storage space available.


CLEARLINEINFO: Delete all source line information

	CLEARLINEINFO

Deletes all source line, function and file information, as well as any symbols with function or file scope. Once source line information has been defined, typically by PLAYing a command file, the information should be deleted before the command file is PLAYed again. The latest versions of most NoICE symbol file utilities insert a CLEARLINEINFO command automatically.

A confirmation dialog is shown. This can be avoided by specifying "Y" on the command line:

	CLEARLINEINFO Y
NOFILES is an alias for CLEARLINEINFO.

CLEARSYMBOLS: Delete all symbols

	CLEARSYMBOLS

Deletes all symbols currently defined.

Individual symbols may be deleted by name by using the DEFINE, DEFBASE, and DEFSCOPED commands.

A confirmation dialog is shown. This can be avoided by specifying "Y" on the command line:

	CLEARSYMBOLS Y

AUTOGENERATE: Automatically generate symbols

This command controls the automatic generation of symbols during disassembly. The command
	AUTOGENERATE  1

will enable automatic symbol generation. The command

	AUTOGENERATE  0

will disable automatic symbol generation.

When AUTOGENERATE is enabled, the disassembler will examine the destination addresses of branch, jump, and call instructions. If no symbol exists whose value is equal to the destination address, such a symbol is defined. The symbol is given a name constructed of an "L" followed by the four character hex value of the destination address. If the destination address is in a paged region, the symbol name will begin with "Pxx", where "xx" denotes the memory page of the address. Only explicit destination addresses are examined: destination addresses specified by indirect or register addressing are not processed.

To use AUTOGENERATE to assist in disassembling code, disassemble the code region once to generate the symbols, then again to view the result including all symbols. To save the disassembled output for later rework into source code, use the CAPTURE command.

The AUTOGENERATE command may be found on the SYMBOL menu.


SYMBOL: Show symbol with value "expr"

	SYMBOL expr

This command displays the symbol whose value represents the expression. If the value exactly matches a symbol, the name of the symbol will be shown. If there is no exact match, but a base symbol whose value is lower than the expression exists, the name of the base symbol and the offset from it to the value of the expression will be shown. If no appropriate symbol or base symbol is found, the message "no symbol found" will be shown.

If no expression is specified, the names and values of all defined symbols and base symbols will be shown in a dialog box.

"SYM" is an abbreviation of "SYMBOL".


CASE: Control Symbol Case Sensitivity

Symbols in NoICE are case sensitive by default. The command

	CASE 0

will disable case sensitivity. The command

	CASE 1

will enable case sensitivity. Symbols defined while case sensitivity is turned off will be stored in all upper case. The command

	CASE 3

will enable "C-style" symbols. Such symbols are case sensitive. Furthermore, the "." character is not allowed as part of such a symbol, because this character is used for structure dereferencing.


RADIX: Set numeric radix for formatted output

	RADIX {base}

WATCH and EDIT of integer data may be displayed and entered in either hexadecimal or decimal as specified by this command. "base" must be either 10 or 16, and is always entered in decimal. The selected radix preference is saved when you exit NoICE.


LEADINGDIGIT

This command determines the format for the entry of hexadecimal numbers. This feature is usually controlled via the Leading Digit Required item on the Options Menu. The command

	LEADINGDIGIT 1

will require that the first digit of any hexadecimal value be a digit in the range 0 through 9. This is useful to prevent ambiguity between values such as "ABH", which could be interpreted either as a hex value or as a symbol name.

	LEADINGDIGIT 0

will allow numbers beginning with "A" through "F" to be entered without a leading digit. Entry of hexadecimal numbers in this fashion is convenient, but may cause ambiguity with respect to symbol and register names.

The preference is saved when NoICE exits.


MODE: Set source mode

This command controls the format of the source window.

	MODE 0

sets the mode to "disassembly". The display will show disassembled processor instructions.

	MODE 1

sets the mode to "mixed source and disassembly". The display will show source file lines which produce code, interleaved with the disassembled processor instructions which correspond to the source lines.

	MODE 2

sets the mode to "source". The display will show source code, if it is available. Otherwise, disassembled processor instructions will be shown.

When NoICE starts, the mode is set to zero. When a LINE command is executed, the mode is set to two.


SOURCE: Display source at address

This command allows the user to display a program in target memory as source code, as disassembled processor instructions, or as a mixture of the two. The format of the display is determined by the MODE command and by the availability of source code and line number information.

To begin display at "addr" (where "addr" is an address expression), enter

	SOURCE addr

To continue display at the instruction after the last one shown in the source window, enter

	SOURCE

Note that if the display mode is 1 or 2, then the cursor keys may also be used to move around in the current source file.

"S" is an abbreviation of "SOURCE".


DEFTYPE: Define data type

This command is used to

	DEFTYPE offset name %type

Defines a data type or structure member called "name", at "offset" bytes from the base address, and of data type "type".

"Offset" will be zero if the DEFTYPE is being used for a typedef or a union. If the DEFTYPE is defining a member of a structure, then "offset" defines the offset of the member from the beginning of the structure.

"Type" is the name of an existing data type. It specifies the underlying data type of the newly named type. The built-in data types are:
X08unsigned hex byte or bytes (default if omitted, unless "addr" has a data type)
X16unsigned hex word (16 bits) or words
X24unsigned hex "semi-long" (24 bits) or words
X32unsigned hex long word (32 bits) or words
B08binary byte or bytes
S08signed byte or bytes in current radix
S16signed word (16 bits) or words in current radix
S24signed "semi-long" word (24 bits) or words in current radix
S32signed long word (32 bits) or words in current radix
U08unsigned byte or bytes in current radix
U16unsigned word (16 bits) or words in current radix
U24unsigned "semi-long" word (24 bits) or words in current radix
U32unsigned long word (32 bits) or words in current radix
ASCIIASCII (actually ISO-8859-1) character or characters
floatIEEE-754 floating point number (32 bits)

any previously defined user-defined data type may also be specified.

To define the standard C data type "int" as a 16 bit integer, use the command

	DEFTYPE 0 int %S16

(This definition is not built in, since "int" may be 8 or 32 bits on some processors.)

A bit field may be defined, specifying both the width in bits and the position of the least significant bit.

	DEFTYPE 6 i %S16:3@2

defines a bitfield "i" as an integer, 3 bits wide, with its least significant bit in bit2 of the 16 bit word stored at offset 6. (Note that if the processor stores word data most significant byte first, the bitfield will actually be in the byte at offset 7.)

Refer to subsequent sections for examples of the use of DEFTYPE in structures and unions. Utilities are provided for automated symbol and type definition with various assemblers and compilers.


ENUM: Define enumerated data type

	ENUM offset {name} {%type}

Begins definition of an enumeration, optionally called "name", stored as underlying data type "type". If "type" is not specified, the enumeration will be stored as a 16 bit signed integer (S16).

"Offset" will be zero if the ENUM is being defined standalone. If the ENUM is defining a member of a structure, then "offset" defines the offset of the member from the beginning of the structure.

Refer to ENDENUMfor examples of the use of ENUM. Utilities are provided for automated symbol and type definition with various assemblers and compilers.


ENUMVAL: Define value of enumerated data type

	ENUMVAL value name

Defines a numeric "value" of the last opened enumeration, and associates the string "name" with the value.

Refer to ENDENUMfor examples of the use of ENUM. Utilities are provided for automated symbol and type definition with various assemblers and compilers.


ENDENUM: End definition of enumerated data type

	ENDENUM {name}

Completes the definition of the last opened enumeration, and optionally calls it "name".

A name for the enumeration should be defined by either the ENUM command, the ENDENUM, command or by both.

Example: the C enumeration defined by

	enum color { blue, red, green=6 };
	enum color q;

may be defined in NoICE by the commands:

	ENUM 0 color %U08
	ENUMVAL 0 blue
	ENUMVAL 1 red
	ENUMVAL 6 green
	ENDENUM

	DEFINE q 1000 %color

Here we have defined an enumerated color set stored as an unsigned byte, and defined a variable of the enumerated type. If the memory byte at location 1000 contains the value 1, then WATCH q or EDIT q will show the value as "red". If the command was EDIT, then a new value may be entered as a string such as "green".

If the value of an enumerated variable does not have a defined string, then the numeric value will be displayed instead. If the string entered for an enumerated value does not match any defined value string, then the string will be interpreted as a numeric expression.

Utilities are provided for automated symbol and type definition with various assemblers and compilers.


STRUCT: Define structure or union data type

This command is used to define a structure or union.

	STRUCT offset {name}

Begins definition of a structure, optionally called "name", at "offset" bytes from the base location.

"Offset" will be zero if the STRUCT is being used to define a stand-alone structure or union. If the STRUCT is defining a structure or union which is defined inline as a member of another structure or union, then "offset" defines the offset of the member from the beginning of the outer structure.

Refer to ENDSTRUCT for examples of the use of STRUCT. Utilities are provided for automated symbol and type definition with various assemblers and compilers.


ENDSTRUCT: End definition of structure or union data type

	ENDSTRUCT size {name}

Completes the definition of the last opened structure or union, specifies its size in bytes, and optionally calls it "name".

A name for the structure or union should be defined by either the STRUCT command, the ENDSTRUCT, command or by both.

Example: the C statements

	typedef struct Bag {
	   int a;
	   char b[4]
	   struct {
	      uint b;
	      uint c;
	   } inner;
	   long int *d;
	   int bi:3;
	   int bj:4;
	} Bag2;

	struct Bag q;
	Bag2 q2;

may be defined in NoICE by the commands:

	STRUCT 0 Bag
	DEFTYPE 0 a %int
	DEFTYPE 2 b %char[4]
	STRUCT 6
	DEFTYPE 0 b %uint
	DEFTYPE 2 c %uint
	ENDSTRUCT 4 inner
	DEFTYPE 10 d %*long
	DEFTYPE 12 bi %int:3@0
	DEFTYPE 12 bj %int:4@3
	ENDSTRUCT 13 Bag2

	DEFINE q 1000 %Bag
	DEFINE q2 1010 %Bag2

Here we have defined a structure called "Bag" which contains the definition of another structure called "inner". We define "Bag2" as an alias for Bag, the result of the typdef in the C code. We define a variable of type Bag, and one of type Bag2. We have assumed that appropriate DEFTYPE definitions for "int", "char", "uint", and "long" have already been made.

Utilities are provided for automated symbol and type definition with various assemblers and compilers.

"ENDS" is an abbreviation of "ENDSTRUCT".


INTSIZE, SHORTSIZE, LONGSIZE: Set sizes of integers

These commands are intended primarily to control the interpretation of IEEE 695 files. However, the values set by these commands will also affect any use of the data types %int, %short, or %long.

	INTSIZE n

Sets the size of the C data type "int" to "n" bytes, where "n" may be 1, 2, or 4. The default value is two bytes.

	SHORTSIZE n

Sets the size of the C data type "short" to "n" bytes, where "n" may be 1, 2, or 4. The default value is two bytes.

	LONGSIZE n

Sets the size of the C data type "long" to "n" bytes, where "n" may be 1, 2, or 4. The default value is four bytes.


POINTERSIZE, SMALLPOINTERSIZE, LARGEPOINTERSIZE: Set sizes of pointers

These commands are intended primarily to control the interpretation of IEEE 695 files. However, the values set by these commands will also affect any pointer defined using size overrides. Size overrides may be generated by utilities such as OMF51NOI and 2500NOI, or by manual command.

	SMALLPOINTERSIZE n

Sets the size of a "small pointer" to "n" bytes, where "n" may be 1, 2, 3, or 4. The default value is one byte for the 8051 and 6502, whose architecture make one-byte pointers meaningful, and two bytes for the other processors. In addition to IEEE 695 small pointers, this definition will be used for a pointer defined with a "small" size override (<). For example,

	DEF pInt 0 %<*S16

defines the variable "pInt" at location zero to be a small pointer to S16.

	LARGEPOINTERSIZE n

Sets the size of a "large pointer" to "n" bytes, where "n" may be 1, 2, 3, or 4. The default value is two bytes. In addition to IEEE 695 large pointers, this definition will be used for a pointer defined with a "large" size override (>). For example,

	DEF pInt 0 %>*S16

defines the variable "pInt" at location zero to be a large pointer to S16.

	POINTERSIZE n

Sets the size of a default pointer to "n" bytes, where "n" may be 1, 2, 3, or 4. The default value is two bytes. This should seldom, if ever, need to be changed. This command is provided to deal with special needs of compilers for the 8051 and similar processors with multiple memory models.

Up to ten levels of pointer indirection may be defined, and size overrides may be used at any level. For example,

	DEF pppMess 0 %<**>*S16

defines the variable "pppMess" at location zero to be a small pointer to a default (address sized) pointer to a large pointer to S16.


FRAMEPOINTER: Define frame pointer register

This command is intended primarily to control the interpretation of IEEE 695 files. It defines the processor register to be used as the base register for automatic variables allocated on the stack.

	FRAMEPOINTER X

sets the frame pointer to register "X". The default value is "SP" for most processors. The framepointer must be set to match your compiler before an IEEE 695 file is loaded. The most common place to do this is in NOICE.NOI.

Before loading an Introl IEEE 695 file for the 68HC11, you must set

	FRAMEPOINTER SP+1

because Introl generates offsets relative to the value in X after a TSX instruction, which increments the SP value.

Before loading an IAR IEEE 695 file for the Z80, you must set

	FRAMEPOINTER IX

For other processors or compilers, consult your compiler documentation, or examine the generated code to see which register is being used as a frame pointer. (Compilers for processors like the 8051 typically do not use a framepointer. For these compilers, you may ignore this command.)


LASTFILELOADED {filename}

When a program is changed and rebuilt, code and data addresses often move so that breakpoints, watches, etc. are no longer valid.

The LASTFILELOADED command deletes breakpoints, watches, symbols, and line information if the specified filename or its modification time have changed from the last invocation of this command. If the file has not changed, then breakpoints, watches etc. are preserved.

LASTFILELOADED is usually specified as the first command within a .NOI file. In this case, the filename may be omitted and name and modification time of the .NOI file are used.


NoICE (tm) Debugger, Copyright © 2005 by John Hartman

Using NoICE - Contact us - NoICE Home