Asm
From Lazarus wiki
Revision as of 17:28, 11 February 2018 by Kai Burghardt (talk | contribs) (more colorful syntax highlight)
│
Deutsch (de) │
English (en) │
español (es) │
suomi (fi) │
The reserved word asm
starts a block of inline assembly code.
0program asmDemo(input, output, stderr);
1
2// The $asmMode directive informs the compiler
3// which syntax is used in asm-blocks.
4// Alternatives are 'att' (AT&T syntax) and 'direct'.
5{$asmMode intel}
6
7var
8 n, m: longint;
9begin
10 n := 42;
11 m := -7;
12 writeLn('n = ', n, '; m = ', m);
13
14 // instead of declaring another temporary variable
15 // and writing "tmp := n; n := m; m := tmp;":
16 asm
17 mov eax, n // eax := n
18 // xchg can only operate at most on one memory address
19 xchg eax, m // swaps values in eax and at m
20 mov n, eax // n := eax (holding the former m value)
21 // an array of strings after the asm-block closing 'end'
22 // tells the compiler which registers have changed
23 // (you don't wanna mess with the compiler's notion
24 // which registers mean what)
25 end ['eax'];
26
27 writeLn('n = ', n, '; m = ', m);
28end.
In order to maintain portability between platforms (i.e. your code still compiles for many targets), while optimizing for specific targets, you want to set up conditional compilation:
0program sign(input, output, stderr);
1
2type
3 signumCodomain = -1..1;
4
5{ returns the sign of an integer }
6function signum(const x: longint): signumCodomain;
7{$ifdef CPUx86_64} // ============= optimized implementation
8assembler;
9{$asmMode intel}
10asm
11 // load constants: cmov cannot handle immediates
12 // xor-instruction modifies flags => put it prior test
13 xor r8, r8 // r8 := 0
14
15 // comparison pulled up front for pipelining
16 test x, x // x = 0 ?
17
18 // load constants, since cmov cannot handle immediates
19 mov r9, -1 // r9 := -1
20
21 // determine result
22 mov eax, 1 // result := 1
23 cmovl eax, r9 // if x < 0 then result := -1
24 cmove eax, r8 // if x = 0 then result := 0
25end;
26{$else} // ========================== default implementation
27begin
28 // This is what virtually math.sign does.
29 // The compiled code requires _two_ cmp instructions, though.
30 if x > 0 then
31 begin
32 signum := 1;
33 end
34 else if x < 0 then
35 begin
36 signum := -1;
37 end
38 else
39 begin
40 signum := 0;
41 end;
42end;
43{$endif}
44
45// M A I N =================================================
46var
47 x: longint;
48begin
49 readLn(x);
50 writeLn(signum(x));
51end.
As you can see, you can implement whole routines in assembly language, by adding the assembler
modifier and writing asm
instead of begin
for the implementation block.
see also
general
relevant compiler directives
special tasks