This chapter contains a very brief description of the inline x86 assembler.
The following features are implemented in the current version:
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
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.
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