asm i delphi

0

Witam
Chcialbym przerobic petle <ort>wykozystujaca </ort>tablice dynamiczne na asm

for i:=0 to high( tabl[0].next) do
begin
if tabl[0].next[i]>0 then z:=tabl[0].next[i]
else
...

i teraz mam problem nigdy nie bawilem sie asm w delphi i mam pytanie
pod jakim adresem przechowywane sa dane z tablicy tzn jasniej w jaki sposob skopiowac wartosc z tablicy do rejestru

0

var p:array of byte; (czy cokolwiek)
Jeśli p jest tablicą bez o długości 0, to p=0. W przeciwnym razie, p=@p[0], czyli p jest adresem pierwszego elementu tablicy. Natomiast pod adresem p-4 zapisana jest długość tablicy. Mały przykładzik w asmie:

var a,b:array of char;
begin
  SetLength(a, 12);
  SetLength(b, 12);
  StrCopy(@a[0],'ala ma kota');
  ShowMessage(PChar(@a[0]));
  asm
    mov esi, a       //1szy element tabl. a
    mov ecx, [esi-4] //w ecx mamy dlugosc tablicy
    mov edi, b       //1szy element tabl. b
    rep movsb       //dopoki ecx<>0, kopiujemy z esi do edi i dec(ecx)
  end;
  ShowMessage(PChar(@b[0]));
  SetLength(a, 0);
  SetLength(b, 0);
end;
0

A co jezeli mamy cos takiego

type
tablica=record
tab1:array of array of smallint
tab2: array of byte
end;

var
tabela: array of tablica;
begin
setlength(tabela,5);

setlength(tabela[0].tab1,10,10);
....

jak w asm dostac dlugosc poszczegolnych rekordow
i jak odczytac np wartosc tabela[1].tab1[0][0] ????

0

Wszystko tak samo, tylko się bardziej zagnieżdża. Ot, taki przykład:

type TTablica = record
       a:array of array of byte;
       b:array of byte;
       c:word;
     end;
var t:array of TTablica;
    a, b, c, d:cardinal;
begin
  //zapisujemy t[a].a[b, c] do t[a].b[d]
  asm
    mov esi, t //esi = @t[0]
    mov eax, a
    mov edx, 10 //SizeOf(TTablica)
    mul edx    //eax = a*SizeOf(TTablica)
    {
      jesli znamy rozmiar TTablica i jest on = 2, 4, 8, to mozna prosciej:
      mov eax, a
      lea esi, [esi+eax*8]
    }
    add esi, eax //esi = @t[a]
    mov edi, TTablica([esi]).b //edi = @t[a].b[0]
    mov esi, TTablica([esi]).a //esi = @t[a].a[0]
    mov eax, b
    mov esi, [esi+4*eax] //esi = @t[a].a[b][0]
    add esi, c //esi = @t[a].a[b][c]
    mov dl, [esi] //dl = t[a].a[b][c]
    add edi, d
    mov [edi], dl
  end;

PS: akurat Delphi ma wyjątkowo dobrą optymalizacje. Polecam ustawić breakpointa w interesującym ciebie miejscu i potem, przy zatrzymanym programie, z menu: View->Debug Windows->CPU

0

Dzieki wielkie za pomoc

1 użytkowników online, w tym zalogowanych: 0, gości: 1