Assembler Directives - wgrzegorz/c5xtools GitHub Wiki
Assembler Directives
Normative source: SPRU018D, chapter 4 (Assembler Directives). The directive set, syntax, and behavior described here are the ones the COFF assembler accepts; c5xasm implements the same grammar so that source written for the TI tool assembles unchanged.
Every directive statement may carry a label and a trailing comment; neither is
shown in the syntax lines below. In the syntax, square brackets mark optional
parameters, quotation marks shown as " must be typed literally where the text
says the name is quoted, and names such as value, expression, and
filename are placeholders.
Complete directive summary
| Directive | Syntax | Description |
|---|---|---|
| .align | .align |
Align the SPC on the next 128-word (page) boundary |
| .asect | .asect "section name", address |
Assemble into an absolute named initialized section (obsolete) |
| .asg | .asg ["]character string["], substitution symbol |
Assign a character string to a substitution symbol |
| .bes | .bes size in bits |
Reserve bits; a label points to the last reserved word |
| .bfloat | .bfloat value |
Initialize a 32-bit IEEE single-precision float; no page crossing |
| .blong | .blong value1 [, ... , valuen] |
Initialize one or more 32-bit integers; no page crossing |
| .break | .break [well-defined expression] |
End .loop assembly when the expression is true |
| .bss | .bss symbol, size in words [, blocking flag] |
Reserve words in the .bss uninitialized section |
| .byte | .byte value1 [, ... , valuen] |
Initialize one or more successive 8-bit bytes |
| .copy | .copy ["]filename["] |
Read source from another file; copied lines are listed |
| .data | .data |
Begin assembling into the .data section |
| .def | .def symbol1 [, ... , symboln] |
Declare symbols defined here and used by other modules |
| .drlist | .drlist |
Enable listing of all directive lines (default) |
| .drnolist | .drnolist |
Inhibit listing of certain directive lines |
| .else | .else |
Assemble a block when the .if condition is false |
| .elseif | .elseif well-defined expression |
Assemble a block when .if is false and this is true |
| .emsg | .emsg string |
Send a user error message; prevents object output |
| .end | .end |
End assembly |
| .endif | .endif |
End a .if conditional block |
| .endloop | .endloop |
End a .loop code block |
| .endstruct | .endstruct |
End a structure definition |
| .equ | symbol .equ value |
Equate a constant value with a symbol |
| .eval | .eval well-defined expression, substitution symbol |
Evaluate an expression into a substitution symbol |
| .even | .even |
Align the SPC on the next full-word boundary |
| .fclist | .fclist |
Allow listing of false conditional blocks (default) |
| .fcnolist | .fcnolist |
Inhibit listing of false conditional blocks |
| .field | .field value [, size in bits] |
Initialize a variable-length bit field |
| .float | .float value |
Initialize a 32-bit IEEE single-precision float |
| .global | .global symbol1 [, ... , symboln] |
Declare one or more global (external) symbols |
| .if | .if well-defined expression |
Assemble a block when the expression is true |
| .include | .include ["]filename["] |
Read source from another file; included lines are not listed |
| .int | .int value1 [, ... , valuen] |
Initialize one or more 16-bit integers |
| .label | .label symbol |
Define a loadtime-relocatable label in a section |
| .length | .length page length |
Set the listing page length |
| .list | .list |
Restart the source listing |
| .long | .long value1 [, ... , valuen] |
Initialize one or more 32-bit integers |
| .loop | .loop [well-defined expression] |
Begin a repeatable assembly block |
| .mlib | .mlib ["]filename["] |
Define a macro library |
| .mlist | .mlist |
Allow macro and loop-block expansion listing (default) |
| .mmregs | .mmregs |
Enter memory-mapped register names into the symbol table |
| .mmsg | .mmsg string |
Send a user message; counts are not changed |
| .mnolist | .mnolist |
Inhibit macro and loop-block expansion listing |
| .newblock | .newblock |
Undefine local labels |
| .nolist | .nolist |
Stop the source listing |
| .option | .option option list |
Select output listing options |
| .page | .page |
Eject a page in the source listing |
| .port | .port |
Turn on the assembler porting switch |
| .ref | .ref symbol1 [, ... , symboln] |
Declare symbols used here but defined elsewhere |
| .sblock | .sblock ["]section name["] [, "section name", ...] |
Designate initialized sections for blocking |
| .sect | .sect "section name" |
Begin assembling into a named initialized section |
| .set | symbol .set value |
Equate a constant value with a symbol |
| .space | .space size in bits |
Reserve bits; a label points to the first reserved word |
| .sslist | .sslist |
Allow substitution-symbol expansion listing |
| .ssnolist | .ssnolist |
Inhibit substitution-symbol expansion listing (default) |
| .string | .string "string1" [, ... , "stringn"] |
Initialize one or more packed text strings |
| .struct | [stag] .struct [expr] |
Begin a structure definition |
| .tab | .tab size |
Set the listing tab size |
| .tag | label .tag stag |
Assign structure attributes to a label |
| .text | .text |
Begin assembling into the .text section |
| .title | .title "string" |
Print a title in the listing page heading |
| .usect | symbol .usect "section name", size in words [, blocking flag] |
Reserve words in a named uninitialized section |
| .version | .version generation #number |
Set the processor generation |
| .width | .width page width |
Set the listing page width |
| .word | .word value1 [, ... , valuen] |
Initialize one or more 16-bit integers |
1. Directives that define sections
Six directives place code and data into the COFF sections. Each section has its
own section program counter (SPC); resuming assembly into a section continues
its SPC from where it left off. .text is the default section at the start of
an assembly.
| Directive | Syntax | Description |
|---|---|---|
| .text | .text |
Begin assembling into the .text section (usually executable code) |
| .data | .data |
Begin assembling into the .data section (usually initialized data) |
| .sect | .sect "section name" |
Begin assembling into a named initialized section |
| .asect | .asect "section name", address |
Named initialized section with absolute addresses (obsolete) |
| .bss | .bss symbol, size in words [, blocking flag] |
Reserve uninitialized words in .bss |
| .usect | symbol .usect "section name", size in words [, blocking flag] |
Reserve uninitialized words in a named section |
.bss and .usect do not end the current section. The assembler reserves the
requested space and then resumes assembling into whatever section was current.
For both, a nonzero blocking flag keeps the reserved space from crossing a
128-word page boundary when it is smaller than a page; a block larger than a
page starts on a page boundary. In .sect and .usect the section name is
significant to eight characters and must be double-quoted.
.asect is obsolete: the linker can now give any section separate load and run
addresses. It still works for compatibility. The first .asect into a given
absolute section requires the address; a later .asect continuing that
section must omit it.
.text ; executable code section
.data ; initialized data section
.bss temp, 4 ; 4 uninitialized words, label temp
.bss array, 100, 1 ; 100 words, blocked to one page
ptr .usect "var1", 1 ; 1 word in named section var1
.sect "Sym_Defs" ; named initialized section
2. Directives that initialize constants
These directives emit data into the current section. When any of .byte,
.word, .int, .long, .string, .float, or .field appears inside a
.struct/.endstruct sequence it defines a member's size and does not
initialize memory (see section 7).
| Directive | Syntax | Description |
|---|---|---|
| .byte | .byte value1 [, ... , valuen] |
One or more 8-bit values, each in the low 8 bits of a word |
| .word | .word value1 [, ... , valuen] |
One or more 16-bit values in consecutive words |
| .int | .int value1 [, ... , valuen] |
Identical to .word |
| .long | .long value1 [, ... , valuen] |
One or more 32-bit values, least significant word first |
| .blong | .blong value1 [, ... , valuen] |
Like .long, but the object cannot span a page boundary |
| .float | .float value |
32-bit IEEE single-precision float, least significant word first |
| .bfloat | .bfloat value |
Like .float, but the object cannot span a page boundary |
| .string | .string "string1" [, ... , "stringn"] |
Text packed two 8-bit bytes per word |
| .field | .field value [, size in bits] |
A value packed into a bit field of the current word |
| .space | .space size in bits |
Reserve bits; a label points to the first reserved word |
| .bes | .bes size in bits |
Reserve bits; a label points to the last reserved word |
.byte, .word, .int
.byte treats each value as an 8-bit signed number and gives each its own word;
values are neither packed nor sign-extended, and values wider than 8 bits are
truncated. A character string operand contributes one value per character. Up
to 100 values are allowed, and the whole line (label, directive, and values)
must stay within 200 characters. .word and .int are equivalent and place
16-bit values, which may be absolute or relocatable; a relocatable value gets a
relocation entry so the linker can patch it.
strx .byte 10, -1, "abc", 'a' ; 6 separate byte words
.word 3200, 1+'AB', -0AFh ; 16-bit words
.int 10, symptr, -1 ; relocatable symptr allowed
.long and .blong
Both store 32-bit values across two-word pairs, least significant word first.
.blong additionally guarantees the datum does not straddle a page boundary.
Dat1 .long 0ABCDh, 'A'+100h
.blong Dat1, 0AABBCCDDh
.float and .bfloat
Each stores the IEEE single-precision (32-bit) representation of one
floating-point constant: a 1-bit sign, an 8-bit biased exponent, and a 23-bit
fraction, with the least significant word stored first. .bfloat prevents a
page crossing.
.float -1.0e25
.bfloat 3
.string
.string packs 8-bit characters two per word, most significant byte first, and
pads the final word with a null byte when needed. This is the packing
difference from .byte. Up to 100 operands are allowed on one line; values over
8 bits are truncated.
Str_Ptr .string "ABCD" ; 4142 4344
.string 41h,42h,43h,44h ; same bytes, given numerically
.field
.field packs a value into a field of 1 to 16 bits (16 if size is omitted),
starting at the least significant bit of the current word. Successive fields
share the word; the SPC does not advance until the word fills or a field will
not fit. A relocatable value requires size 16. An over-wide value is truncated
with a warning. Use .even to force the next field into a new word.
.field 0ABCh, 14 ; 14-bit field in word 0
.field 0Ah, 5 ; does not fit, starts word 1
.field 0Ch, 4 ; same word 1
.even ; flush the partial word
.space and .bes
Both reserve size in bits and fill them with zeros, advancing the SPC past
the reserved space. To reserve words, multiply the word count by 16. A label on
.space points to the first reserved word; a label on .bes points to the
last.
Res_1 .space 100 ; label -> first reserved word
Res_2 .bes 20 ; label -> last reserved word
3. Directives that align the section program counter
| Directive | Syntax | Description |
|---|---|---|
| .align | .align |
Align the SPC on the next 128-word (page) boundary |
| .even | .even |
Align the SPC on the next full-word boundary |
.align fills words with NOPs up to the next 128-word boundary so the following
code starts on a page boundary; if the SPC is already aligned it is unchanged.
It also flags the linker to preserve the alignment at load time. .even writes
out a partially filled word (zero-filling the unused bits) so the next .field
starts a fresh word; it has no effect when the SPC is already word-aligned.
Inside a .struct/.endstruct sequence, .even aligns member offsets rather
than initializing memory.
.byte 4
.align ; next code begins on a page boundary
.field 6, 3
.even ; flush the partial field word
4. Directives that format the output listing
| Directive | Syntax | Description |
|---|---|---|
| .drlist | .drlist |
List all directive lines (default) |
| .drnolist | .drnolist |
Suppress listing of selected directive lines |
| .fclist | .fclist |
List false conditional blocks (default) |
| .fcnolist | .fcnolist |
Suppress listing of false conditional blocks |
| .list | .list |
Resume the source listing |
| .nolist | .nolist |
Suppress the source listing |
| .mlist | .mlist |
List macro and .loop/.endloop expansions (default) |
| .mnolist | .mnolist |
Suppress macro and .loop/.endloop expansions |
| .sslist | .sslist |
List substitution-symbol expansions |
| .ssnolist | .ssnolist |
Suppress substitution-symbol expansions (default) |
| .length | .length page length |
Set listing page length (default 60, min 1, max 32767) |
| .width | .width page width |
Set listing page width (default 80, min 80, max 200) |
| .tab | .tab size |
Set the listing tab size (default 8) |
| .title | .title "string" |
Set the per-page listing title |
| .page | .page |
Eject a listing page |
| .option | .option option list |
Select listing options |
.drnolist suppresses the listing of these directives until .drlist: .asg,
.break, .emsg, .eval, .fclist, .fcnolist, .length, .mlist,
.mmsg, .mnolist, .sslist, .ssnolist, .var, .width, and .wmsg.
.list/.nolist nest; each .nolist needs a matching .list, and the line
counter keeps advancing while the listing is off. The .width and .length
directives are themselves never listed. .sslist marks expanded lines with a
leading #. .title accepts up to 65 characters (longer titles are truncated
with a warning); to title the first page the .title must be the first source
statement.
.option takes a comma-separated list of these (case-insensitive) letters:
| Option | Effect |
|---|---|
| B | Limit each .byte directive listing to one line |
| D | Limit each .int and .word directive listing to one line |
| F | Reset the B, D, L, M, and T options |
| L | Limit each .long directive listing to one line |
| M | Turn off macro expansions in the listing |
| T | Limit each .string directive listing to one line |
| X | Produce a symbol cross-reference listing |
.title "FFT routines"
.length 65
.width 85
.option B, D, L, T
5. Directives that reference other files
| Directive | Syntax | Description |
|---|---|---|
| .copy | .copy ["]filename["] |
Assemble another file; its lines are listed |
| .include | .include ["]filename["] |
Assemble another file; its lines are not listed |
| .mlib | .mlib ["]filename["] |
Name an archive library of macro definitions |
| .def | .def symbol1 [, ... , symboln] |
Symbols defined here, usable elsewhere |
| .ref | .ref symbol1 [, ... , symboln] |
Symbols used here, defined elsewhere |
| .global | .global symbol1 [, ... , symboln] |
Acts as .def or .ref as needed |
.copy and .include stop the current file, assemble the named file, then
resume at the following statement. The copied file's lines appear in the
listing; an included file's lines never do. The filename may be quoted, may be
a full path, and otherwise is searched for in the current source directory, in
-i directories, and in the A_DIR environment paths. These directives nest up
to ten levels.
.mlib names an archive whose members are source files, each holding one macro
whose name matches the member's filename (extension .asm). A macro is
extracted only when it is actually called, and only once.
.def enters a locally defined symbol for export; .ref marks a symbol as an
undefined external and always creates a symbol-table entry whether used or not.
.global is a .def for symbols defined in the module and a .ref for those
that are not, and for an undefined symbol it creates an entry only if the module
uses it.
.def Init ; exported
.ref x, y, z ; imported
.global Init, x, y, z ; both roles, as needed
.copy "byte.asm"
.mlib "mac.lib"
6. Conditional assembly directives
| Directive | Syntax | Description |
|---|---|---|
| .if | .if well-defined expression |
Begin a conditional block; assemble if true (nonzero) |
| .elseif | .elseif well-defined expression |
Assemble when .if is false and this is true |
| .else | .else |
Assemble when .if and all .elseif are false |
| .endif | .endif |
End the conditional block |
| .loop | .loop [well-defined expression] |
Begin a repeatable block (default count 1024) |
| .break | .break [well-defined expression] |
Leave the loop when the expression is true or omitted |
| .endloop | .endloop |
End the repeatable block |
.elseif and .else are both optional, and .elseif may appear more than once
in a block. In a .loop, assembly repeats until the loop count is reached or a
.break with a true or omitted expression is met; a .break whose expression
is false lets the loop continue.
.if sym1 <= 10
.byte 10
.elseif sym2 + sym3 = 5
.byte sym2 + sym3
.else
.byte sym1
.endif
.eval 0, x
.loop
.word x*100
.eval x+1, x
.break x = 6
.endloop
7. Assembly-time symbol directives
| Directive | Syntax | Description |
|---|---|---|
| .set | symbol .set value |
Equate a constant value with a symbol |
| .equ | symbol .equ value |
Identical to .set |
| .asg | .asg ["]character string["], substitution symbol |
Assign a redefinable string to a substitution symbol |
| .eval | .eval well-defined expression, substitution symbol |
Evaluate an expression into a substitution symbol |
| .struct | [stag] .struct [expr] |
Begin a structure template |
| .endstruct | .endstruct |
End the structure template |
| .tag | label .tag stag |
Give a label the attributes of structure tag stag |
| .newblock | .newblock |
Undefine local labels |
.set and .equ bind a constant to a label-field symbol that cannot be
redefined; the value's symbols must be defined earlier, a relocatable value
yields a relocatable symbol, and the value appears in the listing but not in the
object code. Such a symbol can be exported with .def or .global.
.asg assigns a character string (redefinable) to a substitution symbol; the
quotation marks are optional and, without them, the assembler reads up to the
first comma and trims blanks. A substitution symbol may be 32 characters, must
begin with a letter, and may otherwise contain letters, digits, underscores, and
dollar signs. .eval evaluates a well-defined expression and assigns the
string form of the result, which makes it useful as a .loop counter.
bval .set 0100h
count .equ 100/2 + 3
.asg "10, 20, 30, 40", coefficients
.byte coefficients
.eval x+1, x
.struct/.endstruct build a C-like template and allocate no memory; member
descriptors (.string, .byte, .word, .float, .field, and .tag) define
member sizes rather than emitting data. An optional stag labels the structure
(without it, members go into the global symbol table with their offsets); an
optional expr sets the starting offset (default 0); an optional trailing label
on .endstruct receives the total size. Only element descriptors, conditional
directives, .align, and .even may appear in the sequence, and empty
structures are illegal. .tag gives a previously defined stag's layout to a
label and allocates no memory.
real_rec .struct ; structure tag
nom .int ; member offset 0
den .int ; member offset 1
real_len .endstruct ; total size 2
.bss real, real_len ; actual allocation
.newblock undefines the local labels (symbols of the form $n, where n is
one decimal digit) so a name can be reused. .text, .data, and .sect also
reset local labels.
$1 nop
.newblock ; $1 may now be defined again
8. Miscellaneous directives
| Directive | Syntax | Description |
|---|---|---|
| .end | .end |
End assembly |
| .label | .label symbol |
Define a loadtime-relocatable label in the current section |
| .mmregs | .mmregs |
Enter memory-mapped register names into the symbol table |
| .sblock | .sblock ["]section name["] [, "section name", ...] |
Mark initialized sections for blocking |
| .version | .version generation #number |
Select the processor generation |
| .port | .port |
Turn on the assembler porting switch |
| .emsg | .emsg string |
Send a user error message |
| .wmsg | .wmsg string |
Send a user warning message |
| .mmsg | .mmsg string |
Send a user assembly-time message |
.end is optional, terminates assembly like an end-of-file, and causes any
following statements to be ignored. It must not be used to end a macro.
.label defines a symbol that refers to the loadtime address of the current
section, for a section that loads at one address and runs at another; ordinary
labels in the section refer to the run address.
.mmregs defines the memory-mapped register names (IMR, GREG, PMST, the AR0 to
AR7 registers, the circular-buffer registers, and the rest) as local absolute
symbols, equivalent to a .set for each one, so they need not be defined by
hand.
.sblock marks initialized sections for blocking, a weaker alignment that keeps
a section from crossing a 128-word page when it is smaller than a page, or
starts it on a page boundary when larger. It applies only to initialized
sections, not .usect or .bss sections; the section names may or may not be
quoted.
.version tells the assembler the target generation and must appear before any
instruction. The reference lists these device numbers: 10 (TMS320C1x), 16
(TMS320C16), 20 (TMS320C20), 25 (TMS320C2x), 29 (TMS320C2xx), and 50
(TMS320C5x); the directives summary gives the default as 25. It is equivalent to
the -v command-line option.
.port turns on the porting switch (equivalent to the -p option) and has no
effect unless the target is a TMS320C2xx or TMS320C5x; the -v option selects
which of those two the code is generated for.
The three message directives write to the standard output device. .emsg
increments the error count and prevents an object file from being produced.
.wmsg increments the warning count but still produces an object file. .mmsg
changes neither count and still produces an object file.
.mmregs
.sblock .text, .data
.version 50
.emsg "ERROR -- MISSING PARAMETER"
.end
How c5xtools handles these
c5xasm accepts the directive grammar above and resolves sections, constants,
alignment, conditional blocks, substitution symbols, and structure templates as
described; listing-format directives are parsed and apply to the listing output.
The byte-exact conformance gate exercises the data-generating directives
(.byte, .word, .int, .long, .string, .float, .field, .space,
.bes) against the TI golden objects, which is why assembled output matches the
reference assembler word for word.
License
MIT - (c) 2026 Grzegorz Worona [email protected]. See LICENSE.