Difference between revisions of "Label"

From Free Pascal wiki
Jump to navigationJump to search
m (grammar)
(partially undo 132475: Category: Code is not (and should not be) included via Template: label; remove stupid “back-to” link as there are many pages linking here)
(10 intermediate revisions by 2 users not shown)
Line 1: Line 1:
 
{{label}}
 
{{label}}
  
The <code>label</code> keyword is used for declaration of labels (markers for unconditional jumps using [[Goto|goto]] keyword) used further in the unit/program.
+
The <syntaxhighlight lang="pascal" enclose="none">label</syntaxhighlight> keyword is used for declaration of labels (markers for unconditional jumps using [[Goto|<syntaxhighlight lang="pascal" enclose="none">goto</syntaxhighlight>]] keyword) used further in the [[Unit|<syntaxhighlight lang="pascal" enclose="none">unit</syntaxhighlight>]]/[[Program|<syntaxhighlight lang="pascal" enclose="none">program</syntaxhighlight>]].
 +
It is a [[Reserved words|reserved word]].
  
A <code>label</code> section is also required for jump targets in [[Asm|<code>asm</code>-blocks]].
+
== Pascal ==
<syntaxhighlight>program sign(input, output, stderr);
 
  
type
+
To declare a label (not defining it) <syntaxhighlight lang="pascal" enclose="none">label</syntaxhighlight> starts a section with (comma separated) identifiers:
signumCodomain = -1..1;
+
<syntaxhighlight lang="pascal" line start="1" highlight="4-8">
 +
program labelDemo(input, output, stderr);
  
{ returns the sign of an integer }
+
{$goto on}
function signum(const x: longint): signumCodomain;
+
// familiarize the compiler with symbols
{$ifdef CPUx86_64}
+
// that are meant as 'goto' targets
 +
label
 +
// the symbol 'done' becomes of "type" label
 +
done;
 +
</syntaxhighlight>
 +
 
 +
You then define the label, that means associating a symbol with a statement and effectively in the compiled code with an address, by writing the previously declared label in a statement block followed by a colon:
 +
<syntaxhighlight lang="pascal" line start="9" highlight="18">
 +
var
 +
n: qword;
 +
x, sum, arithmeticMean: real;
 +
begin
 +
n := 0;
 +
sum := 0;
 +
while true do
 +
begin
 +
readLn(x);
 +
if x < 0 then
 +
begin
 +
// leave loop and continue at 'done'
 +
goto done;
 +
end;
 +
sum := sum + x;
 +
inc(n);
 +
end;
 +
done:
 +
arithmeticMean := sum / n;
 +
writeLn('arithemetic mean = ', arithmeticMean);
 +
end.
 +
</syntaxhighlight>
 +
 
 +
Pascal imposes further restrictions on labels:
 +
Labels have to be associated with statements: Putting a label right before an [[End|<syntaxhighlight lang="pascal" enclose="none">end</syntaxhighlight>]] is not allowed. To bypass that, you can insert an empty instruction [[;|<syntaxhighlight lang="pascal" enclose="none">;</syntaxhighlight>]] right after the label definition.
 +
 
 +
In addition to normal [[Identifier|identfiers]], labels may be non-negative integers.
 +
 
 +
== Assembler ==
 +
 
 +
A <syntaxhighlight lang="pascal" enclose="none">label</syntaxhighlight> section is also required for jump targets in [[Asm|<syntaxhighlight lang="pascal" enclose="none">asm</syntaxhighlight>-blocks]], unless the [[@|<syntaxhighlight lang="pascal" enclose="none">@</syntaxhighlight>-address-operator]] is used.
 +
 
 +
<syntaxhighlight lang="pascal" line highlight="8-12,18,20-21">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;
 
assembler;
 +
// you have to familiarize the compiler with symbols
 +
// which are meant to be jump targets
 
{$goto on}
 
{$goto on}
 
label
 
label
signum_done;
+
isfni_iterate;
 
{$asmMode intel}
 
{$asmMode intel}
 
asm
 
asm
mov @result, // result := 1
+
xor rax, rax // rax := 0
cmp x, 0        // x = 0 ?
+
// ecx is used as counter by loop instruction
jg signum_done  // if x > 0 then goto signum_done
+
mov ecx, n  // ecx := n
mov @result, -1 // result := -1
+
isfni_iterate:
jl signum_done // if x < 0 then goto signum_done
+
add rax, qword(ecx) // rax := rax + ecx
mov @result, // result := 0
+
loop isfni_iterate // dec(ecx)
signum_done:
+
// 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
if x > 0 then
+
x := 0; // mov rax, 0
 +
for i := n downto 1 do // mov ecx, n
 
begin
 
begin
signum := 1;
+
x := x + i; // add rax, ecx
end
+
end; // loop isfni_iterate
else if x < 0 then
+
iterativeSumFirstNIntegers := x; // mov @result, rax
begin
 
signum := -1;
 
end
 
else
 
begin
 
signum := 0;
 
end;
 
 
end;
 
end;
 
{$endif}
 
{$endif}
  
 +
// M A I N =================================================
 
var
 
var
x: longint;
+
n: longword;
 
begin
 
begin
readLn(x);
+
readLn(n);
writeLn(signum(x));
+
writeLn(iterativeSumFirstNIntegers(n));
 
end.</syntaxhighlight>
 
end.</syntaxhighlight>
 +
Of course in a production program, you would use an algorithm applying the formula <syntaxhighlight lang="pascal" enclose="none">sum := (n * (n + 1)) div 2</syntaxhighlight> (“Gaussian sum formula”).
 +
 +
== See also ==
 +
 +
* [[Goto|<syntaxhighlight lang="pascal" enclose="none">goto</syntaxhighlight> command]]
 +
* [[sGoto|<syntaxhighlight lang="pascal" enclose="none">{$goto}</syntaxhighlight> compiler directive]]
 +
* {{Doc|package=RTL|unit=system|identifier=setjmp|text=<syntaxhighlight lang="pascal" enclose="none">system.setJmp</syntaxhighlight>}}
  
[[category:Pascal]]
+
[[Category: Code]]
[[Category:Control Structures]]
 

Revision as of 02:40, 6 May 2020

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. It is a reserved word.

Pascal

To declare a label (not defining it) label starts a section with (comma separated) identifiers:

1program labelDemo(input, output, stderr);
2
3{$goto on}
4// familiarize the compiler with symbols
5// that are meant as 'goto' targets
6label
7	// the symbol 'done' becomes of "type" label
8	done;

You then define the label, that means associating a symbol with a statement and effectively in the compiled code with an address, by writing the previously declared label in a statement block followed by a colon:

 9var
10	n: qword;
11	x, sum, arithmeticMean: real;
12begin
13	n := 0;
14	sum := 0;
15	while true do
16	begin
17		readLn(x);
18		if x < 0 then
19		begin
20			// leave loop and continue at 'done'
21			goto done;
22		end;
23		sum := sum + x;
24		inc(n);
25	end;
26done:
27	arithmeticMean := sum / n;
28	writeLn('arithemetic mean = ', arithmeticMean);
29end.

Pascal imposes further restrictions on labels: Labels have to be associated with statements: Putting a label right before an end is not allowed. To bypass that, you can insert an empty instruction ; right after the label definition.

In addition to normal identfiers, labels may be non-negative integers.

Assembler

A label section is also required for jump targets in asm-blocks, unless the @-address-operator is used.

 1program sumExample(input, output, stderr);
 2
 3{ iteratively calculates the sum over first n integers }
 4function iterativeSumFirstNIntegers(const n: longword): qword;
 5{$ifdef CPUX86_64} // ============= optimized implementation
 6// assembler modifier appended to routine declaration
 7assembler;
 8// you have to familiarize the compiler with symbols
 9// which are meant to be jump targets
10{$goto on}
11label
12	isfni_iterate;
13{$asmMode intel}
14asm
15	xor rax, rax // rax := 0
16	// ecx is used as counter by loop instruction
17	mov ecx, n   // ecx := n
18isfni_iterate:
19	add rax, qword(ecx) // rax := rax + ecx
20	loop isfni_iterate  // dec(ecx)
21	// if ecx <> 0 then goto isfni_iterate
22	
23	// the @result macro represents the functions return value
24	mov @result, rax // result := rax
25// note, a list of modified registers (here ['rax', 'ecx'])
26//       is ignored for pure assembler routines
27end;
28{$else} // ========================== default implementation
29var
30	i: longword;
31	x: qword;
32begin
33	x := 0; // mov rax, 0
34	for i := n downto 1 do // mov ecx, n
35	begin
36		x := x + i; // add rax, ecx
37	end; // loop isfni_iterate
38	iterativeSumFirstNIntegers := x; // mov @result, rax
39end;
40{$endif}
41
42// M A I N =================================================
43var
44	n: longword;
45begin
46	readLn(n);
47	writeLn(iterativeSumFirstNIntegers(n));
48end.

Of course in a production program, you would use an algorithm applying the formula sum := (n * (n + 1)) div 2 (“Gaussian sum formula”).

See also