Free Pascal supports Intel syntax for the Intel family of Ix86 processors in its asm blocks.
The Intel syntax in your asm block is converted to AT&T syntax by the compiler, after which it is inserted in the compiled source. The supported assembler constructs are a subset of the normal assembly syntax. In what follows we specify what constructs are not supported in Free Pascal, but which exist in Turbo Pascal:
The TBYTE qualifier is not supported.
The & identifier override is not supported.
The HIGH operator is not supported.
The LOW operator is not supported.
The OFFSET and SEG operators are not supported. Use LEA and the various Lxx instructions instead.
Expressions with constant strings are not allowed.
Access to record fields via parenthesis is not allowed
Typecasts with normal pascal types are not allowed, only recognized assembler typecasts are allowed. Example:
mov al, byte ptr MyWord -- allowed, mov al, byte(MyWord) -- allowed, mov al, shortint(MyWord) -- not allowed.
Pascal type typecasts on constants are not allowed. Example:
const s= 10; const t = 32767;
in Turbo Pascal:
mov al, byte(s) -- useless typecast. mov al, byte(t) -- syntax error!
In Free Pascal the compiler emits a syntax error in both cases will give out a syntax error.
Expressions with constants only are not allowed (in all cases they do not work in protected mode, e.g. under linux i386). Examples:
mov al,byte ptr ['c'] -- not allowed. mov al,byte ptr [100h] -- not allowed.
(This is due to the limitation of the GNU Assembler).
Brackets within brackets are not allowed.
Expressions with segment overrides fully in brackets are currently not supported, but they can easily be implemented in the compiler if requested. Example:
mov al,[ds:bx] -- not allowed
use instead:
mov al,ds:[bx]
Possible allowed indexing are as follows:
Sreg:[REG+REG*SCALING+/-disp]
SReg:[REG+/-disp]
SReg:[REG]
SReg:[REG+REG+/-disp]
SReg:[REG+REG*SCALING]
Where Sreg is optional and specifies the segment override. Notes:
The order of terms is important contrary to Turbo Pascal.
The Scaling value must be a value, and not an identifier to a symbol. Examples:
const myscale = 1; ... mov al,byte ptr [esi+ebx*myscale] -- not allowed.
use:
mov al, byte ptr [esi+ebx*1]
Possible variable identifier syntax is as follows: (Id = Variable or typed constant identifier.)
ID
[ID]
[ID+expr]
ID[expr]
Possible fields are as follows:
ID.subfield.subfield …
[ref].ID.subfield.subfield …
[ref].typename.subfield …
Local labels: Contrary to Turbo Pascal, local labels, must at least contain one character after the local symbol indicator. Example:
@: -- not allowed
use instead:
@1: -- allowed
Contrary to Turbo Pascal, local references cannot be used as references, only as displacements. Example:
lds si,@mylabel -- not allowed
Contrary to Turbo Pascal, SEGCS, SEGDS, SEGES and SEGSS segment overrides are presently not supported. (This is a planned addition though).
Contrary to Turbo Pascal where memory sizes specifiers can be practically anywhere, the Free Pascal Intel inline assembler requires memory size specifiers to be outside the brackets. Example:
mov al,[byte ptr myvar] -- not allowed.
use:
mov al,byte ptr [myvar] -- allowed.
Base and Index registers must be 32-bit registers. (limitation of the GNU Assembler).
XLAT is equivalent to XLATB.
Only Single and Double FPU opcodes are supported.
Floating point opcodes are currently not supported (except those which involve only floating point registers).
The Intel inline assembler supports the following macros:
represents the function result return value.
represents the object method pointer in methods.