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.