Sierra C™ Assembler Reference Manual, Beta Version .02
Important information
Texas Instruments makes no warranty, either expressed or implied, including but not limited to
any implied warranties of merchantability and fitness for a particular purpose, regarding any
programs or book materials and makes such materials available solely on an “as-is” basis.
In no event shall Texas Instruments be liable to anyone for special, collateral, incidental, or
consequential damages in connection with or arising out of the purchase or use of these
materials, and the sole and exclusive liability of Texas Instruments, regardless of the form of
action, shall not exceed the purchase price of this product. Moreover, Texas Instruments shall
not be liable for any claim of any kind whatsoever against the use of these materials by any
other party.
The latest version of this Guide, along with all other up-to-date information for developers, is
available at www.ti.com/calc/developers/.
Table 1.24: Type Entries by Storage Class ................................................................................30
Table 1.25: Auxiliary Symbol Table Entries................................................................................31
Table 1.26: Auxiliary Symbol Entry for Filenames......................................................................32
Table 1.27: Auxiliary Symbol Entry for Sections.........................................................................32
Table 1.28: Auxiliary Symbol Entry for Functions.......................................................................33
Table 1.29: Auxiliary Symbol Entry for Beginning of Blocks and Functions................................33
Table 1.30: Auxiliary Symbol Entry for End of Blocks and Functions .........................................33
Table 1.31: Auxiliary Symbol Entry for Arrays ............................................................................34
Table 1.32: Auxiliary Symbol Entry for Tag Names....................................................................34
Table 1.33: Auxiliary Symbol Entry for End of Structures...........................................................35
Table 1.34: Auxiliary Symbol Entry for Structures, Unions, Enumerations.................................35
Table 1.35: Example String Table...............................................................................................36
TI-89 / TI-92 Plus Sierra C Assembler Reference Manual
Not for Distribution
Beta Version February 2, 2001
4Section 1: General Information
TI-89 / TI-92 Plus Sierra C Assembler Reference Manual
Not for Distribution
Beta Version February 2, 2001
1. General Information
1.1. Introduction
This manual describes the Sierra tools, including the compiler, assembler, and
linker invoked by the TI
(apps) and Assembly Language Programs (ASMs) for the TI-89 / TI-92 Plus
calculators, and other Plusutilities that are available to the developer. They were
developed by Sierra Systems to support certain Motorola processors and
coprocessors and IEEE format floating-point numbers. Under license from Sierra
Systems, Texas Instruments has modified this software to support TI BCD
floating-point numbers, and support for coprocessors has been removed.
Although the software has not been modified to exclude support for processors
other than the 68000, the 68000 is the only processor supported by Texas
Instruments. The license from Texas Instruments to use these products is
restricted to development of software that is targeted to execute only on TI
calculators.
FLASH
Studio™ for development of Flash applications
5
Typically, the TI
assembler, and linker but information is included in the various sections to enable
developers to use them directly from the command line or create their own
makefile if they wish, although this is not encouraged.
Section 1 contains information that applies to all the tools and describes the
format of the object file generated.
Section 2 discusses features of the Sierra Systems C compiler,
include number formats, function calls, integer and floating-point arithmetic,
sections, register allocation, macros, possible error messages, and many others.
Section 3 describes both Sierra Systems assemblers:
the TI
wish to take advantage of the macro support it provides. Explanations of
assembler syntax, symbols, constants, expression evaluation, addressing
modes, and complete descriptions of assembler directives for both assemblers
and the
Section 4 is a brief discussion of the Sierra Systems linker,
its features including relocation hole compression.
Section 5 describes the Sierra Systems utilities
part of the TI-89 / TI-92 Plus SDK for use by developers.
FLASH
asm68k
FLASH
Studio, and
macros are in this section.
Studio will handle all invocations of the compiler,
. These
, and some of
, provided as
asm68k
com68
asm68
which is included for developers who may
and
nm68
which is invoked by
link68
size68
TI-89 / TI-92 Plus Sierra C Assembler Reference Manual
Not for Distribution
Beta Version February 2, 2001
6
Section 1: General Information
Conventions used throughout this manual include:
text is used for names of functions, routines, files, keywords, directives,
Bold
•
macros, flags, and registers. It is also used occasionally for emphasis.
•
•
The
Courier
Italicized
font is used to distinguish assembly or C program text.
text indicates an input parameter that should be replaced by actual
data when used in code or entered on the command line.
Brackets ( [ ] ) enclose optional items.
•
The vertical bar ( | ) indicates that the separated items are alternatives.
•
1.2. Command Line Wildcard Expansion
A number of Sierra C™ utilities expand wildcards in command line filenames.
Wildcard characters are defined as follows:
*
?
[
char_set
Match zero or more characters, where characters matched may be any
character except the period (
string matches files with and without extensions.
Match any character except the period (.).
]
Match any character in the character set
listed individually or as members of a range. A range is denoted by a
hyphen (
and all characters lexically between them.
-
) separated pair of characters; it includes the two characters
.
). Dot-star (.*) at the end of a wildcard
char_set
. Characters can be
The following are examples of wildcard expansions:
*.*
*
*.?*
*.c *.s
*.[cs]
Match all filenames in the current directory.
Match all filenames without extensions in the current directory.
Match all filenames with extensions in the current directory.
Match all filenames with extensions of .c or .s in the current directory.
Same as
*.c *.s
c:\doc\version[0-9a-f].doc
Match all filenames in the subdirectory
version followed by a hexadecimal digit and a
TI-89 / TI-92 Plus Sierra C Assembler Reference Manual
Not for Distribution
with a base name of
c:\doc
extension.
.doc
Beta Version February 2, 2001
Section 1: General Information
The following Sierra C utilities support command line wildcard expansion:
7
nm68
size68
Symbol Table Name Utility
Object File Size Utility
1.3. Environment Variables
Some Sierra C utilities need to know the location of certain standard directories
to locate various files. For example, the compiler must know where to search for
files specified by the
#include
information varies depending on the installation, the utilities examine
environment variables to obtain information on the locations of these standard
directories.
Figure 1.1 shows the default standard include (
executable (
), and temporary (
bin
subdirectory names to the directory specified by the
variable. The
for the TI
FLASH
SIERRA
environment variable will be set when the setup program
Studio is executed. The
set before using any of the Sierra utilities.
sierra
filename
tmp
preprocessor directive. Since this
include
), standard library (
lib
),
) directories that are created by appending
environment
SIERRA
SIERRA
environment variable must be
include lib bin tmp
Figure 1.1: Partial Sierra C Directory Structure
Table 1.1 lists the environment variables referenced by Sierra C utilities together
with the utilities that reference the variables and the files that are referenced.
Variable Utility Files referenced
INCLUDE68 com68
LIB68 link68
link68
Table 1.1: Environment Variables
standard include files
standard libraries
default configuration file
Depending on which environment variables are set, the utilities that generate
temporary files will put their files in one of four places. The three environment
variables
TMP68, TMP
search terminating after the first defined variable is located. If either
is defined, the directory specified by that environment variable is used to
TMP
hold temporary files. If the
, and
SIERRA
SIERRA
environment variable is the only variable
are searched for in the order listed with the
TMP68
or
TI-89 / TI-92 Plus Sierra C Assembler Reference Manual
Not for Distribution
Beta Version February 2, 2001
8
Section 1: General Information
defined, the
subdirectory located under the directory specified by
tmp
used to hold temporary files. If none of the three environment variables is
specified, the current directory is used to hold temporary files.
The C preprocessor searches for the two environment variables
SIERRA
directories. If
in the order listed to determine the locations of the standard include
INCLUDE68
is defined, the semicolon-separated list of one or more
directory paths defines the standard include directories. If the
environment variable is the only variable defined, the
located under the directory specified by
directory.
Utilities that search for files in standard include directories search for the two
environment variables
LIB68
locations of the standard include directories. If
semicolon-separated list of one or more directory paths defines the standard
library directories. If the
defined, the
subdirectory located under the directory specified by
lib
SIERRA
used as the standard library directory.
1.4. Object File Format
INCLUDE68
SIERRA
subdirectory
and
SIERRA
SIERRA
include
is used as the standard include
in the order listed to determine the
LIB68
is defined, the
environment variable is the only variable
SIERRA
SIERRA
is
and
is
This section describes the Common Object File Format (COFF) used by
TI
FLASH
assemblers and linker, and recognized by TI
Studio. COFF is the format of the object files created by the
FLASH
Studio and various object
file examination utilities. COFF is a standard file format and the Sierra Systems
implementation (with extensions disabled, -c assembler command line flag)
completely conforms to the format recognized by the AT&T UNIX System V
operating system.
COFF is ideally suited for developing embedded applications. Space is provided
for symbol and line number information used by debuggers and other
applications. Executable files can be divided into numerous independent sections
to allow support for systems with highly fragmented address spaces.
An object file contains the following:
A file header
•
Optional header information
•
A table of section headers
•
Data corresponding to the section header
•
Relocation information
¦
Line numbers
¦
A symbol table
¦
A string table
¦
TI-89 / TI-92 Plus Sierra C Assembler Reference Manual
Not for Distribution
Beta Version February 2, 2001
Section 1: General Information
Table 1.2 shows the overall object file structure.
FILE HEADER
Optional Information
Section 1 Header
. . .
Section n Header
Raw Data for Section 1
. . .
Raw Data for Section n
Relocation Info. for Section 1
. . .
Relocation Info. for Section n
Line Numbers for Section 1
. . .
9
Line Numbers for Section n
SYMBOL TABLE
STRING TABLE
Table 1.2: Object File Layout
Some or all of the last four sections (relocation, line number, symbol table, and
string table) may be missing from the final executable file. If the program is linked
with the -s flag, all four of these sections will be absent. The line number
information does not appear unless the program is compiled with the -q or
debug flag or assembled with the -L line number flag. If there are no unresolved
external symbols after linking, the relocation information is no longer needed and
is thus absent. If there are no symbols with names longer than eight characters,
the string table is not needed and is thus absent.
-q1
TI-89 / TI-92 Plus Sierra C Assembler Reference Manual
Not for Distribution
Beta Version February 2, 2001
10
1.4.1. Definitions and Conventions
Before continuing, you should become familiar with the following terms and
conventions.
1.4.1.1. Sections
A section is the smallest portion of an object file that is relocated and able to be
positioned at an independent location in memory. In the default case, there are
three named sections with the names
executable file, there is also usually a fourth section with the name
TI-89 / TI-92 Plus apps and ASMs also have a
section is unused. Additional named and unnamed sections, up to a total of 126,
can also be added.
1.4.1.2. Physical and Virtual Addresses
The address of a section or symbol is the offset of that section or symbol from
address zero of the address space. The
memory where a section is loaded. The
address from which the section's data will execute. When a section's data has to
be copied from ROM to RAM at program startup, the ROM copy (source) of the
section's data is considered to be at the physical address and the RAM copy
(destination) of the section's data is considered to be at the virtual address. The
section header contains two address fields: a physical address and a virtual
address. In the case where a section's data gets copied from ROM to RAM, the
physical and virtual address entries will be different; but in the case where a
program executes out of ROM, the physical and virtual address entries for the
section's data will be the same.
Section 1: General Information
.text, .data
physical address
virtual address
, and
.const
. In a Sierra Systems
.bss
.ld_tbl
section, and the
is the actual location in
of a section is the
.ld_tbl
.
1.4.1.3. C Language COFF File Structures
The C language COFF file structures and macro definitions used internally by the
various Sierra Systems utilities that operate on object files are defined in the file
file_fmt.txt
members of type (
defined as
structure members are represented as arrays of
generating identical object files on host machines with different internal byte
orderings. Machine-dependent macros for reading and writing the structures in
file_fmt.txt
TI-89 / TI-92 Plus SDK.
TI-89 / TI-92 Plus Sierra C Assembler Reference Manual
supplied with the TI-89 / TI-92 Plus SDK. Note that structure
unsigned) char
unsigned char
are defined in file
arrays of length 1, 2, and 4, respectively. The
, (
unsigned) short
com_fmt.txt
Not for Distribution
, and (
unsigned char
, also supplied with the
unsigned) long
Beta Version February 2, 2001
are
to facilitate
Section 1: General Information
1.4.2. File Header
The file header contains the 20 bytes of information shown in Table 1.3. The last
two bytes are flags that are used by the linker and other object file utilities.
Defined in
file_fmt.txt
file header structure and file header size, respectively.
BytesDeclaration Name Description
are
FILE_HDR
and
FILE_HDR_SIZE
, the typedefs for the
11
0-1
2-3
4-7
8-11
12-15
16-17
18-19
unsigned short fh_magic
unsigned short fh_nbr_sections
unsigned long fh_time_date
unsigned long fh_symtab_ptr
unsigned long fh_nbr_symtab_ents
unsigned short fh_size_opt_hdr
unsigned short fh_flags
1.4.2.1. Magic Number
The
magic number
executed. The number 0x150 identifies the object file as a 68000 family
executable file. The number 0x150 is the only number recognized by the various
Sierra Systems utilities; an error will be reported if a file that does not begin with
0x150 is encountered.
Magic number, 0x150
Number of section headers (equals the
number of sections)
Time and date stamp indicating when the
file was created (expressed as the
number of seconds since 00:00:00 GMT,
January 1, 1970)
File pointer containing the starting offset
of the symbol table
Number of entries in the symbol table
Number of bytes in the optional header
Flags (see Table 1.4)
Table 1.3: File Header Contents
specifies the target machine on which the object file can be
1.4.2.2. Optional Header Size
The optional header shown in Table 1.5 is system-dependent and not specified
by the COFF standard. The size of the optional header is specified in the file
header to allow system-independent object file utilities to skip past the optional
header.
TI-89 / TI-92 Plus Sierra C Assembler Reference Manual
Not for Distribution
Beta Version February 2, 2001
12
1.4.2.3. Flags
The last two bytes of the file header are flags that describe the type of the object
file. The file header flags are described in Table 1.4.
The optional header contains information that varies among the systems that use
COFF. Applications place all system-dependent information in the optional
header. As previously stated, system-independent COFF utilities can skip past
the system-dependent optional header to perform tasks such as dumping the
symbol table.
Bytes Declaration Name Description
0-1
unsigned short magic
0x01 Relocation information stripped from file
0x02 File is executable (i.e., no unresolved references)
0x04 Line numbers stripped from file
0x08 Local symbols stripped from file
0x10 Global symbols stripped from file
0x80 Error in object file
unsigned short version
unsigned long tsize
unsigned long dsize
unsigned long bsize
unsigned long entry
unsigned long text_start
unsigned long data_start
Table 1.5: Sierra Systems Optional Header Contents
The Sierra Systems optional header is 28 bytes long, and the fields of the
optional header are described in Table 1.5. The optional header is present only
on linked executable files; it is not present on assembler-generated files or
partially linked files (-r flag). Defined in
A_OUT_HDR_SIZE
, the typedefs for the optional header structure and optional
header size, respectively.
TI-89 / TI-92 Plus Sierra C Assembler Reference Manual
Version stamp
Size of text in bytes
Size of initialized data in bytes
Size of uninitialized data in bytes
Program entry point
Base address of text
Base address of data
file_fmt.txt
Not for Distribution
are
A_OUT_HDR
and
Beta Version February 2, 2001
Section 1: General Information
1.4.4. Section Headers
Every object file has one section header for each section in the file. The Sierra
Systems object file has at least three section headers. The section headers
describe the organization of data within the file. Table 1.6 describes the fields of
the section header. Defined in
SECTION_HDR_SIZE
, the typedefs for the section header structure and section
file_fmt.txt
header size, respectively.
The size of a section is always padded to a multiple of four bytes.
The file pointers are byte offsets from the beginning of the file, and can be used
to locate the start of the data, relocation, or line entries for the section.
char sh_name
unsigned long sh_phys_addr
unsigned long sh_virt_addr
unsigned long sh_size
unsigned long sh_data_ptr
unsigned long sh_reloc_ptr
unsigned long sh_line_nbr_ptr
unsigned short sh_nbr_reloc_ents
unsigned short sh_nbr_line_ents
unsigned long sh_flags
Table 1.6: Section Header Contents
8-character null-padded section name
Physical address of section
Virtual address of section
Section size in bytes
File pointer to raw data
File pointer to relocation entries
File pointer to line number entries
Number of relocation entries
Number of line number entries
Flags (see Table 1.7)
TI-89 / TI-92 Plus Sierra C Assembler Reference Manual
Not for Distribution
Beta Version February 2, 2001
14
Section 1: General Information
The
field defines the type of the section. Table 1.7 lists the definitions of the
0x000 Regular section: alloc'd, not reloc'd, load'd
0x001 Dummy section: not alloc'd, reloc'd, not load'd
0x002 No load section: alloc'd, reloc'd, not load'd
0x002 Resident section: alloc'd, reloc'd, not load'd
0x004 Grouped section: formed from input sections
0x008 Padding section: not alloc'd, not reloc'd, load'd
0x008 Fill only section: filled at run-time
0x010 Copy section: copied at run-time from destination address to
virtual address
0x020 Section contains executable text
0x040 Section contains initialized data
0x080 Section contains only uninitialized data
0x100 Section contains
'd (absolute) data
ORG
SH_INFO
SH_OVERT
SH_LIB
0x200 Comment section: not alloc'd, not reloc'd, not load'd
0x400 Overlay section: not alloc'd, reloc'd, not load'd
0x800 Library section
Table 1.7: Section Header Flags
All sections, including sections with uninitialized data such as section
static storage), have an associated section header. Uninitialized sections have
symbols that refer to them and symbols that are defined in them, but they do not
have any relocation entries, line number entries, or data associated with them.
Therefore, uninitialized sections have a section header, but occupy no other
space in the object file. In the case of an uninitialized section, zeroes appear in
the fields for the number of relocation and line number entries, as well as in the
fields for all the file pointers.
1.4.5. Relocation Information
Object files have one relocation entry for each relocatable reference in a
text-type or data-type section. The relocation entries are automatically generated
by the assembler, and the information is used by the linker to resolve external
references. Table 1.8 describes the information carried in the object file for each
relocatable reference. Defined in
RELOC_INFO_SIZE
relocation entry size, respectively.
, the typedefs for the relocation entry structure and
file_fmt.txt
are
RELOC_INFO
and
.bss
(blank
TI-89 / TI-92 Plus Sierra C Assembler Reference Manual
Not for Distribution
Beta Version February 2, 2001
Section 1: General Information
Bytes Declaration Name Description
15
0-3
4-7
8-9
unsigned long r_virt_addr
unsigned long r_sym_index
unsigned short r_type_info
Virtual address of reference
Symbol table index
Relocation type (see Table 1.9)
Table 1.8: Relocation Section Contents
The first field of the relocation entry is the virtual address of the text or data to
which the entry applies. The 1-, 2-, or 4-byte area referenced by this first field is
known as a hole since the assembler cannot resolve the reference. The address
or PC-relative offset is ultimately determined and written to the hole by the linker.
The second field is the index of the symbol table entry for the symbol that is
being referenced. The third field indicates the type of relocation that is to be
applied. Table 1.9 lists the relocation types supported by Sierra Systems.
Mnemonic Flag Meaning
RL_FIXED
RL_DIR_BYTE
RL_DIR_WORD
RL_DIR_LONG
0x00 Reference is absolute, no relocation is necessary, the entry
will be ignored
0x0F Direct 8-bit reference to symbol's virtual address
0x10 Direct 16-bit reference to symbol's virtual address
0x11 Direct 32-bit reference to symbol's virtual address
There are two types of relocation: absolute and PC-relative. The assembler
reduces an unresolved reference to an offset from a relocatable section or an
offset from an external symbol. The offset is saved in the hole and the index of
the symbol (external symbol or section name symbol) is saved in the relocation
entry. In addition, if the reference is PC-relative, the address or section-relative
offset of the hole is subtracted from the contents of the hole.
0x12 A PC-relative 8-bit reference to symbol's virtual address
0x13 A PC-relative 16-bit reference to symbol's virtual address
0x14 A PC-relative 32-bit reference to symbol's virtual address
0x40 Operator in a complex relocatable expression
0x50 Absolute operand in a complex relocatable expression
0x60 Relocatable operand in a complex relocatable expression
0x70 External operand in a complex relocatable expression
Table 1.9: Relocation Types
TI-89 / TI-92 Plus Sierra C Assembler Reference Manual
Not for Distribution
Beta Version February 2, 2001
16
The linker, which knows the addresses of all symbols, adds the address of the
symbol referenced by the
addition, if the reference is PC-relative and the hole is in a relocatable section,
the base address of this section is subtracted from the contents of the hole.
In the case of byte or word references (1-byte or 2-byte holes, respectively), it is
possible that the final value determined by the linker will fit in the hole but the
intermediate value to be filled in by the assembler will not fit. Sierra Systems has
added an extension to the COFF standard to remove this deficiency. In the
relocation entry, the higher order byte of the
order byte of the
r_sym_index
are unused. In the case of a 1-byte or 2-byte hole, the overflow first goes into the
unused byte in
r_sym_index
effectively providing the assembler with a 24-bit or 32-bit hole, respectively.
1.4.5.2. Complex Relocation
A complex relocatable expression is an expression that cannot be reduced at
assembly time to either an absolute value or a section-relative reference. For
example, an expression that references multiple external symbols and/or
symbols from different relocatable sections would be classified complex
relocatable.
r_sym_index
field (assuming fewer than 16 million symbols)
and then into the unused byte in
field to the contents of the hole. In
Section 1: General Information
r_type_info
field and the highest
r_type_info
A complex relocatable expression is saved in a sequence of auxiliary relocation
entries that follow the primary entry for the relocation hole. A separate entry is
used for each operand and each operator in the expression. Table 1.10
describes the different types of complex relocation entries. The complex
expression contained in the auxiliary relocation entries is subsequently evaluated
by the linker, and the result is placed in the hole referenced by the primary entry.
set to designate the start of a complex relocatable expression.
TI-89 / TI-92 Plus Sierra C Assembler Reference Manual
Not for Distribution
Beta Version February 2, 2001
Section 1: General Information
1.4.6. Line Number Information
The line number information in the object file is used for source-level debugging.
Line number information is present when C files are compiled with the -q or
debug flag or assembly language files are assembled with the -L line number
flag. When compiled or assembled with one of the above listed flags, a line
number entry is generated for every line of C or assembly language code. The
line number entries are grouped by section and within each section grouping the
entries are grouped by function as shown in Table 1.11.
symbol index 0
virtual address line number
virtual address line number
. . . . . .
symbol index 0
virtual address line number
-q1
17
virtual address line number
Table 1.11: Line Number Grouping
Table 1.12 describes the fields within a line number entry. Defined in
are
LINE_NBR
and
LINE_NBR_SIZE
structure and line number entry size, respectively.
Bytes Declaration Name Description
0-3
0-3
4-5
unsigned long l_sym_index
unsigned long l_phys_addr
unsigned short l_line_nbr
Table 1.12: Line Number Section Contents
The first line number entry within a function grouping specifies line number 0 and
has, in place of the virtual address, an index into the symbol table for the entry
containing the name of the function. The subsequent entries have the actual line
numbers relative to the open brace ' { ' that begins the function, and the address
of the text that corresponds to the line number. The line number entries are
ordered by increasing address.
file_fmt.txt
, the typedefs for the line number entry
Symbol table index of function
Address of source line
Source line number
The
(begin function) symbol entry immediately follows the auxiliary entry for
.bf
the function name symbol. The absolute C source line number of the function's
open brace is specified in the auxiliary entry for the
1.4.9.4 Beginning of Blocks and Functions
TI-89 / TI-92 Plus Sierra C Assembler Reference Manual
). Absolute C source line numbers
Not for Distribution
symbol (see section
.bf
Beta Version February 2, 2001
18
for all other lines in a function are computed by offsetting the relative line
numbers in the line number entries by the absolute line number in the
symbol's auxiliary entry.
1.4.7. Symbol Table
Because of symbolic debugging requirements, the order of the symbols within
the symbol table is very important. The symbols appear in the order shown in
Table 1.13.
filename 1
function 1
local symbols for function 1
function 2
local symbols for function 2
. . .
Section 1: General Information
.bf
statics for file 1
. . .
filename 2
local symbols for function 1
. . .
statics for file 2
. . .
all defined global symbols
all undefined global symbols
Table 1.13: COFF Symbol Table
Local symbols for a function are the symbols that are defined within a function
and accessible only within that function. The term statics as used in Table 1.13
identifies symbols that are C language variables of storage class
outside any function. The symbol table consists of at least one 18-byte entry per
symbol with some symbols followed by one or more auxiliary entries also 18
bytes each. A symbol table entry contains the name of the symbol (or file offset
to the name), the value, the type, and other information.
static
defined
TI-89 / TI-92 Plus Sierra C Assembler Reference Manual
Not for Distribution
Beta Version February 2, 2001
Section 1: General Information
1.4.7.1. Special Symbols
Included in the symbol table are special symbols that are generated by the
compiler and assembler. Most of the special symbols are needed for source-level
debugging. Table 1.14 lists the special symbols.
Symbol Meaning
19
.file
.text
.data
.bss
.bb
.eb
.bf
.ef
.
target
.xfake
.eos
_etext
_edata
_end
Table 1.14: Special Symbols in the Symbol Table
Six of the special symbols are used in pairs. The
encapsulate the symbols defined in inner blocks. The
encapsulate each function. The
unnamed structures, unions and enumerations. The
Filename
Address of
Address of
Address of
Address of start of inner block
Address of end of inner block
Address of start of function
Address of end of function
Pointer to structure or union returned by function
Dummy tag name for structure, union, or enumeration
End of members of structure, union, or enumeration
Next available address after the end of the output section
Next available address after the end of the output section
Next available address after the end of the output section
.text
.data
.bss
section
section
section
x
.
fake
and
and
.bb
symbols define the limits of
.eos
.eb
and
.bf
symbol is also paired
.eos
.text
.data
.bss
symbols
symbols
.ef
with actual names to define the limits of named structures, unions, and
enumerations.
When a structure, union, or enumeration is defined without a tag, the compiler
automatically generates a name for internal use. The generated name is
where
is a unique decimal number. In the case where a file defined three
x
unnamed structures, structure tags with the names
would be generated.
TI-89 / TI-92 Plus Sierra C Assembler Reference Manual
Not for Distribution
.0fake, .1fake
Beta Version February 2, 2001
, and
x
fake
.
.2fake
,
20
1.4.7.2. Inner Blocks
The C language defines a block as a compound statement that begins with an
open brace ' { ' and ends with a balancing close brace ' } '. An inner block is a
block that exists within a function (which is also a block). For each inner block
that has local symbols defined in it, the special symbol
symbol table immediately before the first local symbol of the block. Analogously,
the special symbol
local symbol of the block. Because inner blocks can be nested to multiple levels,
the
.bb
–
symbol pairs and associated symbols can also be nested.
.eb
Table 1.15 shows an example of nested C language blocks and the associated
symbol table.
Nested Blocks Symbol Table
func1( int a ) _func1
{.bf
int b; a
is inserted in the symbol table immediately after the last
.eb
Section 1: General Information
is inserted in the
.bb
{b
int c; .bb
{c
int d; .bb
}d
} .eb
} .eb
.ef
func2( int e ) _func2
{.bf
int f; e
int g; f
{g
int h; .bb
}h
} .eb
.ef
Table 1.15: Example Symbol Table for Functions
and Nested Blocks
TI-89 / TI-92 Plus Sierra C Assembler Reference Manual
Not for Distribution
Beta Version February 2, 2001
Section 1: General Information
1.4.7.3. Symbols and Functions
21
For each function, a special symbol
first local symbol of the function name in the symbol table. Correspondingly, a
special symbol
is put immediately after the last symbol of the function in the
.ef
symbol table. Associated with the
auxiliary symbol table entries) are the absolute line numbers of the function's
open brace ' { ' and close brace ' } ', respectively. The example in Table 1.15 (in
addition to showing nested inner blocks) shows a pair of C language functions
and the associated symbol table.
1.4.8. Symbol Table Entries
All symbols, regardless of their type and storage class, use the same symbol
table format. Every symbol table entry occupies 18 bytes. Table 1.16 describes
the fields within a symbol table entry. It should be noted that the indices for
symbol table entries begin with 0 (not 1). Also, auxiliary entries count as symbol
entries for purposes of indexing into the symbol table. Defined in
SYM_ENT
structure and symbol table entry size, respectively.
BytesDeclaration Name Description
and
SYM_ENT_SIZE
is put between the function name and the
.bf
.bf
and
symbols (as defined by their
.ef
file_fmt.txt
, the typedefs for the symbol table entry
are
0-7
0-3
4-7
8-11
12-13
14-15
16
17
char sym_name
unsigned long sym_zeroes
unsigned long sym_offset
unsigned long sym_value
unsigned short sym_sec_nbr
unsigned short sym_type
char sym_sclass
char sym_nbr_aux
Table 1.16: Symbol Table Entry
8-character null padded symbol name
Zero in this field indicates the name is in the
string table
Offset of the name in the string table
Symbol value (storage class dependent)
Section number of symbol
Basic and derived type information
Storage class of symbol
Number of auxiliary entries
TI-89 / TI-92 Plus Sierra C Assembler Reference Manual
Not for Distribution
Beta Version February 2, 2001
22
1.4.8.1. Symbol Names
The symbol name resides either within the 18 byte symbol table entry itself or in
a string table at the end of the object file. The first eight bytes of the symbol table
entry are a union of an eight byte character array and two longs. If the symbol
name is eight or fewer characters in length, the symbol name (null padded) is
stored in the first eight bytes of the symbol table entry. If the symbol name is
longer than eight characters, the entire null-terminated symbol name is stored in
the string table. When the symbol name is stored in the string table, the first four
bytes of the symbol table entry are zero and the second four bytes contain the
offset (relative to the beginning of the string table) of the name in the string table.
Since there cannot be a symbol with a null name, the zeroes in the first four
bytes distinguish a symbol table entry with an offset into the string table from a
symbol table entry with a name in the first eight bytes.
1.4.8.2. Storage Class
The storage class field is assigned one of the values described in Table 1.17.
The mnemonics listed in the table are defined in
Section 1: General Information
file_fmt.txt
.
All the storage classes that appear in the object file except for
generated by the assemblers,
is generated by the linker,
link68 (-P
asm68
and
asm68k
. The storage class
flag not specified), when it removes
C_ALIAS
are
C_ALIAS
duplicate structure, union and enumeration definitions and places alias entries in
their places.
Note that not all the storage classes listed in Table 1.17 appear in the object file.
Some of the storage classes such as
C_SKIP
are used only internally by the compiler and assemblers.
C_EFCN, C_ARRAY, C_SUE
, and
TI-89 / TI-92 Plus Sierra C Assembler Reference Manual
-1Physical end of function
0
1Automatic variable
2External symbol
3Static
4Register variable
5External definition
6Label
7Undefined label
8Member of structure
9Function argument
10Structure tag
11Member of union
12Union tag
13Type definition
14Uninitialized static
15Enumeration tag
16Member of enumeration
17Register parameter
18Bit field
19Array dimension information
20Structure, union, or enumeration
21Symbol that should not be output
100Beginning and end of block
101Beginning and end of function
102End of structure
103Filename
105Duplicate tag
106Like static, used to avoid name conflicts
Table 1.17: Storage Classes
TI-89 / TI-92 Plus Sierra C Assembler Reference Manual
Not for Distribution
Beta Version February 2, 2001
24
1.4.8.3. Storage Classes for Special Symbols
Some of the special symbols listed in Table 1.14 are restricted to certain storage
classes. Table 1.18 lists the restricted special symbols with their allowed storage
classes. Also, the storage classes
used only with the special symbols they are shown associated with in Table 1.18.
TI-89 / TI-92 Plus Sierra C Assembler Reference Manual
Not for Distribution
Beta Version February 2, 2001
Section 1: General Information
1.4.8.4. Symbol Value Field
The interpretation of the value of a symbol is a function of the symbol's storage
class. Table 1.19 summarizes the relationship between storage class and value.
Stack offset in bytes
Relocatable address
Relocatable address
Register number
Relocatable address
Offset in bytes
Stack offset in bytes
0
0
0
0
0
Enumeration value
Register number
Bit displacement
Relocatable address
Relocatable address
C_EOS
C_FILE
C_ALIAS
C_HIDDEN
Size
(see text below)
Tag index
Relocatable address
Table 1.19: Storage Class and Value
If a symbol has storage class
table entry index of the next
C_FILE
symbol. The
.file
list within the symbol table. The value of the last
index of the first global symbol.
Relocatable symbols have a value that is equal to the virtual address of the
symbol. When a section is relocated by the linker, the values of the section's
relocatable symbols change.
TI-89 / TI-92 Plus Sierra C Assembler Reference Manual
, the value of the symbol is the symbol
entries form a one-way linked
.file
symbol table entry is the
.file
Not for Distribution
Beta Version February 2, 2001
26
1.4.8.5. Section Number Field
Section numbers are listed in Table 1.20.
Mnemonic Section Number Meaning
Section 1: General Information
N_DEBUG
N_ABS
N_UNDEF
N_SCNUM
Table 1.20: Section Number
-2 Special symbolic debugging symbol
-1 Absolute value
0 Undefined external symbol
1-126 Section number where symbol is defined
Section number -2 identifies symbolic debugging symbols, including structure,
union and enumeration tag names, typedefs, and filenames. Section number -1
identifies symbols that have a non-relocatable (absolute) value. Examples of
absolute-valued symbols include automatic and register variables, function
arguments, structure members and
symbols. The
.eos
.text, .data
, and
.bss
sections typically default to section numbers 1, 2, and 3, respectively.
With one exception, section number 0 identifies a relocatable external symbol
that is not defined in the current file. The one exception is the external symbol
generated as the result of defining an uninitialized external variable. The ANSI C
standard permits only a single defining instance (initialized or uninitialized) of a
particular variable. To permit compatibility with early C environments, multiple
defining instances of uninitialized variables are permitted when the linker is
invoked with the -C command line flag. In each file where the symbol for the
uninitialized variable is defined, the section number of the symbol is 0, and the
value of the symbol is representative of the size and alignment of the symbol.
The size of the symbol occupies bits 0 – 29 and the symbol alignment occupies
bits 30 and 31. The alignment is a Sierra Systems extension to COFF where bits
30 and 31 low indicate quad alignment, bit 30 high (31 low) indicates even
alignment, and bit 31 high (30 low) indicates no alignment required. When the
files are combined into an executable object file, the linker (-C flag specified)
combines all the symbols of the same name into one symbol in the
.bss
section.
The maximum size of all the input symbols with the same name is used to
allocate space for the symbol and the value becomes the address of the symbol.
This is the only case where a symbol has a section number 0 and a non-zero
value.
TI-89 / TI-92 Plus Sierra C Assembler Reference Manual
Not for Distribution
Beta Version February 2, 2001
Section 1: General Information
1.4.8.6. Section Numbers and Storage Classes
Symbols having certain storage classes are also restricted to having certain
section numbers. Table 1.21 summarizes the relationship between storage class
and section number.
TI-89 / TI-92 Plus Sierra C Assembler Reference Manual
Not for Distribution
Beta Version February 2, 2001
28
1.4.8.7. Type Entry
The type field in the symbol table entry contains information on the basic and
derived type for the symbol. The type information is generated for a symbol only
if the files are generated with symbolic debugging in mind. Type information is
generated when the compiler is invoked with the -q or
assembler is invoked with the -L flag and
assembly language file. Each symbol has one basic or fundamental type and
from zero to six derived types. The following is the format of the 16-bit type entry:
d6 d5 d4 d3 d2 d1 type
.type
Section 1: General Information
flag and/or the
-q1
directives are inserted into the
Bits 0 through 3, identified as
in Table 1.22. Bits 4 through 15 are arranged as six 2-bit fields identified as
, indicate one of the fundamental types listed
type
d1
through d6. The fields d1 through d6 represent levels of the derived types listed
in Table 1.23.
0 Type not assigned
1 Long double
2 Character
3 Short
4 Integer
5 Long integer
6 Float
7 Double
8 Structure
9 Union
10 Enumeration
11 Member of enumeration
T_UCHAT
T_USHORT
T_UINT
T_ULONG
12 Unsigned character
13 Unsigned short
14 Unsigned integer
15 Unsigned long integer
Table 1.22: Fundamental Types
TI-89 / TI-92 Plus Sierra C Assembler Reference Manual
Not for Distribution
Beta Version February 2, 2001
Section 1: General Information
Mnemonic Value Type
29
DT_NON
DT_PTR
DT_FCN
DT_ARRAY
Table 1.23: Derived Types
0 No derived type
1 Pointer
2 Function
3 Array
The following two examples demonstrate the interpretation of the symbol table
entry type field.
int **func1()
In the above example,
func1
integer. The fundamental type of
is a function that returns a pointer to a pointer to an
is 4 (integer), the first derived type is 2
func1
(function), the second derived type is 1 (pointer) and the third derived type is also
1 (pointer). Combining the information into a single word (01 01 10 0100), as
previously described, the hexadecimal representation of the value in the type
field is 0x164.
short (*(*pfunc[2][3])())[4]
In this example,
pfunc
returns a pointer to an array of short integers. The fundamental type of
is a two-dimensional array of pointers to a function that
pfunc
is
3 (short integer), the first derived type is 3 (array), the second derived type is 3
(array), the third derived type is 1 (pointer, the fourth derived type is 2 (function),
the fifth derived type is 1 (pointer) and the sixth derived type is again 3 (array).
Combining the information into a single word (11 01 10 01 11 11 0011), as
previously described, the hexadecimal representation of the value in the type
field is 0xD9F3.
TI-89 / TI-92 Plus Sierra C Assembler Reference Manual
Not for Distribution
Beta Version February 2, 2001
30
1.4.8.8. Type Entries and Storage Classes
Symbols having certain storage classes are also restricted to having certain type
entries. Table 1.24 summarizes the relationship between storage class and type
entries.
Conditions for the derived types shown in Table 1.24 apply to all derived types,
through d6, with the added restriction that it is impossible to have two
d1
consecutive derived types of function.
TI-89 / TI-92 Plus Sierra C Assembler Reference Manual
T_NULL
T_NULL
T_NULL
T_NULL
T_STRUCT, T_UNION
T_ENUM
Not for Distribution
,
Beta Version February 2, 2001
Section 1: General Information
1.4.9. Auxiliary Table Entries
An auxiliary entry of a symbol contains the same number of bytes (18) as the
symbol table entry. However, unlike symbol table entries, the format of an
auxiliary entry is a function of the symbol's type and storage class. Table 1.25
describes the relationship between type and storage class, and the formation of
the auxiliary entry.
Symbol Storage Type Entry Auxiliary
Name Class d1 type Entry Format
31
.file C_FILE DT_NON T_NULL
section name
tag name
.eos C_EOS DT_NON T_NULL
function name
array name
.bb C_BLOCK DT_NON T_NULL
.bf C_FCN DT_NON T_NULL
.eb C_BLOCK DT_NON T_NULL
.ef C_FCN DT_NON T_NULL
name related to
structure, union, or
enumeration
Note 1: Any except
Note 2:
C_AUTO, C_STAT, C_MOS, C_MOU, C_TPDEF
C_STAT DT_NON T_NULL
C_STRTAG
C_UNTAG
C_ENTAG
C_EXT DT_FCN
(note 2)
(note 2)
T_MOE
,
DT_NON T_NULL
,
(note 1) Function
DT_ARY
DT_PTR,
DT_ARR
(note 1) Array
T_STRUCT
T_UNION
Filename
Section
Tag name
End of structure
Beginning of blocks and
functions
Beginning of blocks and
functions
End of blocks and functions
End of blocks and functions
Structure, union,
enumeration
Table 1.25: Auxiliary Symbol Table Entries
In Table 1.25,
names
function name
tag name
indicates any symbol name including
and
array name
respectively. Any symbol that satisfies more than one condition listed in
Table 1.25 (e.g., array of structures) should have a union format in the auxiliary
entry. Any symbol that does not satisfy any of the conditions listed in Table 1.25
should not have one of the auxiliary entries listed in Tables 1.26 through 1.34.
Future extensions may allow symbols to have more than one auxiliary entry and
auxiliary entries that are not listed in the above referenced tables.
Defined in
file_fmt.txt
is
AUX_ENT
entry structure.
TI-89 / TI-92 Plus Sierra C Assembler Reference Manual
. The symbol
fake
.
x
represent any name for a function or array
, the typedef for the auxiliary symbol table
Not for Distribution
Beta Version February 2, 2001
32
1.4.9.1. Filenames
The auxiliary symbol table entries for filenames have the format shown in
Table 1.26.
Bytes Declaration Name Description
Section 1: General Information
0-13
14-17 – – Unused (filled with 0's)
char aux_file_name
Table 1.26: Auxiliary Symbol Entry for Filenames
1.4.9.2. Sections
The auxiliary symbol table entries for sections have the format shown in
Table 1.27.
Bytes Declaration Name Description
0-3
4-5
6-7
8-17 – – Unused (filled with 0's)
unsigned long sec.len
unsigned short sec.nbr_rel_ents
unsigned short sec.nbr_line_nbrs
Table 1.27: Auxiliary Symbol Entry for Sections
1.4.9.3. Functions
14-character null padded filename
Section length
Number of relocation entries
Number of line number entries
The auxiliary symbol table entries for functions have the format shown in
Table 1.28. The
parameter-and-fp-format
contains information on how function parameters are pushed onto the stack and
which floating
parameter-and-fp-format
Bit 0 – Function is prototyped
Bit 1 – Parameters of type
Bit 2 – Parameters of type
Bit 3 – Not supported by Texas Instruments.
Bit 4 – Not supported by Texas Instruments.
Bit 5 – Not supported by Texas Instruments.
TI-89 / TI-92 Plus Sierra C Assembler Reference Manual
point format the compiler is generating code for. The bits in the
-
word are interpreted as follows when set:
and
short
(Parameters of type
calculators.)
and
short
pushed as 10 bytes (
float
word in the function auxiliary entry
pushed as four-bytes when prototyped
char
are always pushed as two-bytes for TI
char
double
Not for Distribution
) when prototyped
Beta Version February 2, 2001
Section 1: General Information
Bytes Declaration Name Description
33
0-3
4-7
8-11
12-15
16-17
unsigned long symbol.tag_index
unsigned long symbol.u1.func_size
unsigned long symbol.u2.s.line_ptr
unsigned long symbol.u2.s.end_index
unsigned short symbol.high_size
Table 1.28: Auxiliary Symbol Entry for Functions
1.4.9.4. Beginning of Blocks and Functions
The auxiliary symbol table entries for beginning of blocks and functions have the
format shown in Table 1.29.
Bytes Declaration Name Description
0-3 – – Unused (filled with 0's)
4-5
6-11 – – Unused (filled with 0's)
12-15
unsigned short symbol.u1.s.c_line_nbr
unsigned long symbol.u2.s.end_index
Tag index
Size of function
File pointer to line number
Index of entry after this point
Parameter and fp format info
C-source line number
Index of entry after this block
16-17 – – Unused (filled with 0's)
Table 1.29: Auxiliary Symbol Entry for Beginning of Blocks and Functions
1.4.9.5. End of Blocks and Functions
The auxiliary symbol table entries for the end of blocks and functions have the
format shown in Table 1.30.
Bytes Declaration Name Description
0-3 – – Unused (filled with 0's)
4-5
6-17 – – Unused (filled with 0's)
Table 1.30: Auxiliary Symbol Entry for End of Blocks and Functions
unsigned short symbol.u1.s.c_line_nbr
C-source line number
TI-89 / TI-92 Plus Sierra C Assembler Reference Manual
Not for Distribution
Beta Version February 2, 2001
34
1.4.9.6. Arrays
The auxiliary table entries for arrays have the format shown in Table 1.31.
unsigned long symbol.tag_index
unsigned short symbol.u1.s.c_line_nbr
unsigned short symbol.u1.s.size
unsigned short symbol.u2.array_dim[0]
unsigned short symbol.u2.array_dim[1]
unsigned short symbol.u2.array_dim[2]
unsigned short symbol.u2.array_dim[3]
Table 1.31: Auxiliary Symbol Entry for Arrays
1.4.9.7. Tag Names
The auxiliary symbol table entries for tag names have the format shown in
Table 1.32.
Bytes Declaration Name Description
0-5 – – Unused (filled with 0's)
Tag index
Line number of declaration
Size of array
First dimension
Second dimension
Third dimension
Fourth dimension
6-7
8-11 – – Unused (filled with 0's)
12-15
16-17 – – Unused (filled with 0's)
unsigned short symbol.u1.s.size
unsigned long symbol.u2.s. end_index
Size of structure, union, or
enumeration
Index of next entry beyond this
structure, union, or enumeration
Table 1.32: Auxiliary Symbol Entry for Tag Names
TI-89 / TI-92 Plus Sierra C Assembler Reference Manual
Not for Distribution
Beta Version February 2, 2001
Section 1: General Information
1.4.9.8. End of Structures
The auxiliary symbol table entries for the end of structures have the format
shown in Table 1.33.
Bytes Declaration Name Description
35
0-3
4-5 – – Unused (filled with 0's)
6-7
8-17 – – Unused (filled with 0's)
unsigned long symbol.tag_index
unsigned short symbol.u1.s.size
Tag index
Size of structure, union, or enumeration
Table 1.33: Auxiliary Symbol Entry for End of Structures
1.4.9.9. Names Related to Structures, Unions, and Enumerations
The auxiliary table entries for structure, union, and enumeration symbols have
the format shown in Table 1.34.
Bytes Declaration Name Description
0-3
4-5 – – Unused (filled with 0's)
6-7
8-17 – – Unused (filled with 0's)
unsigned long symbol.tag_index
unsigned short symbol.u1.size
Table 1.34: Auxiliary Symbol Entry for Structures, Unions, Enumerations
Tag index
Size of structure, union, or enumeration
TI-89 / TI-92 Plus Sierra C Assembler Reference Manual
Not for Distribution
Beta Version February 2, 2001
36
1.4.10. String Table
Symbol table names longer than eight characters are stored contiguously in the
string table with each symbol name terminated with a null character. The string
table is located immediately after the symbol table and it can be located by
adding the size of the symbol table to the base offset of the symbol table. The
first four bytes of the string table contain the size of the string table in bytes; thus
the first string table symbol will be at offset four.
For example, given a file that includes two symbols with names longer than eight
characters,
this_is_a_long_name
table will appear as shown in Table 1.35.
0 0 0 52 ' t ' ' h ' ' i ' ' s ' ' _ ' ' i '
' s ' ' _ ' ' a ' ' _ ' ' l ' ' o ' ' n ' ' g ' ' _ ' ' n '
' a ' ' m ' ' e ' ' \0 ' ' t ' ' h ' ' i ' ' s ' ' _ ' ' i '
' s ' ' _ ' ' a ' ' _ ' ' s ' ' t ' ' i ' ' l ' ' l ' ' _ '
and
this_is_a_still_longer_name
Section 1: General Information
, the string
' l ' ' o ' ' n ' ' g ' ' e ' ' r ' ' _ ' ' n ' ' a ' ' m '
' e ' ' \0 '
Table 1.35: Example String Table
The string table offset of
this_is_a_long_name
this_is_a_still_longer_name
is 24.
is 4, and the string table offset of
TI-89 / TI-92 Plus Sierra C Assembler Reference Manual
TI-89 / TI-92 Plus Sierra C Assembler Reference Manual
Not for Distribution
Beta Version February 2, 2001
2. Compiler
2.1. Introduction
41
The Sierra Systems C compiler,
68000 assembly code. It generates highly efficient code and supports ROMable
and position-independent code generation for the 68000.
The C compiler,
Motorola processors and coprocessors and IEEE format floating-point numbers.
Under license from Sierra Systems, Texas Instruments has modified this
software to support TI BCD floating-point numbers, and support for coprocessors
has been removed. Although the software has not been modified to exclude
support for processors other than the 68000, the 68000 is the only processor
supported by Texas Instruments. The license from Texas Instruments to use
these products is restricted to development of software that is targeted to
execute only on TI calculators.
com68
, was developed by Sierra Systems to support certain
com68
2.2. Invoking the Compiler
Typically, the TI
using the correct command line flags required to produce TI-89 / TI-92 Plus apps
or ASMs. The following discussion of command line format and flags is included
for developers who may wish to use
create their own makefile.
FLASH
Studio™ will handle all invocations of the compiler,
, converts C language statements into
com68
directly from the command line or
The C compiler is ordinarily invoked with two filenames listed on the command
line. The first filename specifies the C source file and the second specifies the
assembly language output file. If no output file is specified, the compiler writes
the assembly language output to
file is specified either, the compiler reads C source input from
keyboard).
The following command compiles the file test.c and creates the 68000 assembly
language file test.s:
com68 test.c test.s
2.3. Command Line Flags
Flags are used to change the behavior of the compiler. They are specified on the
command line along with the input and output filenames. Flags appear on the
command line as strings of one or more alphabetic characters prefixed with a
hyphen ( - ). Some flags require arguments, and some accept optional
TI-89 / TI-92 Plus Sierra C Assembler Reference Manual
stdout
(usually the display screen). If no input
Not for Distribution
(usually the
stdin
Beta Version February 2, 2001
42
Section 2: Compiler
arguments. Other flags take no arguments. Flags may be grouped together
following a single hyphen; however, any flag that accepts an optional argument
must be the last flag in a group. The TI-89 / TI-92 Plus SDK includes example
invocations of the compiler. It is highly recommended that you only use the flags
as shown in those files.
The following command compiles the C source from the file demo_in.c and
places the generated 68000 assembly code into demo_out.s:
com68 -l -O demo_in.c demo_out.s
The two flags listed on the command line cause the C source to be listed in the
output file as comments, and full optimization t o b e applied t o t h e p r o g r a m,
respectively.
The command can also be specified as follows without changing the behavior of
the compiler:
com68 demo_in.c -lO demo_out.s
These two command lines demonstrate both how flags can be grouped together
using a single hyphen ( - ) and that they can appear anywhere on the command
line.
When two or more contradictory flags are specified on the command line, the last
flag entered determines the behavior. For example, if the
post-code-generation optimizations) is followed by the
post-code-generation optimizations), the
be useful in some cases, for example, you may wish to override a flag contained
in a file included with the -i flag.
2.3.1. Usage
The following is a summary of the command line usage information for the
compiler (see -u flag):
If no command line flags are specified, the compiler defaults to the following
settings:
68000 default settings:
TI-89 / TI-92 Plus Sierra C Assembler Reference Manual
com68 -fc3 -Oa2c0f0i1l1m1p1r2s2x0
Not for Distribution
Beta Version February 2, 2001
Section 2: Compiler
The command line flags for the default settings are defined as follows:
43
-fc3
-Oa2
-Oc0
-Of0
-Oi1
-Ol1
-Om1
-Op1
-Or2
-Os2
When specified by the -l flag, C source lines with comments and blank
lines stripped out are indented by three tabs and placed into the assembly
language output listing.
Both
Do not coalesce function call stack cleanups.
Set up a stack frame only when necessary.
Generate in-line code for the
Move only constants out of inner loops. Full loop invariant optimizations
are not performed.
Expand multiplication by a constant into a sequence of shifts and adds if it
results in faster execution.
Perform all post-code-generation optimizations.
Treat all qualifying automatic variables as register candidates.
In the presence of a function prototype, arguments of type
are pushed onto the stack as two-byte objects.
int
short
and
data are aligned to even boundaries.
int
function.
strcpy
char
and
short
-Ox0
Do not perform common subexpression optimizations.
2.3.3. Description of Flags
-C
-D
name[=string
-E
-f
Leave comments in the preprocessed C source. The -E flag is
implied.
]
Define the name
optional; the name
omitted. No whitespace is allowed on either side of the
Send the preprocessed C source to the output file. Do not compile.
See also
Format the source listings and source line numbers that are optionally
inserted as comments into the assembly language output. The
must be specified to enable the selected format.
a
c
. The
name
is defined to be 1 if the optional string is
name
flag.
-P
Place C source line numbers next to the corresponding
assembly language statements.
Insert C source lines with comments and blank lines
stripped into the assembly language listing.
and substitution string
'='
string
.
'='
-l
are
flag
TI-89 / TI-92 Plus Sierra C Assembler Reference Manual
Not for Distribution
Beta Version February 2, 2001
44
Section 2: Compiler
cmd_file
-i
path
-I
-l
-LIC
-M
-M1
t
-M2[
t
-M3[
t
-M4[
-M5
nbr
nbr
nbr
C
s
#
Include the contents of the file
input at the current position in the command line. The
be used inside an included file; however, it can be specified multiple
times on the command line.
Search the directory specified by
looking in the default directory(ies). There is no limit to the number of
times the
Mix C source and line numbers into the assembly language listing as
specified by the
Display serial number and license information.
Not supported by Texas Instruments, however, -M,
-M2[
]
as reserved flags by the compiler.
Insert C source lines including comments into the
assembly language output.
Place line numbers in front of each C source line in the
assembly language listing.
Specify the number of tabs used to indent the C source
intermixed with the assembly language listing. The default
is three tabs.
cmd_file
into the command line
-i
flag can be specified.
-I
format option.
-f
path
for
#include
files before
-M1
t
nbr
], -M3[
t
nbr
], -M4[
t
nbr
, and
]
are recognized
-M5
flag cannot
,
]
]
-O
Turn on or off specified compiler optimizations. Specifying no flags
after the
invariant, common subexpression, coalescing function call stack
cleanups, and tail recursion elimination). All other optimizations are
enabled by default (see section
a#
A
flag is equivalent to specifying
-O
2.3.2 Default Behavior
Specify alignment for integer data types. a1 imposes no
alignment on any integer data types.
and
a4
quad boundaries.
Ignore the possibility of aliases in the register
scorecarding optimization. When the
specified, slightly smaller, faster code is generated;
however, there is a small possibility that the code will be
incorrect if aliases exist.
data types to even boundaries (default for 68000).
int
aligns
data to even boundaries and
short
-Ol2x1c1t1
a2
-OA
(loop
).
aligns both
int
flag is
short
data to
TI-89 / TI-92 Plus Sierra C Assembler Reference Manual
Not for Distribution
Beta Version February 2, 2001
Section 2: Compiler
45
c#c1
coalesced into a single cleanup.
stack cleanups from being coalesced (default).
f#f0
be setup if it is not essential (default).
stack frame should always be setup.
i#i1
code (default).
generate a normal function call.
with the added provision that all arrays are aligned to the
same boundary as an
l#
Move expressions that are not modified inside a loop to
outside the loop.
expressions are to be moved.
constants are to be moved outside inner-most loops
(default). The
effect for
expressions are to be moved outside the inner-most loops
only.
moved through as many levels of loop nesting as
possible.
a warning is issued (correct code is still generated) if the
compiler exceeds the number of loop invariants that it can
handle.
message is encountered.
causes multiple function call stack cleanups to be
inhibits function call
c0
specifies that a stack frame (
causes calls to the
i0
-Op1
to have any effect. l2 specifies that invariant
l1
specifies that invariant expressions are to be
l3
specifies the same action as l3, except that
l4
typically gives the best performance when this
l2
strcpy
causes calls to the
.
int
specifies that no loop invariant
l0
flag (also default) must also be in
and
link
f1
function to generate in-line
strcpy
is the same as
i2
specifies that only
l1
) should not
unlk
specifies that a
function to
i1
m#m0
p#p0
TI-89 / TI-92 Plus Sierra C Assembler Reference Manual
inhibits multiplication by a constant from being
expanded into a sequence of shifts and adds; it also
inhibits the move-multiple instruction from being
expanded into discrete moves.
a constant to be expanded, but does not allow the
move-multiple instruction to be expanded (default).
specifies that no post-code-generation optimizations
are to be performed.
post-code-generation optimizations are to be performed
(default).
Not for Distribution
specifies that
p1
allows multiplication by
m1
Beta Version February 2, 2001
46
Section 2: Compiler
r#
s#
Specifies how automatic variables are selected for
placement into machine registers.
variables are to be placed into registers.
only variables declared with the register storage-class
specifier are to be candidates for placement into registers.
specifies that both variables declared register and
r2
those not declared register will be register candidates
(default). The nonregister variables are selected as
register candidates based on how often they are used.
They are selected after the declared register candidates
until all have been assigned register candidate status or a
total of 32 (including those declared register) are selected.
specifies the same action as r2, except that register
r3
declarations are ignored. Variables that were declared
register may still be assigned to registers.
floating-point automatic variables that have not been
declared register from being placed into floating-point
registers; otherwise, the behavior is the same as
described by
2.15.1 Register Allocation
The
-Os#
function argument onto the stack. A
function prototype results in a two-byte push when
(default) is specified and a four-byte push when s4 is
specified. In the presence of a
prototype, the argument is pushed as a
and will be pushed on as a
is specified (s2 or s4 implied, respectively).
s5
. For more information, refer to section
r2
.
flag determines how to push a prototyped
double
specifies that no
r0
r1
r4
short int
or a
float
double
double
(10 bytes) when
specifies that
prevents
or
char
s2
(10 bytes)
or
s3
t#t0
x#x0
TI-89 / TI-92 Plus Sierra C Assembler Reference Manual
specifies that duplicate common subexpressions are
not to be removed (default).
to different copies of a common subexpression are to be
replaced by references to a single subexpression with
duplicate subexpressions removed.
Not for Distribution
specifies that references
x1
Beta Version February 2, 2001
t1
Section 2: Compiler
47
-p
-P
-q
-q1
proc
z
Not supported by Texas Instruments, however,
as a reserved flag by the compiler.
Strip
#line
preprocessed C source files. The
Generate full source-level debugging information to allow the
compiled program to be debugged with the TI
source-level debugger. Optimizations that would confuse a
source-level debugger are disabled when the
Generate full source-level debugging information for everything except
automatic variables and allow the compiler to operate with all
optimizations enabled. When debugging with the
locations (register or stack offset) of automatic variables can be easily
determined by issuing the TI
command and examining the C statements with the corresponding
assembly code intermixed.
Optimize the generated code for size, possibly at the
expense of speed.
routine, the unrolling of structure copy loops, and the
expansion of multiplication by constants (except where
the expanded code is more compact). The stack cleanup
coalesce option is enabled. Except for disabling the
unrolling of structure copy loops, which can only be
accomplished with this flag, the
-Oi0c1m0
directives and multiple sequential blank lines out of
.
disables the in-line string copy
z
flag is equivalent to
-Oz
proc
-p
flag is implied.
-E
Studio
flag is specified.
flag, the
-q1
FLASH
FLASH
-q
Studio low-level-display
is recognized
-Q
-s
-T
-u
-U
-X
-Z
name
Suppress the Sierra Systems copyright notice when the compiler is
invoked.
Preprocess and parse the C source file, but do not generate an
assembly language output. This option should be used to save time
during initial compilations when syntax errors are expected.
Process ANSI trigraphs, e.g., map ??( to [ and ??) to ].
Print command line usage information.
Undefine the name
command line using the
Turn on the following specified compiler options.
Turn off the following specified compiler options.
A
The
-XA
register d0 instead of register a0.
that was previously defined on the
name
flag.
-D
flag causes address pointers to be returned in
TI-89 / TI-92 Plus Sierra C Assembler Reference Manual
Not for Distribution
Beta Version February 2, 2001
48
Section 2: Compiler
b
c
length
C
d
e
size
E
Warn about automatic variables that may be defined
before they are used. The compiler will erroneously issue
a warning if it finds a path that would result in a use
before definition when such a path will never be taken
during program execution.
Make a function call to
every line of C source. The
used to perform user-supplied debugging functions.
Set the maximum length of character strings to
The default length is 512 characters. The maximum length
that can be specified is limited by available memory. This
option is not valid with the
Reference data objects relative to address register
with a 16-bit displacement.
Write compiler errors to the file
base name of the compiler input file. Errors are also
written to
Set the
the expression stack is 30. This option is not valid with the
-Z
size
flag.
.
stderr
of the expression stack. The default size of
__line_ck
-Z
immediately before
__line_ck
flag.
infile
function can be
.err where
length
a5
is the
infile
.
f#
i
I
Generate a warning when a function is declared without
prototype information and/or a function call is made in the
absence of any function declaration.
to be issued when a function is called outside the scope
of function declaration and
issued when a function is declared without prototype
information.
— i.e., a warning is issued when a function is called
f2
without a prototype declaration in scope.
Not supported by Texas Instruments, however, i is
recognized as a reserved flag by the compiler.
Define type
is defined to be 16 bits, variables of type
int
to type
larger than 32767 bytes or when offsetting a pointer to an
object larger than 32767 bytes. Both the TI-89 and
TI-92 Plus assume this option is selected and all library
functions support 16-bit integers.
long
specifies the actions of both f1 and
f3
to be 16 bits instead of 32 bits. When an
int
) must be used when indexing into an array
causes a warning to be
f2
causes a warning
f1
(or cast
long
TI-89 / TI-92 Plus Sierra C Assembler Reference Manual
Not for Distribution
Beta Version February 2, 2001
Section 2: Compiler
49
l
L
M
N
p
q
Use long offsets in table look-up switch tables instead of
word offsets. Long offsets must be specified if the total
size of the code inside a switch statement exceeds 32767
bytes.
Reference data objects using the 32-bit absolute
addressing mode. This option inhibits data references
from being coerced to PC-relative modes when the
generation of position-independent code is specified (
flag). See also
Not supported by Texas Instruments, however, M is
recognized as a reserved flag by the compiler.
Automatically size enumerated data types to the smallest
integer type that can represent all associated enumeration
members. When this option is not specified, enumerated
data types are always type
Generate position-independent code with a maximum
PC-relative displacement of 16 bits.
When used with the -Z flag, this option undoes the effect
of the
source-level debugger information. This option is not valid
with the
-q
and
-X
flag.
flag.
-XW
.
int
flags used to specify the generation of
-q1
-Xp
r#
R
Prevent the compiler from using the registers specified by
the
options. The reserved registers are available for use
r
(possibly as base registers) in assembly language
routines that are linked with C programs. The options
through ra cause the following registers to be reserved:
− a5
r0
− a5, a4
r1
− d7
r2
− d7, d6
r3
− d7, d6, d5
r4
− a5, d7
r5
If register a5 is already being used as a base register as
specified by
shifted down one register (e.g., a5, a4 becomes a4, a3).
Base the relative path of
containing the original source file. The default is to base
the path on the directory containing the including file. This
option is only valid with the
undo the effect of the
, the reserved address registers are
-Xd
-XR
− a5, a4, d7
r6
− a5, d7, d6
r7
− a5, a4, d7, d6
r8
− a5, a4, d7, d6, d5
r9
− a5, a4, a3, d7, d6, d5
ra
#include
-Z
flag.
files on the directory
flag and is provided to
r0
TI-89 / TI-92 Plus Sierra C Assembler Reference Manual
Not for Distribution
Beta Version February 2, 2001
50
Section 2: Compiler
[
s
size
Make a function call to
]
every function that requires more than
stack space or calls other functions. The needed stack
space is available to
value for the optional stack size is 40. The stack size
size
S
u
Make a function call to
every function. The amount of stack space needed by the
function is available to
section
information.
Do not place a leading underscore (_) in front of global
variables in the generated assembly code. A leading
underscore is placed in front of compiler-generated local
labels (_L
w#w1
unnecessary assignments and statements that cannot be
reached.
compile-time initialization of address register relative data.
w4
any warnings are generated. The codes to the
must be combined with a bitwise OR operation to disable
more than one class of warnings (e.g., when
followed by
when
-Xw4
__stk_ck
__stk_ck
cannot be specified with the -Z flag.
__stk_ck
__stk_ck
2.12.3 Debugging Functions
) instead.
xxx
disables warnings concerning minor problems such as
disables warnings concerning the
w2
causes the compiler to return a nonzero exit code if
the effect of
-Xw4
is specified the actions of both
-Xw5
are in effect).
at the beginning of
bytes of
size
in register d0; the default
at the beginning of
in register d0. See
for more
is
and
flag
is lost, whereas
-Xw1
-Xw#
-Xw1
-Xw1
W
1
TI-89 / TI-92 Plus Sierra C Assembler Reference Manual
Reference data objects using the 16-bit absolute
addressing mode. This option can be used when it is
known that all data references will be in the top or bottom
32K bytes of memory. It also inhibits data references from
being coerced to PC-relative modes when the generation
of position-independent code is specified (
also
Do not generate source-level debugging
.def – .endef
.endef
default, even in the absence of the
-q
flag.
-XL
pairs for function definitions. The
pairs for function definitions are generated by
flag.
Not for Distribution
Beta Version February 2, 2001
-Xp
flag). See
–
.def
Section 2: Compiler
51
2
2.4. Pragma Directives
A pragma is a preprocessing directive with the following form:
#pragma preprocessing_tokens
The functionality of a
The specified behavior, however, can be embedded into the source file and
turned on and off multiple times during a single compilation.
The Sierra C™ compiler currently supports five
pragmas allow the default names of the text and data sections to be changed to
arbitrary names. One pragma permits integer functions written in C to be used as
interrupt handlers. Finally, two pragmas allow selected data objects to be
referenced using the absolute long addressing mode when a4-relative
addressing is selected on the command line. The five
described as follows:
#pragma
Save and restore register d2 in all functions that use the
register to guarantee that the value of the register remains
unmodified across function calls. The default is to use
register d2 as a temporary scratch register with the value
not guaranteed across function calls.
directive is similar to that of a command line flag.
#pragma
directives. Two of the
#pragma
directives are
#pragma tsection
The
literal strings that will be placed in the text section to be placed in a
section with the name
directive can be used multiple times to change to different names
or switch back and forth between a pair of names. For example,
the directive
text section to switch back to
#pragma dsection
The
literal strings that will be placed in the data section to be placed in
a section with the name
directive can be used multiple times to change to different names
or switch back and forth between a pair of names. For example,
#pragma dsection .data
to switch back to
section_name
#pragma tsection
#pragma tsection .text
section_name
#pragma dsection
.data
directive causes data, instructions, and
. The
section_name
#pragma tsection
will cause the name of the
, the default name.
.text
directive causes data, instructions, and
. The
section_name
#pragma dsection
will cause the name of the data section
the default name.
TI-89 / TI-92 Plus Sierra C Assembler Reference Manual
Not for Distribution
Beta Version February 2, 2001
52
#pragma interrupt
Allow functions written in C to be used as interrupt handlers. When
the
definition, that function saves and restores the data and address
scratch registers (i.e., d0, d1, d2, a0, and a1), and exits using an
rte
applies only to the next function and must be repeated to affect
additional functions.
#pragma +abs_data
Allow data objects declared in a file that is compiled to access
data relative to the program counter or address register a5 to be
accessed using the absolute long addressing mode. All data
objects declared between the
-abs_data
addressing mode.
#pragma -abs_data
Undo the effect of the
#pragma interrupt
directive is placed before a function
instruction instead of an
directives will be accessed using the absolute long
#pragma +abs_data
Section 2: Compiler
. The
rts
#pragma +abs_data
#pragma interrupt
directive.
and
directive
#pragma
#pragma fp_interrupt
Not supported by Texas Instruments.
2.5. Translation Limits
C programs must not include constructs that exceed the following limits:
50 nesting levels for
•
16 nesting levels for conditional source inclusion
•
20 nesting levels for
•
25 nesting levels for loop statements
•
20 nesting levels for function calls
•
32 nesting levels for macro invocations
•
255 significant initial characters in an identifier (internal and external)
•
255 significant initial characters in a macro name
•
255 parameters in one function definition and call
•
31 parameters in one macro definition and invocation
•
#include
switch
files
statements
†
characters in a character string (after concatenation)
512
•
†
The number of characters can be increased with the -XC flag.
TI-89 / TI-92 Plus Sierra C Assembler Reference Manual
Not for Distribution
Beta Version February 2, 2001
Section 2: Compiler
2.6. Reserved Keywords
Following is the list of reserved C language keywords that the Sierra C compiler
recognizes:
keyword is a standard extension to ANSI C that allows statements to be
asm
inserted directly into compiler-generated assembly code. The
followed by a character string enclosed in parentheses, and it can appear in the
C source file wherever a statement or declaration is allowed. For example, the
following statement causes the instruction enclosed in double quotes to be
inserted into the assembly output at the location that corresponds to the
statement’s location in the C source:
asm("move.w #0x2400, sr", 4)
The integer constant 4 that follows the string indicates the size of the instruction
in bytes. The
argument is optional; if omitted, the instruction is assumed to be
size
two bytes long. It is necessary to specify the size of the instruction only when the
statement appears inside a loop, if statement,
asm
between a
statement and the label it references. An incorrect or missing
goto
size specification may cause the compiler to generate an improperly sized
branch instruction, which will result in an assembly error.
2.6.2. ANSI C Keywords
The ANSI C standard added three keywords,
C language. The
embedded systems developers. These two keywords are fully described in
sections
keyword
2.9.8 Const Type Specifier
signed
recognize objects of type
unsigned. The keyword
existing keyword
const
aids in writing portable code. For example, some compilers
unsigned
asm
statement, or
, and
and
volatile
char
signed
switch
const, volatile
keywords are extremely important to
and
2.9.9 Volatile Type Specifier
as signed and others recognize them as
can be used in conjunction with the previously
to control the interpretation of certain object
keyword is
asm
signed
, to the
. The
TI-89 / TI-92 Plus Sierra C Assembler Reference Manual
Not for Distribution
Beta Version February 2, 2001
54
declarations. The Sierra C compiler treats bit fields as unsigned objects by
default. The
signed
keyword can be used to treat bit fields as signed objects.
2.7. Constants
The C compiler recognizes four types of constants: floating-point, integer,
character, and enumeration. Every constant has a type that is determined by its
form and value, as described in this section. All constants are non-negative in the
absence of overflow. If there is a minus sign preceding a constant, it is
recognized as a unary operator applied to the constant, and not as part of the
constant itself.
2.7.1. Floating-Point Constants
A floating-point constant may be written with a decimal point, a signed exponent,
and/or a type specifier suffix. The exponent consists of the letter e or
by an optionally signed decimal constant. The type specifier is one of the letters
f, F, l
constant to be recognized as a floating-point type.
, or L. Either the decimal point or the exponent must be present for the
The digit sequences are interpreted as decimal numbers. The exponent indicates
the power of 10 by which the value to the left of the exponent is to be multiplied.
Note:
All floating-point constants, whether they are written with a suffix or without a suffix, are
of type
(10 byte TI BCD floating point).
double
2.7.2. Integer Constants
An integer constant begins with a decimal digit and contains no decimal point or
exponent. It can have a prefix that specifies its base and a suffix that specifies its
type. The type specifiers are the letters u, U, l, and L, where u (or U) and l (or L)
can be used together in either order. The u (or U) specifier coerces the constant
to an
.
int
unsigned
type, and the l (or L) specifier coerces the constant to a
long
TI-89 / TI-92 Plus Sierra C Assembler Reference Manual
Not for Distribution
Beta Version February 2, 2001
Section 2: Compiler
An integer constant can be represented in three different bases: octal, decimal,
and hexadecimal. A constant’s base is determined by its leading character(s).
Octal constants begin with a zero, and hexadecimal constants begin with the
character pair 0x or 0X. Decimal constants begin with any nonzero digit.
Examples of integer constants include:
The type of an integer constant is determined by its value, base, and suffix (if
any) according to the following rules:
1. The type of a decimal constant with no suffix is the first type in the following
list in which its value can be represented:
2. The type of an octal or hexadecimal constant with no suffix is the first type in
the following list in which its value can be represented:
long int, unsigned long int
150920xf9a0XF9al
03510275uL319LU
.
int, long int, unsigned long int
int, unsigned int
,
55
.
3. The type of a constant with only the u (or U) suffix is the first type in the
following list in which its value can be represented:
long int
.
4. The type of a constant with only the l (or L) suffix is the first type in the
following list in which its value can be represented:
.
int
5. The type of a constant with both the u (or U) suffix and the l (or L) suffix is
unsigned long int
.
For example, the constant 0x81234567 is recognized as an
because it cannot be represented as a 32-bit
2.7.3. Enumeration Constants
An identifier declared as an enumeration constant has type
constant can be used anywhere an integer constant is allowed; however, there
are some restrictions when an enumeration constant is assigned to an
enumeration variable. See section
information.
unsigned int, unsigned
long int, unsigned long
signed long int
int
2.9.5 Enumeration Types
unsigned long int
.
. An enumeration
, for additional
,
TI-89 / TI-92 Plus Sierra C Assembler Reference Manual
Not for Distribution
Beta Version February 2, 2001
56
2.7.4. Character Constants
A character constant is a sequence of up to four characters enclosed in single
quotes ('). Characters that cannot be entered directly or conveniently into the
source program, such as nongraphic characters, can be specified in a character
constant using an escape sequence. Table 2.1 lists the available escape
sequences and their values.
Section 2: Compiler
Character constants have type
. The value of each character in a character
int
constant is its integer encoding in the ASCII character set or the value of its
associated escape sequence, whichever is applicable.
The double quote (") and the question mark (?) can be specified directly or with
their escape sequences. The single quote (') and the backslash (\), however,
must be specified with their escape sequences.
In the octal and hexadecimal escape sequences,
octal digits and
represents up to three hexadecimal digits. These digit
hhh
represents up to three
ooo
sequences are terminated with the third digit or the first nonoctal (or
nonhexadecimal) character. The specified digits determine the value of the
character.
Some integer values that can be represented using three octal or hexadecimal
digits will not fit into a single eight-bit character. When a value does not fit into
eight bits, it is masked with the value 0xFF to force it to fit into eight bits. The
construct ' \x123 ' is a character constant containing a single character. To
TI-89 / TI-92 Plus Sierra C Assembler Reference Manual
ooo
hhh
Not for Distribution
(masked with 0xFF)
(masked with 0xFF)
Beta Version February 2, 2001
Section 2: Compiler
specify a character constant containing the two characters whose values are
' \12 ' and ' 3 ', the construction ' \0123 ' must be used. To specify a character
constant containing the two characters whose values are ' \12 ' and ' z ', the
constructions ' \012z ' and ' \12z ' are both valid.
The sign of the character constant is determined by the most significant bit of the
character. For example, the character constant ' \xFF ' has the value -1, and the
character constant ' \x7F ' has the value +127. The value of a multi-character
character constant is determined by placing its characters (from right to left) into
successively higher order bytes of an integer (beginning with the lowest order
byte). Just as the sign of a single-character character constant is determined by
the value of bit 7, the sign of a four-character character constant is determined
by the value of bit 31. Two- and three-character character constants are always
positive.
The examples in Table 2.2 illustrate how character constants are evaluated.
Character Constant Hexadecimal Value Decimal Value
A character string is a sequence of zero or more characters enclosed in double
quotes (e.g., "abc"). The same considerations that apply to characters and
escape sequences in character constants apply also to character strings.
Refer to Table 2.1 for the list of recognized escape sequences and the rules and
restrictions that apply. In a character string, the only difference in the use of the
escape sequence mechanism is that the single quote (') can be specified
directly or with its escape sequence, whereas the double quote (") must be
specified with its escape sequence.
TI-89 / TI-92 Plus Sierra C Assembler Reference Manual
Not for Distribution
Beta Version February 2, 2001
58
Section 2: Compiler
A character string is actually a static array of characters, where the array has
been initialized with the given characters and a terminating null character.
Character strings cannot be modified during program execution; the static array
containing the characters resides in the program text section, which is typically
loaded into Read-Only Memory (ROM).
A newline is illegal inside of a character string. There are two ways, however, to
continue a character string on a new line. A character string may be continued by
placing a backslash (\) immediately before the newline. For example, the
following two strings are equivalent:
"this is a test of a string that \
spans two lines"
"this is a test of a string that spans two lines"
Character strings can also be continued by placing them adjacent to each other.
For example, the following two strings are equivalent:
"this" " string " "has "
"been broken"" into several pieces"
"this string has been broken into several pieces"
Escape sequences are converted into single characters before adjacent
character strings are concatenated. For example, the first string below is
equivalent to the second string, not the third:
"\x12" "3"
"\x0123"(two characters)
"\x123"(one character)
The maximum length of a character string is 512 characters unless it is increased
with the
flag. When two or more strings are concatenated, the character
-XC
length limit applies to the combined length.
2.9. Types and Representations
This section describes the internal representations of the various integer and
floating-point types. It also describes the correct usage of enumeration types and
bit fields, and discusses the issues concerning the
specifiers.
const, volatile
, and
void
type
TI-89 / TI-92 Plus Sierra C Assembler Reference Manual
Not for Distribution
Beta Version February 2, 2001
Section 2: Compiler
2.9.1. Integer Types
Table 2.3 summarizes the recognized integer types, their sizes, and their value
ranges. Integer data types can also be declared to be
declared to be
unsigned
. The
signed
keyword, however, is significant only
signed
when used in a bit field declaration, because bit fields are the only integer data
types that are unsigned by default.
just as they can be
59
The integer data types
the
command line flag is used to specify 16-bit integers as on the
-XI
int
and
short int
declare objects of the same size (when
TI-89 / TI-92 Plus). Even though objects of both types have the same internal
representation and can be used to store the same values, the two types should
not be used interchangeably. One reason is that pointers to
short int
are different types, and a warning will be issued if either type is
and pointers to
int
assigned to the other. Also, the program may someday be recompiled on
another compiler where
int
and
short int
do not declare objects of the same
size.
Type Size in Bits Minimum Value Maximum Value
char
short int
†
int
long int
unsigned char
unsigned short int
unsigned int
unsigned long int
†
Integers are 16-bit objects on the TI-89 / TI-92 Plus (the
The memory address of any integer data object is the address of its highest
order byte (i.e., the byte containing the most significant bits). Unsigned integer
data types are represented as straight binary numbers, and signed integer types
are represented using two’s complement notation. Figure 2.1 shows the internal
representations of the three basic integer data types for the given values.
TI-89 / TI-92 Plus Sierra C Assembler Reference Manual
Not for Distribution
Beta Version February 2, 2001
60
Section 2: Compiler
Character
msb (sign)
7
1 2
char a = 0x12;
lsb
0
0
address
Integer or Short Integer
msb (sign)
15
1 23 4
0
low address
Long Integer
msb (sign)
31
1 23 45 67 8
0
low address
long int c = 0x12345678;
high address
short int b = 0x1234;
lsb
0
+1
lsb
0
+1+2+3
high address
Figure 2.1: Internal Integer Representations
2.9.3. Floating-Point Types
The Sierra C compiler has been modified by Texas Instruments to support the
TI BCD floating-point format, removing all other previously supported
floating-point formats and coprocessors, except for an IEEE format which is used
in special cases and exists only in the compiler, not on the TI-89 / TI-92 Plus.
(See section
the IEEE format.)
There are two forms of the TI BCD floating-point values, differing only in the
number of significant digits retained in the mantissa. Both have a size of ten
bytes, with
accuracy to 14 digits. There is not a separate representation for
which is interpreted as
available to the users of the TI-89 and TI-92 Plus calculators have 14 digit
mantissas. It is highly recommended to always use the
coding the applications to take advantage of the increased accuracy provided by
the extra two digits. See chapter
TI-89 / TI-92 Plus Developers Guide for information on how and when to round to
the 14 digits required by the calculator user floating-point representation. The
format will not usually be used in TI-89 / TI-92 Plus applications. In the
float
2.12.2 Internal Floating-Point Functions
double
keeping 16 BCD digits in the mantissa, while
double
for more information on
rounds the
float
long double
when encountered. The floating-point values
double
16. Working with Numbers
format when
in the
,
TI-89 / TI-92 Plus Sierra C Assembler Reference Manual
Not for Distribution
Beta Version February 2, 2001
Section 2: Compiler
61
include file (
defined as
tiams.h
double
) supplied with the TI-89 / TI-92 Plus SDK, BCD16 has been
, and should be used when coding applications as a reminder
that routines containing floating-point operations may not be portable code.
2.9.4. Floating-Point Representations
All TI BCD floating points are 10 byte objects. The first two bytes in the TI BCD
floating-point format are the mantissa sign and exponent. The mantissa sign is
the most significant bit of that word (1=negative, 0=positive) and the other 15 bits
are a 0x4000 biased exponent, where a value less than 0x4000 represents a
negative exponent, and a value greater than 0x4000 represents a positive
exponent. The memory address of a floating-point data object is the address of
the first byte of the sign/exponent. The decimal point is assumed to be after the
first BCD mantissa digit. The mantissa consists of 16 BCD digits, with digits 15
and 16 always equal to 0 in a
double and float
Low addressHigh Address
2 bytesMSD 8 bytes LSD
float
.
0x4000 biased1 . . .. . . 1516
exp and sign16 digit mantissa (digits 15 and 16=0 for
Figure 2.2: Internal TI BCD Floating-Point Representation
float
)
Following are some examples of common floating-point values shown as if
written in 68000 assembly language:
TI-89 / TI-92 Plus Sierra C Assembler Reference Manual
Not for Distribution
Beta Version February 2, 2001
62
Section 2: Compiler
_FPNEGTEN:
.word 0xC001; -10
.long 0x10000000,0
The internal floating-point representation allows an exponent range of L16384 to
16383. However, the exponent range available to the users of the TI-89 and
TI-92 Plus calculators is L999 to 999. See chapter
the TI-89 / TI-92 Plus Developers Guide for information on how and when to
verify that the exponent is within the range required by the calculator user
floating-point representation and what to do when it is not.
There are also several specific floating-point representations for signed zeros,
infinities, and undefined values (or NANs).
positive zero
Low addressHigh Address
2 bytesMSD 8 bytes LSD
0x00000x00000000, 0x00000000
16. Working with Numbers
in
negative zero
Low addressHigh Address
2 bytesMSD 8 bytes LSD
0x80000x00000000, 0x00000000
positive infinity
Low addressHigh Address
2 bytesMSD 8 bytes LSD
0x7FFF0xAA00BB00, 0x00000000
negative infinity
Low addressHigh Address
2 bytesMSD 8 bytes LSD
0xFFFF0xAA00BB00, 0x00000000
unsigned infinity
Low addressHigh Address
2 bytesMSD 8 bytes LSD
0x7FFF0xAA00CC00, 0x00000000
TI-89 / TI-92 Plus Sierra C Assembler Reference Manual
Not for Distribution
Beta Version February 2, 2001
Section 2: Compiler
invalid floating-point representation (undefined or NAN)
Low addressHigh Address
2 bytesMSD 8 bytes LSD
0x7FFF0xAA000000, 0x00000000
All of the special internal floating-point values are valid inputs to TI BCD
floating-point routines and will be handled correctly when encountered. It is not
necessary to check for them after every floating-point operation to detect
overflows or other special values. However, none of the special values shown
above can be directly entered on the TI-89 or TI-92 Plus calculators. The signed
zeros may result from a calculation but since they are displayed as 0. on the
calculator, they can only be recognized by their behavior in other calculations.
The infinities and invalid floating-point values must be converted to other
representations before being made available to the user. See chapter
16. Working with Numbers
information on how and when to verify that the floating-point value is valid as
required by the calculator user floating-point representation and what to do when
it is not.
63
Figure 2.3: Special Internal Floating-Point Representations
in the TI-89 / TI-92 Plus Developers Guide for
2.9.5. Enumeration Types
An enumeration type is a set of integer values represented by identifiers; these
identifiers are referred to as enumeration constants. The declaration of an
enumeration type is similar to that of a structure or union type. For example, the
following declaration creates an enumeration type
red, green, blue
this type:
enum color { red, green, blue = 8, white } boat, car;
The enumeration constants (
are assigned integer values when the
constants are assigned either values generated automatically by the compiler or
values specified by an assignment operator and a constant integer expression.
When an explicit assignment is not made, the first enumeration constant in the
list is assigned the value zero; subsequent enumeration constants are assigned
the value of the previous constant plus one. In the above example, the
enumeration constants have the following values:
red = 0
green = 1
blue = 8
white = 9
, and
white
— whose values are
color
— and declares the variables
red, green, blue
enum
, and
type is created. Enumeration
in the above example)
white
boat
and
car
to be of
TI-89 / TI-92 Plus Sierra C Assembler Reference Manual
Not for Distribution
Beta Version February 2, 2001
64
Section 2: Compiler
Using the enumeration constant assignment capability, it is possible (and legal)
to create different enumeration constants with the same integer values.
Enumeration constants are integer type objects and are treated the same as
numerical integer constants (i.e., their values cannot be modified). They can be
used anywhere an integer constant can be used except in an assignment to an
enumeration variable of a different
enum
same block scope must have unique names so that they can be distinguished
from each other as well as other variables, functions, and
Variables and other objects of enumeration type can be declared in the
declaration containing the type definition (as in the above example) or in
subsequent declarations that specify the enumeration type name. If subsequent
declarations will not be made, the enumeration type name (
omitted from the initial declaration. For example, the following three sets of
declarations are equivalent:
enum { sunny, overcast, rainy } CA, FL, NJ;
enum weather { sunny, overcast, rainy } CA, FL, NJ;
in the above example) is placed into the same name
tags.
Enumeration variables and objects are treated the same as integers except in
assignments that involve incompatible enumeration types. An enumeration type
is the same size as an
unless the
int
flag is specified. When this flag is
-XN
specified, the size of an enumeration type is determined by the values of its
associated enumeration constants. If the value of each enumeration constant fits
in a
signed char
of each enumeration constant fits in a
the same size as a
as an
int
.
, the enumeration type is the same size as a
, the enumeration type is
short int
signed short int
. Otherwise, the enumeration type is the same size
. If the value
char
TI-89 / TI-92 Plus Sierra C Assembler Reference Manual
Not for Distribution
Beta Version February 2, 2001
Section 2: Compiler
As previously stated, enumeration constants and variables can be used anywhere
integer types can be used except in assignments involving different enumeration
types. The following examples utilize the enumeration objects declared on the
previous page to demonstrate
int i;
CA = sunny;/* legal*/
i = 25;/* legal*/
red = 36;/* illegal, red is constant*/
car = boat;/* legal*/
car = NJ;/* illegal*/
FL = green;/* illegal*/
boat = i;/* legal*/
2.9.6. Bit Field Description
The C language allows integer data to be stored in spaces that differ in size from
those provided by the basic integer types. Such arbitrarily sized integers are
called bit fields. They are supported by allowing the width in bits of a structure or
union member to be specified using a colon and a constant expression after the
member declarator. In the following declaration, x.a is a 10-bit integer, x.b is a
12-bit integer, and x.c is a seven-bit integer:
type checking across assignments:
enum
65
struct s {
long int a:10;
long int b:12, c:7;
} x;
The three members of this structure occupy a total of four bytes; internally, they
are packed into a space that has the same size and alignment as a
long int
Bit fields can be packed in any of the four basic integer types (for example,
short int, int
, or
long int
allowable bit field size. Bit field declarations can also include the
unsigned
type specifiers. The
). The size of the type determines the maximum
signed
signed
type specifier causes the bit field to be
.
char
and
interpreted as a signed quantity — the most significant bit of the bit field
(for example, the sign bit) is extended when extracting the contents of the field.
The
unsigned
type specifier can also be used, but has no effect since bit fields
are unsigned by default. Given the following initialization, the three bit field
members will have the values shown:
struct t {
int i:3;
signed int j:3;
unsigned int k:3;
} y = { -1, -1, -1 };/* -1 bit pattern all 1's */
,
y.i = 7
y.j = -1
y.k = 7
TI-89 / TI-92 Plus Sierra C Assembler Reference Manual
Not for Distribution
Beta Version February 2, 2001
66
Section 2: Compiler
Note:
Since most computers do not allow bits to be addressed directly, it is illegal to take the
address of a bit field. As a result, pointers to bit fields and arrays of bit fields are not
permitted. Furthermore, functions are not allowed to return bit fields.
2.9.7. Bit Field Internal Representation
Bit fields are packed into memory as efficiently as possible. Each bit field is
placed in the lowest order bits (highest address) available in the specified integer
type. If a bit field does not fit in the remainder of the current integer, it is placed in
a new one (i.e., it cannot span two integers). A bit field declaration without an
identifier is used to force a desired alignment. If the field width is nonzero, the
bits are allocated exactly as if an identifier was present in the declaration; if the
field width is zero, the remainder of the current integer is skipped. For example,
the following declaration causes memory to be allocated as shown:
struct tag {
long int a:10;
long int b:20;
long int c:5;
long int :5;
long int d:8;
long int :0;
long int e:12;
} s;
312990
ba
3117940
dc
31110
e
TI-89 / TI-92 Plus Sierra C Assembler Reference Manual
Not for Distribution
Beta Version February 2, 2001
Section 2: Compiler
2.9.8. Const Type Specifier
67
The value of an object that is declared with the
type specifier cannot be
const
modified; therefore, the object cannot appear as the left-hand side of an
assignment, nor as the operand of the '++' or '− −' operator. The following
examples demonstrate the legality of various modifications involving
const
objects:
const int a = 99;
const int b = 66;
const int *p = &a;
a++;/* illegal*/
b−−;/* illegal*/
a = 10;/* illegal*/
p = &b;/* legal*/
*p = 20;/* illegal*/
The
const
type specifier can be used with integer types, floating-point types,
structure and union types, and enumeration types. It can also be used with
individual members of structures and unions, in which case only the specified
members are affected. If the
specifiers or with only the
The
const
type specifier can also be used to declare pointers to constant objects
volatile
type specifier is used without any other type
const
type specifier (see below), type
is implied.
int
and constant pointers to constant and nonconstant objects. Just as an asterisk
) in a declaration indicates a pointer to an object, the construct *
(
*
const
indicates a constant pointer to an object. A constant pointer cannot be modified;
no restrictions are placed on the object to which it points. The following
declarations define a constant
pointer to a pointer to a constant pointer to a constant
, a constant pointer to an
int
int
double
, and a constant
, respectively:
const int a;
int * const b;
const double * const ** const c;
A pointer to a nonconstant object can be assigned to a pointer to either a
constant or nonconstant object; however, a pointer to a constant object can only
be assigned to a pointer to a constant object. These pointer assignment rules
were established to help prevent accidental modifications of constant objects with
dereferenced pointers to nonconstant objects. These rules can be easily
sidestepped with a type cast, but this is not recommended since it could result in
an attempt to modify data stored in Read-Only Memory (ROM).
TI-89 / TI-92 Plus Sierra C Assembler Reference Manual
Not for Distribution
Beta Version February 2, 2001
68
In most embedded systems, as much information as possible is placed in ROM
(e.g., the entire code (
) section). The
.text
important in these environments because it causes declared data (except when
also declared
volatile
) to be placed in the
For additional information on the use of the
2.14 Static Storage Initialization
2.9.9. Volatile Type Specifier
Section 2: Compiler
type specifier is extremely
const
section — i.e., directly in ROM.
.text
type specifier, refer to section
const
.
An object that is declared with the
volatile
type specifier is guaranteed to be
accessed, in its entirety, each time it is referenced in the source. As a result, the
compiler must forgo optimizations that would alter either the size of references to
the object (e.g.,
char, short, int
, etc.) or the number of references made to the
object. For example, the compiler cannot test a bit in a four-byte volatile object by
referencing only the byte that contains the bit of interest; the object must be
referenced as a four-byte entity. As the following example illustrates, the compiler
would not be able to optimize the first function, which reads data from an I/O port,
as though it were written as the second function:
type specifier is used for memory-mapped I/O ports, variables
shared by other processes, variables modified inside interrupt handlers and error
handlers, and any other variables that are accessed in ways not obvious to the
compiler.
TI-89 / TI-92 Plus Sierra C Assembler Reference Manual
Not for Distribution
Beta Version February 2, 2001
Section 2: Compiler
69
The
volatile
type specifier (see section
const
type specifier observes the same declaration usage rules as the
conjunction with the
volatile
, a constant volatile
int
pointer to a pointer to a volatile
volatile int a;
volatile const int b;
volatile double ** volatile const * volatile c;
The second declaration above could be used for a resource such as a real-time
clock; the compiler does not know when the value of a real-time clock changes,
and a program should not attempt to modify it.
A pointer to a nonvolatile object can be assigned to a pointer to either a volatile
or nonvolatile object; however, a pointer to a volatile object can only be assigned
to a pointer to a volatile object. These pointer assignment rules, which are
analogous to the rules for constant pointers described above, were established to
help prevent accidental references of volatile objects with dereferenced pointers
to nonvolatile objects.
2.9.10. Touch Operator
const
2.9.8 Const Type Specifier
); it can be used in
type specifier. The following declarations define a
, and a volatile pointer to a constant volatile
int
double
, respectively:
The
_touch(*
, to “touch” the memory location pointed to by
tst
pointer_to_volatile_argument
embedded systems design, it is often necessary to touch an address-mapped
piece of hardware — e.g., to increment a counter or set a latch. The argument to
_touch( )
otherwise,
must be a dereferenced pointer to a
_touch( )
behaves as an ordinary function.
2.9.11. Void Type Specifier
An expression of type
can be neither referenced nor converted (implicitly or explicitly) to another type.
The
type specifier is most frequently used in the declaration of functions
void
that return no values. It is illegal for a
return value of a
also be used to indicate that the value of an expression is ignored. For example,
the following function, which returns no value, uses a
return value of the
void report_error(int error, int line)
{
(void)printf("Error %d on line: %d\n", error, line);
}
void
function to be used in an expression. The
void
function:
printf
) operator uses the test instruction,
pointer_to_volatile_argument
volatile
integer type object;
has no value associated with it. Such an expression
function to return a value or for the
void
type can
void
cast to discard the
void
. In
TI-89 / TI-92 Plus Sierra C Assembler Reference Manual
Not for Distribution
Beta Version February 2, 2001
70
Section 2: Compiler
The
cast is not necessary in the above example, but many programmers
void
use the cast to indicate that the return value is being intentionally ignored.
2.9.12. Void Pointer (void *)
A pointer to
meaning to the compiler. A pointer to any type of object can be converted to a
pointer and back again with the resultant and original pointers guaranteed
void
to compare equal. Additionally,
together in assignment and comparison expressions with no explicit type
conversion. The following examples demonstrate legal and illegal pointer
expressions:
The compiler provides for both the implicit and explicit conversion of values from
one type to another.
A value may be explicitly converted to another type with a cast operator.
•
An operand may be implicitly converted to another type so that a specific
•
arithmetic or logical operation can be performed.
An implicit conversion may result from the assignment of an object of one
•
type to an object of another type.
An argument to a function may be implicitly converted to another type in
•
preparation for the function call.
The value returned by a function may be implicitly converted to the function
•
return type before the function return.
2.10.1. General Considerations
When a value of one type is converted to a value of another type, the internal
representation (i.e., bit pattern) may change. Conversions between floating-point
types and integer types always involve a change in representation. When
TI-89 / TI-92 Plus Sierra C Assembler Reference Manual
Not for Distribution
Beta Version February 2, 2001
Section 2: Compiler
converting between different integer types, the resultant representation is easily
determined since the target machine uses a two’s complement representation.
Conversions between integer types of the same length involve no change in
representation. Conversions from longer integer types to shorter integer types
involve a truncation of the excess high order bits. Conversions from shorter
integer types to longer integer types involve the padding of the additional high
order bits with all 1’s or 0’s.
2.10.2. Integer Types
When an integer of one type is converted to an integer of another type, the
resultant value is determined according to the following rules:
When a signed integer type is converted to another signed integer type of
•
equal or greater length, the value remains unchanged.
When an unsigned integer type is converted to another unsigned integer type
•
of equal or greater length, the value remains unchanged.
71
When an unsigned integer type is converted to an integer type of greater
•
length, the value remains unchanged.
When an integer type is converted to an integer type of shorter length, the
•
resultant value is the value of the truncated bit pattern as interpreted by the
new type.
When a signed integer type is converted to an unsigned integer type of
•
greater length the resultant value is unchanged if the value of the signed
integer was non-negative. Otherwise, the bit pattern representation in the
unsigned integer is determined by promoting the signed integer to a signed
integer of the same length as the unsigned integer.
When an integer type is converted to an integer type of the same length, the
•
resultant value is the value of the bit pattern as interpreted by the new type.
2.10.3. Floating-Point and Integer Types
When a floating-point type is converted to an integer type, the resultant value is
determined by discarding the fractional part. If the conversion is to an
and the value of the integral part cannot fit in the space provided, the
long
behavior is undefined. If the conversion is to any other integer type and the value
of the integral part cannot fit, the integral part is first assigned to a
and is then converted to the specified integer type using the integer conversion
rules. If the integral part cannot fit in a
positive or negative value (depending on the sign of the integral part) that can be
represented by a
signed long
.
signed long
unsigned
signed long
, it is assigned the largest
TI-89 / TI-92 Plus Sierra C Assembler Reference Manual
Not for Distribution
Beta Version February 2, 2001
72
2.10.4. Floating-Point Types
Since all TI BCD floating-point data objects are ten bytes, there is no promoting
to
float
double
difference between them. TI floating-point arithmetic will recognize that a
has only 14 significant digits. If a cast from
round14
recommended to always use
accuracy. (See section
double
or
function on the TI-89 / TI-92 Plus is available. However, it is strongly
or demoting
double
double
to
is also ignored. This does not imply that there is no
float
double
2.9.3 Floating-Point Types
to
float
, taking advantage of the increased
2.10.5. Usual Arithmetic Conversions
Most binary operators that require operands of arithmetic type cause implicit
conversions (to yield a common type). These conversions are known as the
usual arithmetic conversions
specifies the performed conversions:
. The first applicable rule in the following lists
Section 2: Compiler
. Explicit type casting of
double
to
for more information.)
is desired, the
float
float
to
float
If either operand is of type
•
double
If either operand is of type
•
If either operand is of type
•
to type
If one operand has type
•
conversion depends on the specified integer size (see
integers are used (as on the TI-89 / TI-92 Plus), the operand of type
unsigned int
converted to the type
If either operand is of type
•
long int
If either operand is of type
•
type
If either operand is
•
16-bit integers are used, as on the TI-89 / TI-92 Plus, and the operand type is
unsigned short int
its value.)
.
unsigned long int
is converted to the type
.
unsigned int
.
not
, it will be converted to
double
float
unsigned long int
.
long int
unsigned long int
long int
unsigned int
of type
, the other operand is converted to type
, the other operand is converted to type
, the other operand is converted
and the other has type
long int
, the other operand is converted to type
, it is converted to type
int
; otherwise, both operands are
.
, the other operand is converted to
unsigned int
unsigned int
flag). When 16-bit
-XI
. (Exception: if
int
in order to preserve
float
, the
.
If both operands are of type
•
TI-89 / TI-92 Plus Sierra C Assembler Reference Manual
, no conversion is necessary.
int
Not for Distribution
Beta Version February 2, 2001
Section 2: Compiler
73
Note:
Note:
These binary conversion rules do not apply to the shift operators (>> and <<), since the
operands are not combined directly. Instead, each operand is treated as if it were an
operand of a unary operator.
Operands of type integer are not always converted as stated above. Sometimes, smaller
integer types are used if doing so results in improved run-time performance without loss
of precision.
2.10.6. Restrictions
Type conversions can be performed on any of the scalar types — i.e., integer
types, floating-point types, enumeration types, and pointers. There are, however,
certain restrictions imposed upon both explicit and implicit conversions.
The only explicit conversions that are not permitted are those between
floating-point types and pointers; any other conversions involving scalar types
are allowed.
Additional restrictions apply to implicit conversions that are made across
assignments and through function returns. Any statement requiring either an
implicit conversion between two enumeration types or an implicit conversion
involving a pointer (excluding null pointers and void pointers) is illegal. In both of
these cases, however, the conversion will be performed and a warning issued.
All conversions between
float
and
double
are ignored since they are both 10
byte objects, however, no warning or error is issued.
2.11. Function Calling Conventions
When a function is called with arguments, the value of each specified argument
is pushed onto the stack. (Hereafter, the value of an argument will be referred to
simply as the argument.) The arguments are pushed onto the stack in reverse
order — i.e., beginning with the rightmost argument. After a function call, the
stack pointer is incremented, if necessary, to restore its value to that prior to the
stacking of the arguments.
Note:
Note:
When the -O,
necessarily be incremented after every function call that has arguments pushed onto the
stack. In the presence of any of these flags, attempts are made to coalesce more than
one stack cleanup into a single stack adjustment.
If the top of the stack is free, the rightmost argument is sometimes moved directly into
the top stack position (i.e., the stack pointer is not decremented); otherwise, it is pushed
onto the stack. Additional arguments are always pushed onto the stack.
-Oz
, or
command line flag is specified, the stack pointer will not
-Oc1
TI-89 / TI-92 Plus Sierra C Assembler Reference Manual
Not for Distribution
Beta Version February 2, 2001
74
The amount of stack space used by each function argument is determined by the
type of the argument and whether the function is declared with a function
prototype. Structure arguments are pushed onto the stack and take as much
stack space as necessary to fit the entire structure. If necessary, the stack space
allocated to a structure argument is rounded up to a multiple of four bytes.
2.11.1. Declarations and Definitions
Section 2: Compiler
A function
declaration
declares a variable to be a function and specifies the type
of value it returns. A prototype function declaration also establishes the number
of function arguments and the types of those arguments. A function declaration
does not cause memory to be allocated or code to be generated. A function
definition
causes memory to be allocated and code to be generated; it also
serves as a function declaration.
2.11.1.1. Function Prototypes
A function prototype is a function declaration or definition that specifies both the
number of arguments and the argument types. Function prototypes prevent
errors caused by passing the wrong argument type or wrong number of
arguments to a called function.
The following are examples of prototype function declarations:
double f1( short x, int y, double z );
double f2( short, int, double );
double f3( short, int, double, ... );
double f4( void );
The functions f1, f2, f3, and f4 are declared to return a value of type
first two functions are declared to accept exactly three arguments: a
, and a
int
double
function declarations are identical. The formal parameters x, y, and z in function
f1 are optional and are used for documentation purposes only. The scope of
these optional parameter names extends only to the end of the declaration; the
names do not have to match the formal parameter names in the actual function
definition. Function f3 is declared to accept three or more arguments. The ellipsis
notation (, . . .) informs the compiler that zero or more additional arguments of
unknown type will be passed to the function. In the body of the function definition,
the macros
be used to access the additional argument values. Function f4 is declared to
accept no arguments; calling f4 with any arguments will result in an error.
, respectively. Except for the function names, the first two
va_start( )
and
va_arg( )
defined in the include file
double
short
tiams.h
. The
, an
should
TI-89 / TI-92 Plus Sierra C Assembler Reference Manual
Not for Distribution
Beta Version February 2, 2001
Section 2: Compiler
An in-scope prototype function declaration not only establishes the function
return type, but also enables verification that the function is called with the
correct number of arguments and that the type of each argument is compatible
with its corresponding formal parameter. The type checking and conversions that
are performed are identical to those performed when assigning a value using the
assignment operator ( = ). For example, if a function that is defined with a
parameter of type
automatically converted to a value of type
stack; an explicit cast operator is unnecessary. Additional arguments permitted
by the ellipsis notation (, . . .) are handled as if they were arguments to a function
declared without a prototype. When declared with the ellipsis notation, type
checking and automatic type conversions cannot be performed; instead, the
ANSI C integral and floating-point promotion rules are applied to the arguments.
The following is an example of a prototype function definition:
double
is called with an argument of type
double
double f1( short a, int b, double c )
{
/* function body */
}
, the argument is
int
before being pushed onto the
75
The function f1 is defined to accept three arguments and return a value of type
double
. The formal parameter type declarations
declare how the parameters will be used inside the function. The Sierra C
compiler specifies how the parameters are pushed onto the stack at the function
call site. If a prototype declaration is in scope, an argument of type
promoted to an
before being pushed onto the stack. The rules for determining
int
how an argument is pushed onto the stack in the presence of a prototype is
determined by specific command line flags. Table 2.4 (section
Argument Values
) summarizes how arguments of different types are pushed
onto the stack with and without a prototype in scope.
2.11.1.2. Old-Style Declarations
An old-style function declaration is a declaration that provides only the type of the
return value. Information on the types and number of arguments is not
established. The following is an example of an old-style (nonprototype) function
declaration:
int f5();
The function f5 is declared to return a value of type
number and types of arguments is specified. This declaration could be deleted
from the program without any effect, since the default function return type is
int a, short b
, and
short
2.11.2 Passing
; no information about the
int
double c
may be
int
.
TI-89 / TI-92 Plus Sierra C Assembler Reference Manual
Not for Distribution
Beta Version February 2, 2001
76
Section 2: Compiler
The following is an example of an old-style function definition:
int f5( a, b, c, d, e )
int a;
short b;
long c;
float d;
double e;
{
/* function body */
}
The function f5 is defined to accept five arguments and return a value of type
The formal parameter type declarations
double e
declare how the parameters will be used inside the function. They do
int a, short b, long c, float d
not describe the types of the actual parameters that are pushed onto the stack at
the function call site. The expected types of the actual parameters are
determined by the integral and floating-point promotion rules. The promotion
rules state that arguments of type
that arguments of type
are converted to type
float
char
and
are converted to type
short
double
are performed.
At a function call site, there is no information available on the types of the
arguments. If a called function has a formal parameter declared to be of type
, it is expecting an actual parameter of type
float
the stack. If, however, the parameter is of type
either a
pushed as an
float
or a
double
. Finally, if the function is called with too few or too many
int
at the call site to prevent it from being incorrectly
double
, it must be explicitly cast to
int
parameters, the error will go undetected during compilation.
2.11.1.3. Mixing Prototype and Old-Style Declarations
The Sierra C compiler supports both new-style (prototype) and old-style
(nonprototype) function declarations and definitions as specified by the ANSI C
standard. However, it is highly recommended that the prototype style be used
exclusively.
int
, and
, and
int
; no other conversions
to have been pushed on
.
Mixing prototype declarations and old-style function definitions should be avoided
because it will often create problems. The following is an example of a prototype
declaration and an old-style function definition:
int func( short a );
int func( a )
short a;
{
/* function body */
}
TI-89 / TI-92 Plus Sierra C Assembler Reference Manual
Not for Distribution
Beta Version February 2, 2001
Section 2: Compiler
When the file containing the above example is compiled, the following warning
will be issued:
This message is generated because the prototype declaration declares a
function that accepts a
function that accepts an
definition is recognized as an
format; therefore, the integral promotion rules are applied to the
parameter. To further understand the problem, examine the case in which a
is pushed as two bytes in the presence of a prototype. A two-byte value
short
will be pushed onto the stack because a prototype declaration is in scope;
however, a four-byte argument will be expected inside the function that was
defined using the old style. A problem also results if a function that is defined with
a prototype to accept a
declaration) in scope.
The above problems can be avoided through exclusive use of prototype
declarations and definitions. The compiler command line flags
can be used to verify that appropriate declarations are being utilized. The
-Xf3
flag causes a warning to be issued when a function is called outside the
-Xf1
scope of a function declaration. The
when a function is declared without a prototype. The
of
parameter, while the function definition declares a
short
parameter. The formal parameter in the function
int
because the function definition is in the old-style
int
is called with an old-style declaration (or no
short
flag causes a warning to be issued
-Xf2
flag (the combination
-Xf3
and
) causes a warning to be issued if a function is called without a
-Xf2
short
-Xf1, -Xf2
77
, and
2.11.2. Passing Argument Values
Several factors determine how an argument value is pushed onto the stack when
a function call is made: the specified command line flags, the type of the
argument, and whether or not a function prototype is in scope. If a function
prototype is not in scope, the integral and floating-point promotion rules will be
applied to the argument types.
The
rather than 32 bits (default). Specifying the
will cause all integer types (except for type
independent of whether a function prototype is in scope. The
determine how argument values of different types are passed only in the
presence of a function prototype. In the presence of a prototype, parameters of
type
specified, and are pushed as four-byte objects when the
flag instructs the compiler to interpret objects of type
-XI
char
and
are pushed as two-byte objects when the
short
as 16 bits
int
flag, as on the TI-89 / TI-92 Plus,
-XI
) to be passed as 16-bit objects
long
flags
-Os#
flag is
-Os2
flag is specified.
-Os4
TI-89 / TI-92 Plus Sierra C Assembler Reference Manual
Not for Distribution
Beta Version February 2, 2001
78
Compiler and Flags char short int long float double
Table 2.4 shows the sizes in bytes that function arguments occupy on the stack.
The sizes are shown as a function of the compiler and associated command line
flags, argument type, and whether or not a prototype is present. The numbers in
the table to the left of the slash ( / ) are sizes in bytes in the presence of a
prototype; the numbers to the right are sizes in the absence of a prototype.
2.11.3. Accessing Parameters
Inside the called function, the function parameters are accessed from the stack.
The exact mechanism for accessing the parameters is determined by the
presence or absence of the
The
instruction, if present, is the first instruction in a function; it is used to set
link
up a stack frame using address register a6 as the frame pointer (refer to the
instruction in the
M68000 Family Programmer’s Reference Manual
instruction is also used to leave an extra four bytes free on the top of the stack.
When the top of the stack is free, the rightmost parameter in a function call can
be moved onto the stack instead of pushed onto the stack. The default action is
to use a
instruction only when a stack variable is referenced while the stack
link
is temporarily displaced, or when the program is to be examined with a
source-level debugger. Its use can be forced with the
When the
the stack to be free a
instruction is not used and a function parameter expects the top of
link
subq.l #4, sp
function to free up the top of the stack.
The
movem
instruction (
saves on the stack the registers that must remain unmodified across a function
link
move
and
movem
instructions.
-Of1
command line flag.
instruction is inserted at the start of the
or
movea
instruction if only one register is saved)
). The
link
link
TI-89 / TI-92 Plus Sierra C Assembler Reference Manual
Not for Distribution
Beta Version February 2, 2001
Section 2: Compiler
79
call. If the
be saved into stack space reserved by the
movem
movem
instruction pushes the registers to be saved onto the stack. A second
instruction restores the saved registers before the function returns.
When the
instruction is used, the
link
instruction is present, the function parameters are referenced
link
movem
instruction moves the registers to
link
. If the
is not used, the
link
relative to the frame pointer — register a6. The offset from register a6 required to
reference the leftmost function parameter (i.e., the last parameter pushed onto
the stack) is eight bytes: four bytes for the function return address and four bytes
introduced by the
When the
instruction is not present, the function parameters are referenced
link
instruction.
link
relative to the stack pointer — register a7 (also referred to as sp). The offset
from register a7 required to reference the leftmost function parameter is
determined as follows:
Four bytes for the function return address.
•
Four bytes for each data or address register pushed onto the stack.
•
Ten bytes for each floating-point register pushed onto the stack.
•
Four bytes introduced by the
•
addq.l #4, sp
instruction, if present.
2.11.4. Returning Values
Functions that return scalar (nonaggregate) data types return their data in one of
several registers. Integer data types are returned in register d0. Address pointers
are returned in register a0 (d0 when the
data types are returned in register
determined by the data type specified in the function declaration.
Functions that return a structure are significantly more complicated than
functions that return a scalar data type. Inside the called function, the structure to
be returned is copied into stack space that is allocated by the calling function.
Information about the reserved stack space is passed to the called function as an
address pointer that is pushed onto the stack immediately before the function call
(as if it were the function’s leftmost argument). Immediately before the function
returns, the structure is copied into the reserved space. The address of the
reserved space is returned in register a0. Immediately after the function returns,
the pointer in a0 is used to copy the returned structure to its destination.
flag is specified). Floating-point
-XA
. The type of the return register is
fp0
TI-89 / TI-92 Plus Sierra C Assembler Reference Manual
Not for Distribution
Beta Version February 2, 2001
80
Section 2: Compiler
The structure return mechanism can be further clarified using a pair of examples.
Example A shows a function returning a structure, and Example B uses structure
pointers to demonstrate (at the C level) what the compiler generates internally
when a function returns a structure. These examples generate essentially
identical code.
Example AExample B
struct s {struct s {
int a;int a;
int b;int b;
};};
struct s f();struct s *f();
struct s x;struct s x;
main()main()
{{
TI-89 / TI-92 Plus Sierra C Assembler Reference Manual
A function that returns anything other than an integer
before it is called. Failure to do so could result in unexpected behavior. Without a
declaration in scope, a called function is assumed to return an integer; therefore, its
return value is expected to be in d0. However, if the function actually returned a
pointer, the return value would be found in a0. Similarly, if the function returned
floating-point data, the return value would be in
object of type
that would result in a corrupted integer value.
A function that returns a structure
when the return value is not used. Without a declaration in scope, the pointer to the
structure return area is not pushed onto the stack. The called function, which
assumes that the memory pointer has been pushed, cannot access its parameters
correctly and may corrupt memory when it attempts to return a structure.
char
or
short int
be declared in a file
must
. Even if the function returned an
fp0
, the upper portion of d0 might contain invalid data
be declared in a file before it is called, even
must
Not for Distribution
Beta Version February 2, 2001
Section 2: Compiler
2.11.5. Register Usage
Data, address, and floating-point registers are used to hold both the values of
automatic variables and the intermediate results generated during the evaluation
of an expression. The registers used to hold intermediate expression values are
referred to as scratch registers. Registers
as scratch registers by the compiler; their values are not guaranteed across
function calls. When the
is guaranteed across function calls. Registers
d2
must remain stable across function calls and are thus required to be saved and
restored in any function that uses them. Registers a6 (frame pointer) and
(stack pointer) must also remain stable across function calls. The
restores registers a6 and a7.
command line flag is specified, the value of register
-X2
d0–d2, a0–a1
d3–d7, a2–a5
2.12. Compiler-Generated Function Calls
The compiler usually generates in-line assembly code when translating C
programs. Sometimes, however, the compiler calls library functions to perform
operations when in-line code would be inefficient or when special debugging
options have been requested. The compiler-generated function calls fall into the
following three categories:
, and
fp0–fp1
, and
unlk
81
are used
fp2–fp7
a7
instruction
1. calls to integer arithmetic functions
2. calls to floating-point software functions
3. calls to debugging functions
Compiler-generated function calls do not follow the standard C function calling
conventions. For example, when calling internal integer arithmetic functions,
parameters are passed in registers instead of on the stack. The following
sections describe the special calling conventions used by each category of
compiler-generated function calls.
TI-89 / TI-92 Plus Sierra C Assembler Reference Manual
Not for Distribution
Beta Version February 2, 2001
82
2.12.1. Internal Integer Arithmetic Functions
Section 2: Compiler
The 68000 compiler,
com68
, generates function calls to perform integer
arithmetic when in-line code would require an unacceptable amount of space. It
also generates function calls to perform some division and modulus operations.
The size and type of the operands determine whether a function call is
generated. For example, the division of two signed 16-bit operands will be
handled by in-line code, but the division of two signed 32-bit operands will be
handled by a function call. Table 2.5, Integer Arithmetic Functions, lists the
functions that are called by the 68000 compiler to perform the specified integer
arithmetic operations.
Function Name Operation
__du16u16 Divide 16-bit unsigned by 16-bit unsigned
__ds32s32 Divide 32-bit signed by 32-bit signed
__du32u32 Divide 32-bit unsigned by 32-bit unsigned
__ds16u16 Divide 16-bit signed by 16-bit unsigned
__ms16u16 Mod 16-bit signed with 16-bit unsigned
__mu16u16 Mod 16-bit unsigned with 16-bit unsigned
__ms32s32 Mod 32-bit signed with 32-bit signed
__mu32u32 Mod 32-bit unsigned with 32-bit unsigned
Table 2.5: Integer Arithmetic Functions
Arguments are passed to the functions listed in Table 2.5 in registers d0 and d1;
they are not passed on the stack. Results are always 32 bits and are returned in
register d1 (basically,
d1 = d1 / d0
or
d1 = d1 % d0
). The functions that operate
on 16-bit operands use only registers d0 and d1. The functions that operate on
32-bit operands also use registers d2, a0, and a1.
The following example, which shows both a 68000 C file and the generated
assembly code, illustrates the generation of an internally generated function call:
extern int i, j; move.l _i,d1
void f( void ) move.l _j,d0
{ jsr __ds32s32
i = i / j; move.l d1,_i
} rts
TI-89 / TI-92 Plus Sierra C Assembler Reference Manual
Not for Distribution
Beta Version February 2, 2001
Section 2: Compiler
2.12.2. Internal Floating-Point Functions
The Sierra C compiler supports two different floating-point formats, each one
being automatically used in specific cases. The supported formats include the
TI BCD floating
compiler, not on the TI-89 / TI-92 Plus. Floating
are performed in the IEEE format by the compiler while all other floating
operations are handled by internally generated calls to the BCD floating
routines on the TI-89 / TI-92 Plus. Floating
BCD if they are used as operands in the TI BCD floating
important to remember that in rare cases, it is possible that a value computed in
the IEEE format and converted to BCD may differ from the result of the identical
operation if performed by the TI floating
accuracy between IEEE and BCD. Floating
used with caution for this reason, although since the IEEE format is comparable
to 20 BCD digits and the TI BCD values have 16 digits, differences will be
extremely rare.
point format and an IEEE format which exists only in the
-
point constants are converted to
-
point routines due to the difference in
-
-
point operations on constants
-
point
-
point
-
point routines. It is
-
point constant operations should be
83
When generating code for the TI BCD floating-point routines, floating-point
registers
(
-80, a6
through
fp0
correspond to stack frame locations (
fp7
-10, a6
) through
), respectively; each location occupies ten bytes. To minimize the amount
of code needed to make an internally generated call, the compiler goes through
an interface function on the TI-89 / TI-92 Plus,
__bcd_math
. Calls to the
floating-point interface function differ from calls generated for C language
function calls in two major respects:
Operand information, including the specification of both source and
•
destination registers (when applicable), is encoded into a single two-byte
argument.
The called (not the calling) function restores the stack upon function return.
•
When using the function call to
__bcd_math
, a two-byte code word is inserted
into the instruction sequence immediately following the function call. The code
word fully describes the floating-point operation, the size of the operands, and
the effective addresses of both the source and destination operands. If both the
source and destination operands are registers (data and/or emulation
floating-point registers), no information other than that supplied by the code word
is required.
TI-89 / TI-92 Plus Sierra C Assembler Reference Manual
Not for Distribution
Beta Version February 2, 2001
84
Section 2: Compiler
Figure 2.4 explains how to decipher information in the floating-point emulation
code word. The operator and size components of the code word should be
self-explanatory. Source and destination registers refer to the actual processor
data registers and the emulation floating-point registers that correspond to
locations on the stack frame (as explained above). If the destination operand is a
register, the operator, size, and source operand determine whether it references
a data register or a floating-point register.
The TI software emulation is patterned after the 68881/2 floating-point
coprocessor (see section
3.1.2 Prerequisite Reading
more information is desired). The same rules and restrictions that apply to
68881/2 instruction operands apply to corresponding emulation instruction
operands. If one of the operands is specified by its absolute address, the 32-bit
address is pushed onto the stack immediately before the function call. If an
operand is specified to be an immediate
short
, immediate
the 16-bit or 32-bit immediate value or the 16-bit a6-relative frame displacement
is inserted into the instruction sequence immediately following the code word.
From the information in the code word, the called function adjusts its return
address to skip over the code word and the operand (if present).
The following example demonstrates the interface to the TI BCD floating-point
routines. Shown below is a sample C listing, followed by the code that is
generated after compilation.
TI-89 / TI-92 Plus Sierra C Assembler Reference Manual
Not for Distribution
Beta Version February 2, 2001
Section 2: Compiler
double area, radius;
void circle( void )
{
}
68000 C Compiler 3.2h Copyright 1987-99 by Sierra Systems. All rights
reserved.
TI-89 / TI-92 Plus Sierra C Assembler Reference Manual
Not for Distribution
Beta Version February 2, 2001
86
2.12.3. Debugging Functions
The compiler can be directed to insert calls to debugging functions in the
generated assembly code using the
and
-XS
defined as a C function) at the beginning of each function. The
the compiler to place a call to
following each line of C source code.
flags cause the compiler to place calls to
-Xs
-XS, -Xs
__line_ck
(i.e.,
, and
-Xc
_line_ck
Section 2: Compiler
command line flags. The
__stk_ck
defined as a C function)
(i.e.,
flag causes
-Xc
_stk_ck
Both the
_stk_ck
and
_line_ck
functions are intended to be provided by the
user. These functions provide a mechanism to check various aspects of a
program. Although the
_stk_ck
function will typically compare the current stack
pointer offset and the amount of stack space needed by the calling function to the
total amount of available stack space, on the TI-89 / TI-92 Plus, this is done
through hardware. Even though the traditional use for
_stk_ck
is no longer
necessary, the function may be used for any other debugging purpose desired.
The
_line_ck
function could be used to locate the position in a program where a
particular memory location is corrupted.
The
flag causes the compiler to insert calls to
-XS
_stk_ck
at the beginning of
every function in the file. The amount of stack space used by the function is
available to
_stk_ck
registers (i.e.,
The
-Xs
flag is identical to the
size
compiler to insert the call to
more than
size
in register d0. If the
d3–d7, a2–a7
, or
fp2–fp7
_stk_ck
_stk_ck
), it must save and restore them.
flag with the exception that it causes the
-XS
only when a function is expected to take
function uses any nonscratch
number of bytes of stack space. If no value is specified, the
default value of 40 bytes is used.
The
of compiled C source code. No information is passed to
flag causes the compiler to insert a call to
-Xc
_line_ck
_line_ck
following each line
. The
_line_ck
function can be a very useful debugging aid, and its uses are left up to your
imagination. Unlike other functions,
it uses including scratch registers
_line_ck
must save and restore the condition codes in the status register,
d0–d2, a0–a1
_line_ck
must save and restore all registers
, and
fp0–fp1
. In addition,
because the function call may occur between the time a condition code is set and
when it is used.
Note:
TI-89 / TI-92 Plus Sierra C Assembler Reference Manual
The compiler adds a leading underscore ( _ ) to all function names and external
variables (unless the
( ) and _
abc
respectively.
( ) will appear in an assembly language listing as _
xyz
flag is specified). For example, the C language functions
-Xu
and _ _
abc
Not for Distribution
Beta Version February 2, 2001
xyz
,
Section 2: Compiler
2.13. Sections
The TI-89 / TI-92 Plus SDK includes example invocations of the compiler. You
must use the sections as shown in those files when compiling applications. The
compiler places information into four different sections for TI-89 / TI-92 Plus
applications:
.text, .data, .const
data that has not been declared
data is placed into
.bss
. The
, and
.bss
const
.bss
is placed into
section is set to zero during app initialization.
For more detailed information on application data storage and initialization, see
chapter
7. Flash Application Layout
in the TI-89 / TI-92 Plus Developers Guide
supplied with the TI-89 / TI-92 Plus SDK.
2.14. Static Storage Initialization
A data object with static storage duration can be assigned an initial value when it
is declared. The initializing value is placed directly into the
section of the program by the compiler; the assignment is not made at run-time.
If a static data object is not initialized in a declaration, the data object is assigned
to the
section where it is set to zero at the start of program execution.
.bss
87
(blank static storage). Initialized static
. Uninitialized static
.data
.text, .const
, or
.data
An initializer for an integer or floating-point data object must be an expression
that evaluates to a constant during compilation. A compile-time constant
expression may contain an arbitrary number of operators and subexpressions
and include both integer and floating-point constants. The same data type
conversions that apply across an assignment at run-time also apply to
compile-time initializations. The following are examples of legal compile-time
initializations:
int a = 50;
double b = 3.1415926;
int c = 2 * (5 + 7 / 3) - (122 && 15);
int *d = &c + 50;
char *e = (char *)0x80000;
When a scalar (pointer or arithmetic object) is initialized, a single expression
optionally enclosed in a single set of braces, is permitted in the declaration.
See section
2.12.2 Internal Floating-Point Functions
for more information on
initializing floating-point data objects. An initializer for a pointer must be an
expression that evaluates to an integer constant at compile-time or the address
of a static object, plus or minus a constant expression. When the address of an
object appears in an initializer the object must have been declared previously in
the same file. When a nonzero constant expression is used to initialize a pointer,
the expression must be cast to the appropriate pointer type.
TI-89 / TI-92 Plus Sierra C Assembler Reference Manual
Not for Distribution
Beta Version February 2, 2001
88
Section 2: Compiler
When the initialized variable is an aggregate (structure or array), the initializer
consists of a brace-enclosed list of comma-separated initializers. The initializers
in the list are applied to the aggregate in increasing member or subscript order. If
the aggregate contains members that are also aggregates, the same rules apply
recursively to the subaggregates. If there are fewer initializers in a
brace-enclosed list than there are members in the aggregate, the remaining
members are initialized to the value zero. It is illegal for there to be more
initializers in a brace-enclosed list than there are members in the aggregate. For
initialization purposes a union is treated as a structure that contains a single
member, where the single member is the first member of the union.
The following is a fully initialized array of structures:
struct {
int a;
int b[3];
} c[2] = { {1, {2,3,4}}, {5, {6,7,8}} };
The initial values for the array c are as follows: