30-12-2020, Saat: 07:31
(Son Düzenleme: 30-12-2020, Saat: 20:37, Düzenleyen: PROGRAMADOR35.)
Bu başlık altında kendi oluşturmuş olduğum ya da faydalandığım 64 bit delphi assembly kodları paylaşacağım. Kodlar arasına mümkün mertebe yorum satırları ekleyeceğim.
Delphi'nin inttostr fonksiyonuna alternatif bir assembly fonksiyonu:
Kullanımı:
Bu fonksiyon ansistring içindir.
Agner Fog'un hazırlamış olduğu asmlib kütüphanesinden delphiye aktardığım StrLen fonksiyonu:
Standard length fonksiyonuna göre oldukça hızlıdır.
Delphi'nin inttostr fonksiyonuna alternatif bir assembly fonksiyonu:
{ Author: Hakan DİMDİK Last modified: 30/12/2020 An alternatif function to inttostr } procedure intoansi(src:uint64; dst:pansichar); asm .noframe //edx:eax bölünen, kalan dl mov eax, ecx //src'yi eax'e alıyoruz mov r9, rdx //string adresi mov r10, 10 //constant 10 xor r8, r8 //basamak sayısı 0'dan başlıyor, çünkü indeks numarasıyla işlem yapacağız @basamakLoop: xor edx, edx //dx sıfırlama div r10d //eax'i 10'a bölüyoruz add r8,1 cmp eax, 10 jae @basamakLoop mov eax, ecx //src'yi eax'e tekrar alıyoruz cmp eax, r10d //sayı ondan küçükse sona git jb @Ret @L: xor edx, edx //bölme işleminde kalan kısmı tekrar sıfırlıyoruz div r10d //eax'i 10'a bölüyoruz //kalanı ekledik add dl, 48 //dl'den ascii karakteri elde ediyoruz mov [r9+r8], dl sub r8, 1 //bölüm 10'dan küçükse bitir cmp eax, r10d jb @Ret10 jmp @L; @Ret10: add al, 48 mov byte ptr [r9+r8], al ret @Ret: add al, 48 //sayıya 48 eklenince ascii değerini alıyoruz mov byte ptr [r9+r8], al //indekse ascii değeri yaz end;
Kullanımı:
procedure TestMy; var str:ansistring; begin SetLength(str,2); intoansi(33,pansichar(str)); write(str); Readln; end;
Bu fonksiyon ansistring içindir.
Agner Fog'un hazırlamış olduğu asmlib kütüphanesinden delphiye aktardığım StrLen fonksiyonu:
{ Agner Fog strlen function https://github.com/tpn/agner/blob/master...rlen32.asm } function StrLen(const AStr: PAnsiChar): NativeUInt; asm .noframe mov rax, rcx //; string'in pointerini alıyoruz mov r8, rcx //; string'in pointerini kopyalıyoruz //; rax = s, ecx = 32 bits of s pxor xmm0, xmm0 //; xmm0 registerini sıfırlıyoruz and ecx, 0FH //; lower 4 bits indicate misalignment and rax, -10H //; align pointer by 16 movdqa xmm1, [rax] //; read from nearest precedingboundary pcmpeqb xmm1, xmm0 //; compare 16 bytes with zero pmovmskb edx, xmm1 //; get one bit for each byte result shr edx, cl // ; shift out false bits shl edx, cl // ; shift back again bsf edx, edx // ; find first 1-bit jnz @L2 // ; found //; Main loop, search 16 bytes at a time @L1: add rax, 10H // ; increment pointer by 16 movdqa xmm1, [rax] // ; read 16 bytes aligned pcmpeqb xmm1, xmm0 // ; compare 16 bytes with zero pmovmskb edx, xmm1 // ; get one bit for each byte result bsf edx, edx // ; find first 1-bit //; (moving the bsf out of the loop and using test here would be faster for long strings on old processors, //; but we are assuming that most strings are short, and newer processors have higher priority) jz @L1 @L2: //; Zero-byte found. Compute string length sub rax, r8 // ; subtract start address add rax, rdx // ; add byte index ret end;
Standard length fonksiyonuna göre oldukça hızlıdır.