Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- program randtest;
- {$mode objfpc}{$H+}
- {$apptype console}
- uses sysutils,CRT;
- type
- TTestProc=function (str:ansistring;startPos:integer;count:integer):ansistring;
- function RDTSC(): int64;
- var
- TimeStamp: record case byte of
- 1: (Whole: int64);
- 2: (Lo, Hi: Longint);
- end;
- begin
- {$asmmode intel}
- asm
- db 00Fh,031h
- mov [TimeStamp.Lo],EAX
- mov [TimeStamp.Hi],EDX
- end;
- result:=TimeStamp.Whole;
- end;
- procedure IsFuncRight(f:TTestProc);
- var
- i,j:integer;
- s,ss:ansistring;
- begin
- j:=50;
- setlength(s,j);
- for i:=1 to j do s[i]:=inttostr(i)[1];
- asm
- pushad
- end;
- ss:=f(s,0,j);
- asm
- popad
- end;
- if CompareByte(s[1],ss[1],j)=0 then writeln('Dzialanie: OK') else writeln('Dzialanie: FAIL');
- end;
- procedure TestFunc(f:TTestProc;cnt:int64;str_len:integer;il_cnt:integer=5);
- var
- i,j,m:integer;
- n:int64;
- s,ss:ansistring;
- t1:int64;
- r1:double;
- begin
- r1:=0;
- for m:=0 to il_cnt-1 do
- begin
- setlength(s,str_len);
- for i:=1 to str_len do s[i]:=chr(random(256));
- t1:=RDTSC;
- n:=0;
- repeat
- asm
- pushad
- end;
- f(s,0,str_len);
- asm
- popad
- end;
- inc(n);
- until n>=cnt;
- r1:=r1+(RDTSC-t1);
- end;
- r1:=r1/il_cnt;
- writeln('Srednia ilosc taktow maszynowych: ',r1:0:2);
- end;
- function copy_str_1(str: string; startPos: integer; count: integer): string;
- var
- s: string;
- begin
- setLength(s, count);
- asm
- mov ESI, str {ustawiam sourceIndex}
- add ESI, startPos {ustawiam pozycję, od której kopiować}
- mov EDI, s {i dest index}
- mov ECX, count {ustawiam ilość powtórzeń}
- rep movsb {kopiuję bajt po bajcie}
- end;
- result:=s;
- end;
- function copy_str_2(str: string; startPos: integer; count: integer): string;
- var
- s: string;
- begin
- setLength(s, count);
- asm
- mov ESI, str {ustawiam sourceIndex}
- add ESI, startPos {ustawiam pozycję, od której kopiować}
- mov EDI, s {gdzie kopiować}
- mov ECX, count {ustawiam licznik - ilość pozostałych znaków}
- @check:
- cmp ECX, 4 {jeśli zostało więcej niż 3 znaki, kopiuj po 4 bajty}
- jae @b4
- cmp ECX, 2 {jeśli zostało więcej niż 1 znak, kopiuj po 2 bajty}
- jae @b2
- cmp ECX, 0 {jeśli już wszystko skopiowano, zakończ}
- je @end
- @b1: {kopiowanie ostatniego bajtu}
- movsb
- dec ECX;
- jmp @end
- @b2: {kopiowanie dwóch bajtów}
- movsw
- sub ECX, 2
- jmp @check
- @b4: {kopiowanie 4 bajtów}
- movsd
- sub ECX, 4
- jmp @check
- @end:
- end;
- result:=s;
- end;
- function copy_str_123(str: ansistring; startPos: integer; count: integer): ansistring;
- var
- p:pointer;
- begin
- setLength(result, count);
- p:=@result[1];
- {$ASMMODE INTEL}
- asm
- mov ESI, str
- add ESI, startPos
- mov ECX,count
- mov EDI, p
- shr ECX,2
- rep movsd
- mov EBX,count
- and BL,03h
- test BL,BL
- jz @end
- cmp BL,2
- je @do2
- cmp BL,1
- je @do1
- @do3: movsw
- @do1: movsb
- jmp @end
- @do2: movsw
- @end:
- end;
- end;
- var
- x,y:integer;
- begin
- randseed:=0;
- writeln('1:');
- IsFuncRight(@copy_str_1);
- TestFunc(@copy_str_1,1000000,10000);
- randseed:=0;
- writeln('2:');
- IsFuncRight(@copy_str_2);
- x:=WhereX; y:=WhereY;
- writeln('Idz sobie odpocznij...');
- gotoxy(x,y);
- TestFunc(@copy_str_2,1000000,10000);
- randseed:=0;
- writeln('123:');
- IsFuncRight(@copy_str_123);
- TestFunc(@copy_str_123,1000000,10000);
- writeln;
- writeln('Tests complete.');
- readln;
- end.
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement