Difference between revisions of "Label"
From Free Pascal wiki
Jump to navigationJump to searchm (formatting) |
(changed example with Asm) |
||
Line 4: | Line 4: | ||
A <code>label</code> section is also required for jump targets in [[Asm|<code>asm</code>-blocks]]. | A <code>label</code> section is also required for jump targets in [[Asm|<code>asm</code>-blocks]]. | ||
− | |||
− | + | <syntaxhighlight>program sumExample(input, output, stderr); | |
− | |||
− | { | + | { iteratively calculates the sum over first n integers } |
− | function | + | function iterativeSumFirstNIntegers(const n: longword): qword; |
− | {$ifdef | + | {$ifdef CPUX86_64} // ============= optimized implementation |
+ | // assembler modifier appended to routine declaration | ||
assembler; | assembler; | ||
+ | // you have to familiarize the compiler with symbols | ||
+ | // which are meant to be jump targets | ||
{$goto on} | {$goto on} | ||
label | label | ||
− | + | isfni_iterate; | |
{$asmMode intel} | {$asmMode intel} | ||
asm | asm | ||
− | + | xor rax, rax // rax := 0 | |
− | + | // ecx is used as counter by loop instruction | |
− | + | mov ecx, n // ecx := n | |
− | + | isfni_iterate: | |
− | + | add rax, qword(ecx) // rax := rax + ecx | |
− | mov @result, | + | loop isfni_iterate // dec(ecx) |
− | + | // if ecx <> 0 then goto isfni_iterate | |
+ | |||
+ | // the @result macro represents the functions return value | ||
+ | mov @result, rax // result := rax | ||
+ | // note, a list of modified registers (here ['rax', 'ecx']) | ||
+ | // is ignored for pure assembler routines | ||
end; | end; | ||
− | {$else} | + | {$else} // ========================== default implementation |
+ | var | ||
+ | i: longword; | ||
+ | x: qword; | ||
begin | begin | ||
− | // | + | x := 0; // mov rax, 0 |
− | // | + | for i := n downto 1 do // mov ecx, n |
− | |||
begin | begin | ||
− | + | x := x + i; // add rax, ecx | |
− | end | + | end; // loop isfni_iterate |
− | + | iterativeSumFirstNIntegers := x; // mov @result, rax | |
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
end; | end; | ||
{$endif} | {$endif} | ||
+ | // M A I N ================================================= | ||
var | var | ||
− | + | n: longword; | |
begin | begin | ||
− | readLn( | + | readLn(n); |
− | writeLn( | + | writeLn(iterativeSumFirstNIntegers(n)); |
end.</syntaxhighlight> | end.</syntaxhighlight> | ||
+ | Of course in a production program, you would use an algorithm applying the formula <code>sum := (n * (n + 1)) div 2</code> (“Gaussian sum formula”). | ||
+ | |||
+ | |||
[[category:Pascal]] | [[category:Pascal]] | ||
[[Category:Control Structures]] | [[Category:Control Structures]] |
Revision as of 18:05, 8 February 2018
│
Deutsch (de) │
English (en) │
français (fr) │
русский (ru) │
The label
keyword is used for declaration of labels (markers for unconditional jumps using goto
keyword) used further in the unit/program.
A label
section is also required for jump targets in asm
-blocks.
program sumExample(input, output, stderr);
{ iteratively calculates the sum over first n integers }
function iterativeSumFirstNIntegers(const n: longword): qword;
{$ifdef CPUX86_64} // ============= optimized implementation
// assembler modifier appended to routine declaration
assembler;
// you have to familiarize the compiler with symbols
// which are meant to be jump targets
{$goto on}
label
isfni_iterate;
{$asmMode intel}
asm
xor rax, rax // rax := 0
// ecx is used as counter by loop instruction
mov ecx, n // ecx := n
isfni_iterate:
add rax, qword(ecx) // rax := rax + ecx
loop isfni_iterate // dec(ecx)
// if ecx <> 0 then goto isfni_iterate
// the @result macro represents the functions return value
mov @result, rax // result := rax
// note, a list of modified registers (here ['rax', 'ecx'])
// is ignored for pure assembler routines
end;
{$else} // ========================== default implementation
var
i: longword;
x: qword;
begin
x := 0; // mov rax, 0
for i := n downto 1 do // mov ecx, n
begin
x := x + i; // add rax, ecx
end; // loop isfni_iterate
iterativeSumFirstNIntegers := x; // mov @result, rax
end;
{$endif}
// M A I N =================================================
var
n: longword;
begin
readLn(n);
writeLn(iterativeSumFirstNIntegers(n));
end.
Of course in a production program, you would use an algorithm applying the formula sum := (n * (n + 1)) div 2
(“Gaussian sum formula”).