Label: what changed
Revision 0 to 1. Removed lines have a minus sign; added lines have a plus sign.
Title: Label
| Old | New | Line | |
|---|---|---|---|
| 1 | + | The `label` keyword is used for declaration of labels (markers for unconditional jumps using [[Goto|goto]] keyword) used further in the [[Unit|unit]]/[[Program|program]]. It is a [[Reserved words|reserved word]]. | |
| 2 | + | ||
| 3 | + | ## Pascal | |
| 4 | + | ||
| 5 | + | To declare a label (not defining it) `label` starts a section with (comma separated) identifiers: | |
| 6 | + | ||
| 7 | + | ``` pascal | |
| 8 | + | program labelDemo(input, output, stderr); | |
| 9 | + | ||
| 10 | + | {$goto on} | |
| 11 | + | // familiarize the compiler with symbols | |
| 12 | + | // that are meant as 'goto' targets | |
| 13 | + | label | |
| 14 | + | // the symbol 'done' becomes of "type" label | |
| 15 | + | done; | |
| 16 | + | ``` | |
| 17 | + | ||
| 18 | + | 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: | |
| 19 | + | ||
| 20 | + | ``` pascal | |
| 21 | + | var | |
| 22 | + | n: qword; | |
| 23 | + | x, sum, arithmeticMean: real; | |
| 24 | + | begin | |
| 25 | + | n := 0; | |
| 26 | + | sum := 0; | |
| 27 | + | while true do | |
| 28 | + | begin | |
| 29 | + | readLn(x); | |
| 30 | + | if x < 0 then | |
| 31 | + | begin | |
| 32 | + | // leave loop and continue at 'done' | |
| 33 | + | goto done; | |
| 34 | + | end; | |
| 35 | + | sum := sum + x; | |
| 36 | + | inc(n); | |
| 37 | + | end; | |
| 38 | + | done: | |
| 39 | + | arithmeticMean := sum / n; | |
| 40 | + | writeLn('arithemetic mean = ', arithmeticMean); | |
| 41 | + | end. | |
| 42 | + | ``` | |
| 43 | + | ||
| 44 | + | Pascal imposes further restrictions on labels: Labels have to be associated with statements: Putting a label right before an [[End|end]] is not allowed. To bypass that, you can insert an empty instruction [[;]] right after the label definition. | |
| 45 | + | ||
| 46 | + | In addition to normal [[Identifier|identfiers]], labels may be non-negative integers. | |
| 47 | + | ||
| 48 | + | ## Assembler | |
| 49 | + | ||
| 50 | + | A `label` section is also required for jump targets in [[Asm|asm-blocks]], unless the [[@|@-address-operator]] is used. | |
| 51 | + | ||
| 52 | + | ``` pascal | |
| 53 | + | program sumExample(input, output, stderr); | |
| 54 | + | ||
| 55 | + | { iteratively calculates the sum over first n integers } | |
| 56 | + | function iterativeSumFirstNIntegers(const n: longword): qword; | |
| 57 | + | {$ifdef CPUX86_64} // ============= optimized implementation | |
| 58 | + | // assembler modifier appended to routine declaration | |
| 59 | + | assembler; | |
| 60 | + | // you have to familiarize the compiler with symbols | |
| 61 | + | // which are meant to be jump targets | |
| 62 | + | {$goto on} | |
| 63 | + | label | |
| 64 | + | isfni_iterate; | |
| 65 | + | {$asmMode intel} | |
| 66 | + | asm | |
| 67 | + | xor rax, rax // rax := 0 | |
| 68 | + | // ecx is used as counter by loop instruction | |
| 69 | + | mov ecx, n // ecx := n | |
| 70 | + | isfni_iterate: | |
| 71 | + | add rax, qword(ecx) // rax := rax + ecx | |
| 72 | + | loop isfni_iterate // dec(ecx) | |
| 73 | + | // if ecx <> 0 then goto isfni_iterate | |
| 74 | + | ||
| 75 | + | // the @result macro represents the functions return value | |
| 76 | + | mov @result, rax // result := rax | |
| 77 | + | // note, a list of modified registers (here ['rax', 'ecx']) | |
| 78 | + | // is ignored for pure assembler routines | |
| 79 | + | end; | |
| 80 | + | {$else} // ========================== default implementation | |
| 81 | + | var | |
| 82 | + | i: longword; | |
| 83 | + | x: qword; | |
| 84 | + | begin | |
| 85 | + | x := 0; // mov rax, 0 | |
| 86 | + | for i := n downto 1 do // mov ecx, n | |
| 87 | + | begin | |
| 88 | + | x := x + i; // add rax, ecx | |
| 89 | + | end; // loop isfni_iterate | |
| 90 | + | iterativeSumFirstNIntegers := x; // mov @result, rax | |
| 91 | + | end; | |
| 92 | + | {$endif} | |
| 93 | + | ||
| 94 | + | // M A I N ================================================= | |
| 95 | + | var | |
| 96 | + | n: longword; | |
| 97 | + | begin | |
| 98 | + | readLn(n); | |
| 99 | + | writeLn(iterativeSumFirstNIntegers(n)); | |
| 100 | + | end. | |
| 101 | + | ``` | |
| 102 | + | ||
| 103 | + | Of course in a production program, you would use an algorithm applying the formula `sum := (n * (n + 1)) div 2` (“Gaussian sum formula”). | |
| 104 | + | ||
| 105 | + | ## See also | |
| 106 | + | ||
| 107 | + | - [[Goto|goto command]] | |
| 108 | + | - [[sGoto|{$goto} compiler directive]] | |
| 109 | + | - [`system.setJmp`](https://www.freepascal.org/docs-html/rtl/system/setjmp.html) | |
| 110 | + | ||
| 111 | + | --- | |
| 112 | + | *From the Free Pascal wiki, page "Label", 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](/wiki-contact).* | |
| 113 | + | Category: Code |
