Asm/fi
Deutsch · English · Español · Suomi
Varattu sana asm aloittaa lohkon sisäiselle assembly koodille.
program asmDemo(input, output, stderr);
// The $asmMode directive informs the compiler
// which syntax is used in asm-blocks.
// Alternatives are 'att' (AT&T syntax) and 'direct'.
{$asmMode intel}
var
n, m: longint;
begin
n := 42;
m := -7;
writeLn('n = ', n, '; m = ', m);
// instead of declaring another temporary variable
// and writing "tmp := n; n := m; m := tmp;":
asm// eax := n// xchg can only operate at most on one memory address// swaps values in eax and at m// n := eax (holding the former m value)// an array of strings after the asm-block closing 'end'// tells the compiler which registers have changed// (you don't wanna mess with the compiler's notion// which registers mean what)
mov eax, n // eax := n
// xchg can only operate at most on one memory address
xchg eax, m // swaps values in eax and at m
mov n, eax // n := eax (holding the former m value)
// an array of strings after the asm-block closing 'end'
// tells the compiler which registers have changed
// (you don't wanna mess with the compiler's notion
// which registers mean what)
END ['eax'];
writeLn('n = ', n, '; m = ', m);
end.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:
program sign(input, output, stderr);
type
signumCodomain = -1..1;
{ returns the sign of an integer }
function signum(const x: longint): signumCodomain;
{$ifdef CPUx86_64} // ============= optimized implementation
assembler;
{$asmMode intel}
asm// load constants: cmov cannot handle immediates// xor-instruction modifies flags => put it prior test// r8 := 0// comparison pulled up front for pipelining// x = 0 ?// load constants, since cmov cannot handle immediates// r9 := -1// determine result// result := 1// if x < 0 then result := -1// if x = 0 then result := 0
// load constants: cmov cannot handle immediates
// xor-instruction modifies flags => put it prior test
xor r8, r8 // r8 := 0
// comparison pulled up front for pipelining
test x, x // x = 0 ?
// load constants, since cmov cannot handle immediates
mov r9, -1 // r9 := -1
// determine result
mov eax, 1 // result := 1
cmovl eax, r9 // if x < 0 then result := -1
cmove eax, r8 // if x = 0 then result := 0
END;
{$else} // ========================== default implementation
begin
// This is what virtually math.sign does.
// The compiled code requires _two_ cmp instructions, though.
if x > 0 then
begin
signum := 1;
end
else if x < 0 then
begin
signum := -1;
end
else
begin
signum := 0;
end;
end;
{$endif}
// M A I N =================================================
var
x: longint;
begin
readLn(x);
writeLn(signum(x));
end.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
From the Free Pascal wiki, page "Asm/fi", as it stood on 2022-08-06 after a change by Kai Burghardt, out of the wiki's dump of 2024-05-26. Copyright stays with the author who wrote it, according to the old wiki's Licensing page. If you have concerns about this material, message the admin.