Assembly is always faster than high-level languages. For example, I tested an empty loop in Delphi repeating 1 billion times, and same loop but written in assembly. The Delphi loop took 6 billion (x64 CPU) cycles, but the assembly loop took only 2 billion cycles.
When I need to perform a high-performance action, I’ll code it in assembly whenever possible. But I can’t always code in assembly; sometimes I’ll need to do actions which need a high-level programming language. Now everything is good, but a loop requires labels.
I tried closing the assembly block, doing my actions, then opening final assembly blocks to handle the loop. But it results in errors. I entered this code in Delphi:
program Test;
{$APPTYPE CONSOLE}
{$R *.res}
uses
Sysutils;
var
f, i: int64;
begin
asm
rdtsc
mov dword ptr f[0], eax
mov dword ptr f[4], eax
mov eax, 1000
@loop:
sub eax, 1
end;
WriteLn('Hello, World!');
asm;
jnz @loop
rdtsc
mov dword ptr i[0], eax
mov dword ptr i[4], eax
end;
ReadLn; // Allow user to read output
end.
I expected this to print Hello, World!
1,000 times, but instead I got this error:
E2003: Undeclared identifier: '@loop' at line 23 (23:1)
The problem is that Delphi’s in-line assembly won’t allow accessing labels declared in previous assembly blocks.
Can you help me to access labels declared in previous assembly blocks?
Without touching why your reasoning and code is wrong on so many levels, I can get it to compile if I define the loop in Delphi Seattle by defining only the label in pascal. That might trigger extra instructions, (stack related) but probably only before the real label.
program Project5;
{$APPTYPE CONSOLE}
uses
System.SysUtils;
label loop;
var
f, i: int64;
begin
asm
rdtsc
mov dword ptr f[0], eax
mov dword ptr f[4], eax
mov eax, 1000
end;
loop:
asm
sub eax, 1
end;
WriteLn('Hello, World!'); // will EAX survive this? Otherwise push/pop
asm // remove spurious ;
test eax,eax // zero flag might not survive writeln
jnz loop
rdtsc
mov dword ptr i[0], eax
mov dword ptr i[4], eax
end;
ReadLn; // Allow user to read output
end.