# Inline assembler

This chapter contains a very brief description of the inline x86 assembler.

- Implemented features
- Basic syntax
- Labels
- Accessing Modula-2/Oberon-2 objects
- Known problems
- Potential problems

## Implemented features

The following features are implemented in the current version:

- Base instruction set up to and including Pentium Pro (see Known problems).
- Floating point instructions up to and including Pentium Pro.
- Pentium MMX instructions.
- Labels and their usage in branch and call instructions.
- Modula-2/Oberon-2 procedure calls and variable access (see Accessing Modula-2/Oberon-2 objects).

## Basic syntax

The assembler uses the same scanner as the Modula-2/Oberon-2 front-end, so it is possible to use conditional compilation and comments.

Language extensions have to be enabled using the M2EXTENSIONS and O2EXTENSIONS options in order to use inline assembly facilities.

The keyword `ASM` denotes the beginning of inline assembly code; the keyword `END` denotes its end.

Each line in a piece of the assembly code may contain not more than one instruction. It is not possible to continue an instruction on the next string.

Keywords and names of instructions and registers are not case sensitive.

There are instructions one of which arguments is fixed (`DIV`, `FCOMI`). These instructions are differently denoted in different assemblers. We use the syntax described in Intel's documentation.

If size or an operand may not be determined based on instruction semantics and/or size of another operand, it is necessary to explicitly specify it. The following size specifiers are recognized:

Specifier | Size
`BYTE PTR` | 1
`WORD PTR` | 2
`DWORD PTR` | 4
`FWORD PTR` | 6
`QWORD PTR` | 8
`TBYTE PTR` | 10

Examples:

`MOV WORD PTR [EBX],1` here size specifier is obligatory

`MOV [EBX],AX` here size is determined automatically

## Labels

An instruction may be prepended with a label, delimited with a colon character:

`Save: PUSH EAX`

Labels may not match instruction names. It is also not recommended to use assembly keywords (`DWORD`, `EAX`) as labels.

In the current version, labels may only be used in branch and call instructions.

## Accessing Modula-2/Oberon-2 objects

It is possible to reference Modula-2/Oberon-2 entities from within the inline assembly code, namely whole constants, variables, and procedures (in `JMP` and `CALL` instructions only).

Example:

`MOV j,10`

In this example, the type of `j` is used to choose between byte, word, and doubleword `MOV` instructions.

Note: In the first pre-release versions which included inline assembler, it was necessary to specify the base register `EBP` to access local variables:

`MOV j[EBP],10`

It is no longer required.

In case of nested procedures, code to access a variable from an outer procedure scope has to be written by hand.

Record field access is not supported yet. There are also no operators to denote attributes of Modula-2/Oberon-2 entities.

The `OFFSET` operator returns the offset of its operand, which has to be a variable:

`MOV EAX, OFFSET j`

## Known problems

1. Instruction prefixes (`REP`, `LOCK`, etc.) are not supported yet.
2. Segment overriding (`DS:`, etc.) is not supported yet.
3. Error position precision is +/- 1-2 tokens.
4. Error 3029 incorrectly positioned.
5. 16-bit addressing modes (e.g. `[BX+SI]`) are not supported and unlikely to be supported in the future.
6. Modula-2/Oberon-2 entities access facilities are limited.
7. It is possible to use commands like `MOVSB`, `MOVSW`, `MOVSD`, but not as in `MOVS DWORD PTR [ESI]`.
8. Modula-2/Oberon-2 variables usage is poorly checked for correctness.
9. It is possible to use only one `OFFSET` operator in a constant expression.

## Potential problems

1. Not all instructions were tested with all addressing modes.
2. Error diagnostics and recovery were not tested.