Expressions, operands, and operators
Expressions consist of expression operands and operators.
The assembler accepts a wide range of expressions, including both arithmetic and logical operations. All operators use 64-bit two’s complement integers. Range checking is performed if a value is used for generating code.
Expressions are evaluated from left to right, unless this order is overridden by the priority of operators. See also Assembler operators.
These operands are valid in an expression:
Constants for data or addresses, excluding floating-point constants
Symbols—symbolic names—which can represent either data or addresses, where the latter also is referred to as labels
The program location counter (PLC),
.(period).
The operands are described in greater details on the following pages.
Note
You cannot have two symbols in one expression, or any other complex expression, unless the expression can be resolved at assembly time. If they are not resolved, the assembler generates an error.
Integer constants
The assembler uses 64-bit two’s complement internal arithmetic, so integers have a (signed) range from -263-1 to 263-1.
Constants are written as a sequence of digits with an optional preceding - (minus) sign in front to indicate a negative number.
Commas and decimal points are not permitted.
The following types of number representation are supported:
Integer type | Example |
|---|---|
Binary |
|
Octal |
|
Decimal |
|
Hexadecimal |
|
Note
Both the prefix and the suffix can be written with either uppercase or lowercase letters.
ASCII character constants
ASCII constants can consist of any number of characters enclosed in single or double quotes. Only printable characters and spaces can be used in ASCII strings. If the quote character itself will be accessed, two consecutive quotes must be used:
Format | Value |
|---|---|
|
|
|
|
|
|
|
|
|
|
| Empty string (no value) |
| ' |
|
|
|
|
|
|
Floating-point constants
The IAR Assembler accepts floating-point values as constants and converts them into IEEE half-precision (16-bit), single-precision (32-bit) or double-precision (64-bit) floating-point format, or fractional format.
Floating-point numbers can be written in the format:
[+|-][digits].[digits][{E|e}[+|-]digits]
This table shows valid examples:
Format | Value |
|---|---|
| 1.023 x 101 |
| 1.23456 x 10-24 |
| 1.0 x 103 |
Spaces and tabs are not allowed in floating-point constants.
Note
Floating-point constants do not give meaningful results when used in expressions.
True and false
In expressions, a zero value is considered false, and a non-zero value is considered true.
Conditional expressions return the value 0 for false and 1 for true.
Symbols
User-defined symbols can be up to 32,000 characters long, and all characters are significant. Depending on what kind of operation a symbol is followed by, the symbol is either a data symbol or an address symbol where the latter is referred to as a label. A symbol before an instruction is a label and a symbol before, for example the EQU directive, is a data symbol. A symbol can be:
absolute—its value is known by the assembler
relocatable—its value is resolved at link time.
Symbols must begin with a letter, a–z or A–Z, ? (question mark), or _ (underscore). Symbols can include the digits 0–9 and $ (dollar).
Symbols may contain any printable characters if they are quoted with ` (backquote), for example:
`strange#label`Case is insignificant for built-in symbols like instructions, registers, operators, and directives. For user-defined symbols, case is by default significant but can be turned on and off using the Case sensitive user symbols (-s) assembler option. For more information, see -s.
Use the symbol control directives to control how symbols are shared between modules. For example, use the PUBLIC directive to make one or more symbols available to other modules. The EXTERN directive is used for importing an untyped external symbol.
Note that symbols and labels are byte addresses. See also Data definition or allocation directives.
Labels
Symbols used for memory locations are referred to as labels.
Program location counter (PLC)
The assembler keeps track of the start address of the current instruction. This is called the program location counter.
To refer to the program location counter in your assembler source code, use the . (period) character. For example:
section MYCODE:CODE(2)
arm
b . ; Loop forever
endRegister symbols
This table shows the predefined register symbols available in 32-bit mode:
Name | Size | Description |
|---|---|---|
| 32 bits | Current program status register |
| 64 bits | Floating-point coprocessor registers for double precision |
| 32 bits | Floating-point context payload |
| 32 bits | Floating-point coprocessor, exception register |
| 32 bits | Floating-point coprocessor, status and control register |
| 32 bits | Floating-point coprocessor, system ID register |
| 128 bits | Advanced |
| 32 bits | General purpose registers |
| 32 bits | Stack pointer |
| 32 bits | Link register |
| 32 bits | Program counter |
| 32 bits | Floating-point coprocessor registers for single precision |
| 32 bits | Saved program status register |
In addition, specific cores might allow you to use other registers, for example APSR for the Cortex-M3, if available in the instruction syntax.
This table shows the predefined register symbols available in 64-bit mode:
Name | Size | Description |
|---|---|---|
| 64 bits | 64 bits in 64-bits general purpose registers |
| 32 bits | 32 bits in 64-bits general purpose registers |
| 64 bits | Stack pointer |
| 32 bits | Stack pointer |
| 128 bits | 128-bit SIMD and floating-point registers |
| 128 bits | 128-bit entity in 128-bit SIMD and floating-point registers |
| 64 bits | Double-precision floating-point in 128-bit SIMD and floating-point registers |
| 32 bits | Single-precision floating-point in 128-bit SIMD and floating-point registers |
| 16 bits | Half-precision floating-point in 128-bit SIMD and floating-point registers |
| 8 bits | 8-bit entity in 128-bit SIMD and floating-point registers |
| 64 bits | First intra-procedure-call scratch register, alias to |
| 64 bits | Second intra-procedure-call scratch register, alias to |
| 64 bits | Frame pointer, alias to |
| 64 bits | Link register, alias to |
| 64 bits | Zero 64-bit register |
| 32 bits | Zero 32-bit register |
Predefined symbols
These predefined symbols are available:
Symbol | Value |
|---|---|
This symbol is defined to | |
This symbol is defined according to the Arm C Language Extensions (ACLE). | |
This symbol is defined according to the Arm C Language Extensions (ACLE). | |
An integer that is set based on the | |
This symbol is defined according to the Arm C Language Extensions (ACLE). | |
This symbol is defined according to the Arm C Language Extensions (ACLE). | |
This symbol is defined according to the Arm C Language Extensions (ACLE). | |
This symbol is defined according to the Arm C Language Extensions (ACLE). | |
This symbol is defined according to the Arm C Language Extensions (ACLE). | |
This symbol is defined according to the Arm C Language Extensions (ACLE). | |
This symbol is defined according to the Arm C Language Extensions (ACLE). | |
This symbol is defined according to the Arm C Language Extensions (ACLE). | |
An integer that is set based on the assembler option The symbol is set to The symbol is undefined for cores without CMSE. | |
This symbol is defined to This symbol is defined according to the Arm C Language Extensions (ACLE). | |
This symbol is defined to This symbol is defined according to the Arm C Language Extensions (ACLE). | |
This symbol is defined to This symbol is defined according to the Arm C Language Extensions (ACLE). | |
This symbol is defined according to the Arm C Language Extensions (ACLE). | |
This symbol is defined to This symbol is defined according to the Arm C Language Extensions (ACLE). | |
This symbol is defined according to the Arm C Language Extensions (ACLE). | |
This symbol is defined according to the Arm C Language Extensions (ACLE). | |
This symbol is defined to This symbol is defined according to the Arm C Language Extensions (ACLE). | |
This symbol is defined according to the Arm C Language Extensions (ACLE). | |
This symbol is defined according to the Arm C Language Extensions (ACLE). | |
This symbol is defined according to the Arm C Language Extensions (ACLE). | |
This symbol is defined according to the Arm C Language Extensions (ACLE). | |
This symbol is defined according to the Arm C Language Extensions (ACLE). | |
This symbol is defined according to the Arm C Language Extensions (ACLE). | |
This symbol is defined according to the Arm C Language Extensions (ACLE). | |
This symbol is defined according to the Arm C Language Extensions (ACLE). | |
This symbol is defined according to the Arm C Language Extensions (ACLE). | |
This symbol is defined according to the Arm C Language Extensions (ACLE). | |
An integer that is set based on the | |
An integer that is set based on the | |
This symbol is defined according to the Arm C Language Extensions (ACLE). | |
This symbol is defined according to the Arm C Language Extensions (ACLE). | |
An integer that is set based on the | |
An integer that is set based on the | |
An integer that is set based on the assembler option | |
An integer that is set based on the assembler option | |
An integer that is set based on the assembler option | |
A unique integer that identifies the build number of the assembler currently in use. The build number does not necessarily increase with an assembler that is released later. | |
An integer that identifies the chip core in use. The value reflects the setting of the assembler option | |
The current date in | |
The name of the current source file (string). | |
IAR assembler identifier (number). Note that the number could be higher in a future version of the product. This symbol can be tested with | |
An integer that is set to | |
This symbol is defined to | |
The current source line number (number). | |
Identifies the byte order in use. Expands to the number 1 when the code is compiled with the little-endian byte order, and to the number 0 when big-endian code is generated. Little-endian is the default. | |
This symbol is defined to | |
Target identity, consisting of two bytes (number). The high byte is the target identity, which is 0x4F (=decimal 79) for the IAR Assembler for Arm. | |
The current time in | |
The version number in integer format, for example, version 6.21.2 is returned as 6021002 (number). |
Including symbol values in code
Several data definition directives make it possible to include a symbol value in the code. These directives define values or reserve memory. To include a symbol value in the code, use the symbol in the appropriate data definition directive.
For example, to include the time of assembly as a string for the program to display:
name timeOfAssembly
extern printStr
section MYCODE:CODE(2)
adr r0,time ; Load address of time
; string in R0.
bl printStr ; Call string output routine.
bx lr ; Return
data ; In data mode:
time dc8 __TIME__ ; String representing the
; time of assembly.
endTesting symbols for conditional assembly
To test a symbol at assembly time, use one of the conditional assembly directives. These directives let you control the assembly process at assembly time.
For example, if you want to assemble separate code sections depending on whether you are using an old assembler version or a new assembler version, do as follows:
#if (__VER__ > 6021000) ; New assembler version
;…
;…
#else ; Old assembler version
;…
;…
#endifFor more information, see Conditional assembly directives.
Absolute and relocatable expressions
Depending on what operands an expression consists of, the expression is either absolute or relocatable. Absolute expressions are those expressions that only contain absolute symbols or relocatable symbols that cancel each other out.
Expressions that include symbols in relocatable sections cannot be resolved at assembly time, because they depend on the location of sections. These are referred to as relocatable expressions.
Such expressions are evaluated and resolved at link time, by the linker. They can only be built up out of a maximum of one symbol reference and an offset after the assembler has reduced it.
For example, a program could define absolute and relocatable expressions as follows:
name simpleExpressions
section MYCONST:CONST(2)
first dc32 5 ; A relocatable label.
second equ 10 + 5 ; An absolute expression.
dc32 first ; Examples of some legal
dc32 first + 1 ; relocatable expressions.
dc32 first + second
endNote
At assembly time, there is no range check. The range check occurs at link time and, if the values are too large, there is a linker error.