Assembler statement syntax

Each ASM statement or assembler procedure contains a list ofassembler statements.  The assembler statements must be separated by semicolonsor by end-of-lines.

The syntax of an assembler statement is:

[label:] [OpCode [OpExpr {,OpExpr }]]

where:
label is a label definition.
OpCode is an instruction mnemonic or assembler directive.
OpExpr is an operand expression.  

The destination of an instruction operation, where applicable,is the first (leftmost) operand.

These elements are discussed in the sections that follow.

The documentation for the compiler built-in assembler assumesyou are familiar with assembly code and have written some assembly code before. Examplesof assembly source code can be found in the language RTL. Simply search the RTL sourcesfor 'Assembler' and/or 'PureAsm' to find examples.  The "system" modulesare a good start.

Labels

A label can precede any assembler statement.  Labels areoptional.  

The label defines the current location in the code, and can beused as the destination of jump and call instructions.

Local labels are the only type of label supported by the compiler. Local labels are defined as follows:

Local labels start with @ and consist of letters and digits.

Local labels are known only inside the ASM statement that containsthem.  You can, therefore, redefine local labels within different ASM statementsin the same procedure.

Opcodes

The Opcode portion of an assembler statement is either an instructionmnemonic or an assembler directive.

Instruction mnemonics

Instruction mnemonics identify a specific machine instruction. The inline assembler uses a mostly generic RISC instruction set. This can bedone because most RISC architectures are more similar than different. This have takenthis approach because it allows for greater portability.

Assembler directives

If you are familiar with assemblers, you are probably used tousing a large number of assembler directives in your assembly code.  Most ofthese directives have to do with defining constants and variables.

In Modula-2 and Ada95, many of the directives are not needed,since the same effect can be achieved through Modula-2 and Ada95 declarations.

The only directives supported by the inline assembler are theDB, DW, and DD directives, which allow you to specify bytes, words, and longwordsof constant data.

Each of these directives takes a variable number of operands,separated by commas.  Each operand is an expression, which defines a byte, word,or longword of memory, depending on which directive you use.

Examples:

DB 1, 2, 3
DW OFFSET X
DB "Device is not installed",13,10

In the last example, a string literal is used.  Each characterin the string literal defines a byte in memory.

Operand expressions

Many instructions require one or more operand expressions.  Youconstruct these expressions from:

Operand expressions have three attributes that determine howthey can be used in expressions and as operands of instructions.  These attributesare:

The next sections discuss first the three operand expressionattributes, and then the operands and operators from which you construct operandexpressions.

Operand classes

Operand expressions can be divided into four classes: immediate,register, memory, and label.  Each instruction requires a specific combinationof operand classes for its operands.

Immediate class operands

Immediate operands are integer constants.  Their meaningis their own constant value.

Examples:

set    r1, 10

The constant 10 is moved to the r1 register.

You can also use names declared in integer constant declarationsas immediate operands.

Register class operands

Register operands refer to the processor registers.  Youuse the register name to specify a register operand.

Examples:

add    r2, r1, 3
mov r8, r1

Memory class operands

Memory operands refer to memory locations as data.  Youuse the square brackets [ ] to specify a memory reference.

Examples:

ld32u    r1, [r4]

ld32u r1, [r4+r5]

ld32u r1, [r4+24]

You also can use Modula-2 and Ada95 variables as memory references. To simplify access to these variables further generic load "ld" andstore "st" mnemonic opcodes are defined. The inline assembler automaticallyuses the correct instruction mnemonic to access the variable.

ld r1, MyVariable

Label class operands

Label operands refer to locations in code, and are the destinationsof jump and call instructions.

Example:

be    @zero

This jumps to the location specified by local label @zero, ifthe previous comparison was equal.

Relocatability

Nonregister operand expressions can be further classified asAbsolute or Relocatable.  

An immediate class expression is:

A memory reference expression is:

absolute if it is constructed entirely from constants, localvariables, parameters, and index registers.  In this case, the offset portionof the address is known at compile time, even if the actual address is not.  

relocatable if it involves global variables, external variables,or labels, since their offsets are not known until link time.

Operand types

Each operand or expression also has a type associated with it. The type of an operand depends on its class:

For Modula-2 and Ada95 variables, the operand type is determinedby the type of the variable.

Operands

An expression consists of operands, which refer to a specificconstant or memory location, and operators, which allow you to combine operands intoexpressions.  

Expressions are evaluated by the inline assembler using longintarithmetic.  Real and string expressions are not supported.

The next 10 sections discuss each type of operand you can usein expressions.  Following the types of operands is discussion of the operatorsand types of operators.

Constant as operands

You can use decimal and hexadecimal constants using the Modula-2syntax.  In assembler instructions you can also use binary, octal, and hexadecimalconstants by following the number with the letter:

b for binary constants
o for octal constants
h for hexadecimal constants

Examples:

12 0FFH 10110100B 77o 3Eh

Constants are immediate class operands.

Strings as operands

You can use a quoted string of up to four characters in expressionsexactly as if the string were a numeric constant.  The characters of the stringare placed in a longint, with the leftmost character being the least significant. If you specify fewer than four characters, the number is padded with zerosto fill the longint.

Examples:

"A"    = 00000041h
"1234"    = 34333231h

Strings are immediate class operands.

Variables and typed constants as operands

You can use variables and typed constants from your program asoperands.  If a variable or typed constant is a record or object type, use afield selector to refer to a field of the record or object.

Examples:

X Location.column

Variables and typed constants are memory class operands.

Modula-2 VAR parameters and Ada95 out and in out parameters asoperands

These parameters, when used as an assembly language operand,refer to the address of the actual parameter, rather than to the actual parameteritself.  To refer to the actual parameter, you must load the address into registersand use an indirect reference, as follows:

Example:

ld    r1, Result

st32 [r1], 0

Var parameters are memory class operands.

Registers as operands

Integer registers are specified by 'r' followed by the registernumber:

r0, r1, etc...

Floating point registers are specified by 'f' followed by theregister number:

f1, f2, etc...

Register sp is a name alias for the stack pointer register, whichvaries by architecture.

Register fp is a name alias for the stack frame pointer register,which varies by architecture.

Registers are register class operands.

SPARC architecture specifics

Labels as operands

Label operands are local labels defined in the current ASM statement.

Labels can be used as the destination for jump and call instructionsonly, or as the operands of an OFFSET or SEG operator.

Examples:

jmp    @Next            {Locallabel}

ld32u r1, OFFSET @Next {Local label}

Labels are label class operands.

Procedures as operands

You can use Modula-2 and Ada95 procedures as label class operands. Procedures are simply referred to by name.

Procedures are treated as label class operands.

Field offsets as operands

You can refer to the offset of a field within a record or objecttype by using the following syntax:

TypeName.FieldName

where:
TypeName is the name of a record or object type.
FieldName is the name of a field.  

The resultant operand is the offset of the field from the startof the record or object.  

Field offsets are immediate class operands.

Example:

ld32u    r1, [r4].MyRecord.Field

Function results as operands

When you use the inline assembler in a function procedure, youcan refer to the function's return value by using the symbol @result.  You cannotuse this form of operand in assembler or pureasm functions, since the compiler doesnot allocate the function result variable in this case.  Additionally, the @resultmay only be used for structured return types.

Example:

st    @result, r1

@result is a memory class operand.