Skip to content

Assembler Syntax

kombos edited this page Oct 6, 2026 · 1 revision

Assembler Source Syntax

Normative source: SPRU018D, chapter 3 (sections 3.6 through 3.13). This page describes the syntax of an assembler source statement, the constant and symbol forms the assembler accepts, how expressions are evaluated, what the source and cross-reference listings contain, and the enhanced instruction forms.

A source program is a sequence of source statements. A statement may hold an assembler directive, a machine instruction, a macro directive, or a comment. The assembler reads up to 200 characters of each line; a longer line is truncated and a warning is issued.


1. Source statement format

A source statement is made of four ordered fields. Only the position of the first field is fixed; the rest are separated by whitespace. The general form:

  [label][:]   mnemonic   [operand list]   [;comment]

Column and whitespace rules:

  • Every statement must start with one of: a label, a blank, an asterisk, or a semicolon.
  • A label, when present, must start in column 1.
  • At least one blank separates each field. A tab counts as a blank.
  • A comment is optional. In column 1 it may open with an asterisk or a semicolon; anywhere past column 1 it must open with a semicolon.

The four fields of a line:

  col 1
  |
  v
 +----------+---+-----------+----------------+--------------------+
 | label    | : | mnemonic  | operand list   | ;comment           |
 +----------+---+-----------+----------------+--------------------+
  starts in     must NOT    opcode,          optional, runs to
  column 1,     start in    directive,       end of line; begins
  colon         column 1    macro call or    with ; (or * only
  optional      (else read  macro directive; in column 1)
                as a label) operands are
                            comma-separated

Example statements:

  SYM1      .set   2       ; Symbol SYM1 = 2
  Begin:    LDPK   SYM1    ; Load DP with 2
            .word  016h    ; Initialize a word with 016h

1.1 Label field

A label is optional for every machine instruction and for most (not all) directives. When used it begins in column 1 and holds up to 32 alphanumeric characters from A-Z, a-z, 0-9, underscore, and dollar sign. Labels are case sensitive and the first character may not be a digit. An optional trailing colon is allowed and is not part of the name. When there is no label, column 1 must hold a blank, a semicolon, or an asterisk.

A label takes the current value of the section program counter (SPC), so it points to the statement it sits on. A label alone on a line is a valid statement; it assigns the current SPC and so points to the instruction on the following line (the SPC is not advanced). This is equivalent to:

  label  .set  $     ; $ is the current value of the SPC

1.2 Mnemonic field

The mnemonic follows the label and must not begin in column 1 (if it does, it is read as a label). It may be a machine instruction (such as ABS, MPYU, SPH), an assembler directive (such as .data, .list, .set), a macro directive (such as .macro, .var, .mexit), or a macro call.

1.3 Operand field

The operands follow the mnemonic. An operand may be a constant, a symbol, or an expression built from constants and symbols. Operands are separated by commas.

1.4 Comment field

A comment may start in any column and runs to the end of the line. It may hold any ASCII character, blanks included. Comments appear in the listing but have no effect on assembly. A line that is only a comment is valid; in column 1 it opens with a semicolon or an asterisk, elsewhere with a semicolon only. An asterisk is a comment marker only in column 1.


2. Constants

The assembler accepts six kinds of constant. Each is held internally as a 32-bit quantity and is not sign-extended, so 0FFH equals 00FF hex (255), not -1.

Type Form Limits Notes
Binary up to 16 binary digits then B or b right-justified, zero-filled if short digits 0 and 1
Octal up to 6 octal digits then Q or q digits 0 through 7
Decimal string of decimal digits -32,768 to 65,535
Hexadecimal up to 4 hex digits then H or h right-justified if short must begin with a digit 0-9; digits 0-9, A-F, a-f
Character one or two characters in single quotes held as 8-bit ASCII see section 2.1
Assembly-time a symbol given an absolute value by .set see section 2.2

Worked examples:

Written Decimal Hexadecimal Kind
00000000B 0 0 binary
0100000b 32 20 binary
01b 1 1 binary
11111000B 248 0F8 binary
10Q 8 8 octal
100000Q 32,768 8,000 octal
226q 150 96 octal
1000 1000 3E8 decimal
-32768 -32,768 8,000 decimal
25 25 19 decimal
78h 120 0078 hexadecimal
0FH 15 000F hexadecimal
37ACh 14,252 37AC hexadecimal

2.1 Character constants

A character constant is one or two characters in single quotes, held as 8-bit ASCII. Each single quote that is part of the constant is written as two consecutive single quotes. A constant of two single quotes alone is valid and has the value 0. A single character is right-justified.

Written Meaning Internal value
'a' the character a 61 hex
'C' the character C 43 hex
'''' one single quote 27 hex
'' a null character 00 hex

A character constant is a single integer value; a character string (section 3) is a list of characters.

2.2 Assembly-time constants

A symbol given a value by .set becomes a constant. To use it in an expression the assigned value must be absolute:

  shift3  .set 3
          LAC  *,shift3,AR1

.set may also give a symbol a register name, making the symbol a synonym for the register:

  AuxR1   .set AR1
          LAC  *,0,AuxR1

3. Character strings

A character string is a run of characters in double quotes, held as 8-bit ASCII. A double quote that belongs to the string is written as two consecutive double quotes. The maximum length depends on the directive that uses the string.

Written Resulting string Length
"sample program" sample program 14
"PLAN ""C""" PLAN "C" 8

Character strings appear as filenames (for example .copy "filename"), section names (.sect "section name"), data for .byte "charstring", and the operand of .string.


4. Symbols

A symbol serves as a label, a constant, or a substitution symbol. The name is up to 32 alphanumeric characters from A-Z, a-z, 0-9, dollar sign, and underscore. The first character may not be a digit and the name may not hold embedded blanks. Symbols are case sensitive (ABC, Abc, and abc are three symbols) unless the -c option overrides this. A symbol is known only during the assembly that defines it unless .global declares it external.

4.1 Labels

A symbol used as a label becomes a symbolic address tied to a program location. Labels used locally within a file must be unique. Mnemonic opcodes and directive names without the leading dot are valid label names. Labels may be operands of .global, .ref, .def, or .bss.

4.2 Symbolic constants

Symbols may be set to constant values with .set or with the .struct/.tag/.endstruct directives, letting a meaningful name stand for a value. Symbolic constants cannot be redefined. The -d assembler option (dspa -dname=[value]) also equates a value with a symbol; if the value is omitted the symbol is set to 1. Source can test such a symbol:

Test Directive usage
Exists .if $isdefed("name")
Does not exist .if $isdefed("name") = 0
Equal to a value .if name = value
Not equal to a value .if name != value

The argument to $isdefed must be quoted so it is taken literally rather than as a substitution symbol.

4.3 Predefined symbols

The assembler predefines several symbols:

  • $ stands for the current value of the section program counter (SPC).
  • Register symbols: AR0-AR1 on the 'C1x, AR0-AR7 on the 'C2x/C2xx/5x.
  • Port address symbols: PA0-PA7 on the 'C1x, PA0-PA15 on the 'C2x/C2xx/5x.
  • Version symbols that steer code generation for a target processor, used with the version switch or the .version directive.
  • Symbols brought in by the .mmregs directive.

Version symbols:

Version symbol -Version option .version directive
.TMS32010 -v10 10
.TMS32016 -v16 16
.TMS32020 -v20 20
.TMS32025 -v25 25
.TMS3202XX -v2xx 29
.TMS32050 -v50 50
.TMS320XX processor version

.TMS320XX holds the value of the version switch; invoking dspa -v20 filename makes .TMS320XX equal 20, so .TMS32020 is true (1) and the other version symbols are false (0).

Register symbol values differ by device. On 'C1x/C2x/C2xx the values are AR0 = 0, AR1 = 1, and so on. On 'C5x they equal the memory-mapped addresses, so the assembler reads the symbol by context: in ADD *+, AR7 the AR7 means 7, while in ADD AR7 it is the address of AR7, which is 17.

4.4 Substitution symbols

A symbol may be assigned a string value, aliasing a character string to a name. When the assembler meets a substitution symbol it replaces the name with the string. Unlike symbolic constants, substitution symbols can be redefined. They are assigned with .asg anywhere in the program; macro parameters are substitution symbols that receive the macro arguments.

  .asg "ar0", SP     ; stack pointer
  .asg "*+",  INC    ; indirect auto-increment
  ADD  label, INC, SP

4.5 Local labels

A local label has the form $n, where n is a decimal digit 0-9 (for example $4, $1). Unlike a normal label it may be undefined and defined again. A local label is reset in any of four ways:

  • the .newblock directive,
  • changing sections with .sect, .text, or .data,
  • entering an include file (.include or .copy),
  • leaving an include file (.include or .copy).

Up to ten local labels may be in effect at once. After one is undefined it may be defined and used again. Local labels do not appear in the object code symbol table, which makes them useful inside macros that are called more than once: with a local label plus .newblock, the label is reset each expansion instead of raising a multiple-definition error.

  Label1:  lac a
           sub b
           blz $1
           lac b
           b   $2
  $1       lac a
  $2       add c
           .newblock   ; undefine $1 so it can be reused
           blez $1
           sacl c
  $1       nop

5. Expressions

An expression is a constant, a symbol, or constants and symbols joined by arithmetic operators. Valid expression values range from -32,768 to 32,767. Three factors set the order of evaluation:

  • Parentheses are always evaluated first; 8/(4/2) is 4 while 8/4/2 is 1. Braces and brackets may not stand in for parentheses.
  • Precedence groups: when parentheses do not decide the order, the highest-precedence operator runs first; 8 + 4/2 is 10.
  • Left-to-right: when neither parentheses nor precedence decide, evaluation runs left to right, except group 1, which runs right to left; 8/4*2 is 4 while 8/(4*2) is 1.

5.1 Operator precedence

Operators fall into four precedence groups, group 1 highest:

Group Operator Description Evaluation
1 + unary plus right to left
1 - unary minus right to left
1 ~ ones complement right to left
2 * multiplication left to right
2 / division left to right
2 % modulo left to right
2 << left shift left to right
2 >> right shift left to right
3 + addition left to right
3 - subtraction left to right
3 ^ bitwise exclusive-OR left to right
3 | bitwise OR left to right
3 & bitwise AND left to right
4 < less than left to right
4 > greater than left to right
4 <= less than or equal to left to right
4 >= greater than or equal to left to right
4 = or == equal to left to right
4 != not equal to left to right

5.2 Overflow and conditional expressions

The assembler checks arithmetic for overflow and underflow at assembly time and issues a Value Truncated warning when either happens; it does not check multiplication. The group-4 relational operators are especially useful in conditional assembly. A conditional expression yields 1 if true and 0 if false, and may compare only operands of equivalent types (absolute with absolute, not absolute with relocatable).

5.3 Well-defined expressions

Some directives require a well-defined expression: one built only from symbols or assembly-time constants that are already defined where the expression appears, and whose evaluation is absolute. For example 1000h+X is well defined when X was previously defined as an absolute symbol.

5.4 Relocatable symbols and legal expressions

An expression may not multiply or divide by a relocatable or external symbol, and may not hold unresolved symbols that are relocatable with respect to other sections. Symbols or registers made global with .global are called external here. Relocatable registers may appear in expressions; their addresses are relocatable with respect to the register section that defined them unless declared external.

The result type of addition and subtraction:

A is B is A + B is A - B is
absolute absolute absolute absolute
absolute external external illegal
absolute relocatable relocatable illegal
relocatable absolute relocatable relocatable
relocatable relocatable illegal absolute (same section only)
relocatable external illegal illegal
external absolute external external
external relocatable illegal illegal
external external illegal illegal

Subtracting one relocatable from another is absolute only when both are in the same section.

Every legal expression reduces to either relocatable symbol +/- absolute symbol or an absolute value. Unary operators apply only to absolute values, never to relocatable symbols, and an expression that cannot be reduced to a single relocatable symbol is illegal. Examples (extern_1 external, intern_1 and intern_2 relocatable in the same section, LAB1 = 2 absolute):

  LACK LAB1 + ((4+3) * 7)       ; ACC = 51
  LACK LAB1 + 4 + (3*7)         ; ACC = 27
  LACK extern_1 - 10            ; legal
  LACK 10 - extern_1            ; illegal, cannot negate a relocatable
  LACK -(intern_1)              ; illegal, cannot negate a relocatable
  LACK extern_1/10              ; illegal, / is not additive
  LACK intern_1 + extern_1      ; illegal, two relocatables
  LACK intern_1 - intern_2 + extern_1   ; legal
  LACK intern_1 + intern_2 + extern_1   ; illegal
  LACK intern_1 + extern_1 - intern_2   ; illegal (left to right adds two relocatables first)

6. Source listings

Invoking the assembler with -l (lowercase L) produces a source listing that pairs each source statement with the object code it generates. Each page opens with two banner lines, a blank line, and a title line that carries any .title text and a page number. A source statement that produces several words of object code lists the extra SPC and object-code words on their own following lines. A listing line has four fields:

Field Contents
1 Source statement number decimal line number; the assembler may also prefix an include-file letter and a macro/loop nesting-level number. Some statements advance the counter without being listed, so a gap in the numbers counts the unlisted statements.
2 Section program counter hexadecimal SPC. Each section (.text, .data, .bss, named sections) keeps its own SPC. Directives that do not touch the SPC leave this blank.
3 Object code hexadecimal object code, with a trailing relocation-type character (see below).
4 Source statement the source characters as scanned, up to 200; spacing follows the source.

Relocation-type characters appended to field 3:

Character Relocation
! undefined external reference
' .text relocatable
" .data relocatable
+ .sect relocatable
- .bss or .usect relocatable
^ .asect relocatable

7. Cross-reference listings

Invoking with -x (or the .option directive) appends a cross-reference listing to the source listing. It shows each symbol and its definition:

Column Contents
Label every symbol defined or referenced during assembly
Value a 4-digit hexadecimal value, or a name describing the symbol's attributes, optionally followed by an attribute character
DEFN the statement number that defines the symbol; blank if undefined
REF line numbers of statements that reference the symbol; blank if never used

Symbol attribute characters and names in the Value column:

Character or name Meaning
REF external reference (.global symbol)
UNDF undefined
' defined in a .text section
" defined in a .data section
+ defined in a .sect section
- defined in a .bss or .usect section

8. Enhanced instruction forms

An enhanced instruction is a single mnemonic that stands in for several similar base instructions; these are valid on the 'C2x, 'C2xx, and 'C5x. The assembler reads the operands and picks the correct opcode. For example:

Enhanced instruction Base instruction
ADD x ADD x
ADD *+ ADD *+
ADD #100 ADDK 100
ADD #3000 ADLK 3000
ADD *+,16 ADDH *+

License

MIT - (c) 2026 Grzegorz Worona grzegorz@worona.pl. See LICENSE.

c5xtools wiki

Start here

The TMS320C5x processor

Writing assembly

The instruction set

A: ABS ADCB ADD ADDB ADDC ADDH ADDI ADDK ADDS ADDT ADLK ADRK AND ANDB ANDI ANDK APAC APL APLI APLK

B: B BACC BACCD BANZ BANZD BBNZ BBZ BC BCND BCNDD BD BDDD BDSD BGEZ BGZ BIOZ BIT BITT BKDK BLDD BLDP BLEZ BLKD BLKP BLPD BLZ BNC BNV BNZ BPSD BSAR BV BZ

C: CALA CALAD CALL CALLD CC CCD CLRC CMPL CMPR CNFD CNFP CONF CPL CPLI CPLK CRGT CRLT

D: DINT DMOV

E: EHWBS EHWBT EINT EMPSD EMRET ESTOP ESTPD ETRAP EXAR

F: FORT

I: IDLE IDLE1 IDLE2 IN INTR

L: LAC LACB LACC LACI LACK LACL LACT LALK LAMM LAR LARK LARP LDP LDPI LDPK LMMR LPH LRLK LST LST0 LST1 LT LTA LTD LTP LTS

M: MAC MACD MADD MADS MAR MPY MPYA MPYI MPYK MPYS MPYU MRKL

N: NEG NMI NOP NORM

O: OPL OPLI OPLK OR ORB ORI ORK OUT

P: PAC POP POPD PSHD PUSH

R: RC RET RETC RETCD RETD RETE RETI RFSM RHM ROL ROLB ROR RORB ROVM RPT RPTB RPTI RPTK RPTR RPTZ RSXM RTC RTXM RXF

S: SACB SACH SACL SAMM SAR SATH SATL SBB SBBB SBLK SBRK SC SETC SFL SFLB SFR SFRB SFSM SHM SMMR SOVM SPAC SPH SPL SPLK SPM SQRA SQRS SST SST0 SST1 SSXM STC STXM SUB SUBB SUBC SUBH SUBI SUBK SUBS SUBT SWI SXF

T: TBLR TBLW TRAP TRAPD

X: XC XOR XORB XORI XORK XPL XPLI XPLK

Z: ZAC ZALH ZALR ZALS ZAP ZPR

Building a program

The tools

Normative sources: TI SPRU056D and SPRU018D (see References).

Changelog


License: MIT - (c) 2026 Grzegorz Worona.

Clone this wiki locally