Asm/fi
From Free Pascal wiki
Jump to navigationJump to search
│
Deutsch (de) │
English (en) │
español (es) │
suomi (fi) │
Varattu sana asm
aloittaa lohkon sisäiselle assembly koodille.
1program asmDemo(input, output, stderr);
2
3// The $asmMode directive informs the compiler
4// which syntax is used in asm-blocks.
5// Alternatives are 'att' (AT&T syntax) and 'direct'.
6{$asmMode intel}
7
8var
9 n, m: longint;
10begin
11 n := 42;
12 m := -7;
13 writeLn('n = ', n, '; m = ', m);
14
15 // instead of declaring another temporary variable
16 // and writing "tmp := n; n := m; m := tmp;":
17 asm
18 mov eax, n // eax := n
19 // xchg can only operate at most on one memory address
20 xchg eax, m // swaps values in eax and at m
21 mov n, eax // n := eax (holding the former m value)
22 // an array of strings after the asm-block closing 'end'
23 // tells the compiler which registers have changed
24 // (you don't wanna mess with the compiler's notion
25 // which registers mean what)
26 end ['eax'];
27
28 writeLn('n = ', n, '; m = ', m);
29end.
Jotta saataisiin siirrettävyys eri alustojen välillä (eli koodi voitaisiin edelleen koota moniin ympäristöihin), samalla kun halutaan optimoida tiettyjä laitteita, niin asetetaan ehdollinen kääntäminen:
1program sign(input, output, stderr);
2
3type
4 signumCodomain = -1..1;
5
6{ returns the sign of an integer }
7function signum(const x: longint): signumCodomain;
8{$ifdef CPUx86_64} // ============= optimized implementation
9assembler;
10{$asmMode intel}
11asm
12 // load constants: cmov cannot handle immediates
13 // xor-instruction modifies flags => put it prior test
14 xor r8, r8 // r8 := 0
15
16 // comparison pulled up front for pipelining
17 test x, x // x = 0 ?
18
19 // load constants, since cmov cannot handle immediates
20 mov r9, -1 // r9 := -1
21
22 // determine result
23 mov eax, 1 // result := 1
24 cmovl eax, r9 // if x < 0 then result := -1
25 cmove eax, r8 // if x = 0 then result := 0
26end;
27{$else} // ========================== default implementation
28begin
29 // This is what virtually math.sign does.
30 // The compiled code requires _two_ cmp instructions, though.
31 if x > 0 then
32 begin
33 signum := 1;
34 end
35 else if x < 0 then
36 begin
37 signum := -1;
38 end
39 else
40 begin
41 signum := 0;
42 end;
43end;
44{$endif}
45
46// M A I N =================================================
47var
48 x: longint;
49begin
50 readLn(x);
51 writeLn(signum(x));
52end.
Kuten nähdään niin voidaan toteuttaa kokonaisia rutiineja assembly kielellä lisäämällä assembler
modifioija ja kirjoittamalla asm
sen sijaan, että se aloitettaisiin
begin
toteutuslohkolla.
Katso myös
Yleistä
Merkitykselliset kääntäjänohjeet
Erityistehtävät