Delphi jest językiem
bardzo wysokiego poziomu.
Jego optymalizator jest świetny i doskonale radzi sobie
nawet z najbardziej skomplikowanym kodem.
Jednakże czasami potrzebna jest dużo większa prędkość - zwłaszcza przy operacjach
wykonywanych tysiące (lub miliony) razy. Wtedy warto skorzystać z assemblera.
Tekst ten jest przeznaczony dla osób, które używały już assemblera.
Podstawy
Zarówno Turbo Pascal jak i Delphi umożliwiają używanie assemblera na dwa sposoby:
1. Jako wtrącenie w ciele funkcji:
begin
{..}
asm
mov eax, 10
{...}
end;
{..}
end;
|
2. Jako cała funkcja:
procedure Nazwa(i: Integer); assembler;
asm
mov eax, 10
mov ebx, i
{...}
end;
|
Rezultat funkcji jest zawsze zwracany przez rejestr EAX.
Ograniczenia stawiane przez Windows
Po pierwsze należy pamiętać, że aplikacja dla Windows (32-bitowego) działa w
trybie 32-bitowym. Dla procesorów x86 tryb ten nazywa się chronionym.
Segmenty mają różną wielkość, nie do wszystkich można pisać,
nie wszystkie można czytać. Nie ma dostępu do portów I/O, ani do przerwań.
Nie można wykonywać niektórych instrukcji, np.:
CLI i
STI.
Wszelkie naruszenie zasad obowiązujących w trybie chronionym zakończy się wystąpieniem
wyjątku GPF (ang. General Protection Fault).
Ograniczenia stawiane przez Delphi
Dowolnie można modyfikować rejestry EAX, ECX i EDX. Rejestr EBX jest wykorzystywany
jako licznik w pętlach. Przy tym należy pamiętać, że jeśli zmienna iteracyjna nie
ma wpływu na wynik działania pętli, to delphi liczy iteracje wstecz. Warto zwrócić uwagę
na to, że nawet jeśli zmienna iteracyjna jest użyta w ciele pętli, ale nie ma wpływu na
wynik jej działania to i tak iteracje będą liczone wstecz.
for i:=0 to 10 do MessageBeep(0);
|
Delphi zapisze to tak:
mov ebx, 10
loop:
push 0
call MessageBeep
dec ebx
jnz loop
|
Natomiast jeśli w ciele pętli wykorzystamy zmienną iteracyjną:
for i:=0 to 10 do MessageBeep(i);
|
to Delphi zapisze to tak:
xor ebx, ebx
loop:
push ebx
call MessageBeep
inc ebx
cmp ebx, 10
jne loop
|
To taki kruczek, o którym każdy powinien wiedzieć.
Zalety optymalizatora Delphi
Nie wszystkie parametry przekazywane są przez stos.
Optymalizator zawsze stara się przenosić parametry funkcji za pomocą rejestrów procesora.
Delphi używa wszystkich rejestrów poza EBP, ESP i segmentowymi.
Bez obaw możemy używać rejestrów EAX, ECX i EDX. Delphi to uwzględni, tzn.: jeśli w ciele
procedury jest użyty jeden z rejestrów, to optymalizator nie będzie go używał.
Zainteresowanym polecam podglądanie Delphi w okienku disassemblera.
Można się naprawdę dużo nauczyć.
To tyle, jeśli ktoś ma jakieś pytania to proszę
pisać.
Michał Bąkowski
Tutaj znajdzie się twoje zdanie jeśli znajdziesz chwilkę, żeby je wklepać...