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