Super Prev Next

Inline assembler

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

Super Prev Next

Implemented features

The following features are implemented in the current version:

Super Prev Next

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


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

    MOV [EBX],AX           here size is determined automatically

Super Prev Next


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.

Super Prev Next

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).


    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:


Super Prev Next

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.

Super Prev Next

Potential problems

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