Sign in Join
Wiki copytemporary

Asm: what changed

Revision 0 to 1. Removed lines have a minus sign; added lines have a plus sign.

Title: Asm

OldNewLine
1+The [[Reserved word|reserved word]] `asm` starts a [[Frame|frame]] of inline [[Assembly language|assembly]] code.
2+
3+``` pascal
4+program asmDemo(input, output, stderr);
5+
6+// The $asmMode directive informs the compiler
7+// which syntax is used in asm-blocks.
8+// Alternatives are 'att' (AT&T syntax) and 'direct'.
9+{$asmMode intel}
10+
11+var
12+ n, m: longint;
13+begin
14+ n := 42;
15+ m := -7;
16+ writeLn('n = ', n, '; m = ', m);
17+
18+ // instead of declaring another temporary variable
19+ // and writing "tmp := n; n := m; m := tmp;":
20+ asm
21+ mov eax, n // eax := n
22+ // xchg can only operate at most on one memory address
23+ xchg eax, m // swaps values in eax and at m
24+ mov n, eax // n := eax (holding the former m value)
25+ // an array of strings after the asm-block closing 'end'
26+ // tells the compiler which registers have changed
27+ // (you don't wanna mess with the compiler's notion
28+ // which registers mean what)
29+ end ['eax'];
30+
31+ writeLn('n = ', n, '; m = ', m);
32+end.
33+```
34+
35+In order to maintain portability between platforms (i.e. your code still compiles for many targets), while optimizing for specific targets, you want to set up [[Conditional compilation|conditional compilation]]:
36+
37+``` pascal
38+program sign(input, output, stderr);
39+
40+type
41+ signumCodomain = -1..1;
42+
43+{ returns the sign of an integer }
44+function signum({$ifNDef CPUx86_64} const {$endIf} x: longint): signumCodomain;
45+{$ifDef CPUx86_64} // ============= optimized implementation
46+assembler;
47+{$asmMode intel}
48+asm
49+ xor rax, rax // ensure result is not wrong
50+ // due to any residue
51+
52+ test x, x // x ≟ 0
53+ setnz al // al ≔ ¬ZF
54+
55+ sar x, 63 // propagate sign-bit through reg.
56+ cmovs rax, x // if SF then rax ≔ −1
57+end;
58+{$else} // ========================== default implementation
59+begin
60+ // This is what math.sign virtually does.
61+ // The compiled code requires _two_ cmp instructions, though.
62+ if x > 0 then
63+ begin
64+ signum := 1;
65+ end
66+ else if x < 0 then
67+ begin
68+ signum := -1;
69+ end
70+ else
71+ begin
72+ signum := 0;
73+ end;
74+end;
75+{$endIf}
76+
77+// M A I N =================================================
78+var
79+ x: longint;
80+begin
81+ readLn(x);
82+ writeLn(signum(x));
83+end.
84+```
85+
86+As you can see, you can implement whole routines in assembly language, by adding the `assembler` modifier and writing `asm` instead of `begin` for the implementation block.
87+
88+## see also
89+
90+general
91+
92+- [[The inline assembler parser]]
93+- [[Lazarus inline assembler]]
94+- [[Label|label § “assembler”]]
95+
96+relevant compiler directives
97+
98+- [[$asmMode|{$asmMode}]]
99+- [[$goto|{$goto}]]
100+- [[$stackFrames|{$stackframes}]]
101+
102+special tasks
103+
104+- [[Hardware Access|hardware access]]
105+- [[AVR Programming|AVR programming]]
106+
107+---
108+*From the Free Pascal wiki, page "Asm", as it stood on 2021-02-05 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).*
109+Category: Code
110+Category: Reserved words

Back to history