Mengonversi angka menjadi string menggunakan FPU

Setiap orang yang menyukai pemrograman wajib menulis versinya sendiri tentang solusi untuk masalah ini. Saya memutuskan untuk tidak terkecuali.





Sesuai dengan, x64 software conventions



kami akan menganggap bahwa nomor yang akan dikonversi berada di XMM0



.





Kami akan menggunakan x64



kode x32



bit untuk pengalamatan bit. Cara penyebutan ini memungkinkan Anda memanfaatkan kedua dialek.





Simpan nilai tumpukan dan buat titik data selaras paragraf untuk meningkatkan kinerja:





	;  
	mov    r9d, esp
	lea    r8d,[r9d - 70h]
	and    r8d, 0FFFFFFF0h
	mov    esp, r8d
      
      



Kami mempersiapkannya dengan FPU



membebaskannya dari data dan mengatur peningkatan akurasi dan pembulatan ke nol:





	fsave [esp]
	finit
	mov  dword ptr[esp - dword], 037F0F7Fh
	fldcw         [esp - dword]
      
      



Kami membebani nomor dari XMM0



menjadi FPU



:





	movd qword ptr[esp - xmmword], xmm0
	fld  qword ptr[esp - xmmword]
      
      



Temukan urutan desimal dari Angka tersebut:





	fld     st(0)
	fxtract
	fldl2t
	fst     st(1)
	fdivr   st(0),st(2)
	frndint
      
      



Atur pembulatan ke angka terdekat:





	fldcw	[esp - word]
      
      



Kami mempertahankan urutan Angka dan menemukan urutan desimal Pengali untuk mengubah digit signifikan dari Angka menjadi bagian bilangan bulat:





	fist      dword ptr[esp - dword]
	movzx edx, word ptr[esp - dword]
	mov       dword ptr[esp - dword], 10h
	fisubr    dword ptr[esp - dword]
      
      



Temukan Pengali desimal dan kalikan dengan Angka:





	fmulp   st(1),st(0)
	fst     st(1)
	frndint
	fsub    st(1),st(0)
	fld1
	fscale
	fstp    st(1)
	fmulp   st(2),st(0)
	f2xm1
	fld1
	faddp   st(1),st(0)
	fmulp   st(1),st(0)
	frndint
      
      



Kami memuat ulang nomor yang dihasilkan dari FPU



ke register AX



dan XMM0



dalam ukuran masing-masing 2 dan 8 byte pertama berikutnya. Saat memuat 8 byte ke dalam register, XMM0



kami secara bersamaan mengubah urutan byte dengan menyelaraskan penunjuk tumpukan dengan paragraf:





	fbstp           tbyte ptr[esp - xmmword]
	mov       ax,    word ptr[esp -   qword]
	pshuflw xmm0, xmmword ptr[esp - xmmword], 00011011b
      
      



Kami memulihkan keadaan FPU



:





	frstor [esp]
      
      



0



:





	punpcklbw xmm0, xmm0
	pshuflw   xmm0, xmm0, 10110001b
	pshufhw   xmm0, xmm0, 10110001b
      
      



:





	mov            dword ptr[esp], 0FF00FF0h
	pshufd xmm1, xmmword ptr[esp], 0
	pand   xmm0, xmm1
	psrlw  xmm1, 4
	movdqa xmm2, xmm1
	pand   xmm1, xmm0
	psrlw  xmm1, 4
	pandn  xmm2, xmm0
	paddb  xmm1, xmm2
      
      



:





	pxor    xmm0, xmm0
	pcmpeqb xmm0, xmm1
      
      



:





	mov            dword ptr[esp], 30303030h
	pshufd xmm2, xmmword ptr[esp], 0
	paddb  xmm1, xmm2
      
      



:





	mov  byte ptr[esp],'-'
	btr             ax, 0Fh
	adc            esp, 0
	add             ax,'.0'
	mov  word ptr[esp], ax
      
      



0



:





	movdqu	      xmmword ptr[esp + word], xmm1
	pmovmskb ecx, xmm0
	bsf      ecx, ecx
	add      esp, ecx
      
      



:





	mov    ecx,(word + dword)
	mov    eax, edx
	neg     dx
	jnc     @f
	cmovns eax, edx
	setns   dh
      
      



:





	cmp   ax, 0Ah
	sbb  ecx, ecx
	mov   dl, 0Ah
	div   dl
	cmp   al, 0Ah
	sbb  ecx, 0
	shl  eax, 8
	shr   ax, 8
	div   dl
	add eax, 303030h
	lea edx,[edx * 2 + 2B51h]
	
	mov dword ptr[esp + word + ecx + word], eax
	mov  word ptr[esp + word], dx
      
      



EAX



ECX



:





@@:	lea ecx,[esp + ecx + qword]
	sub ecx, r8d
  mov eax,ecx
      
      



XMM1



XMM2



:





	movdqa xmm1, xmmword ptr[r8d]
	movdqa xmm2, xmmword ptr[r8d + xmmword]
      
      



:





	mov esp, r9d
      
      



.





/ . x64 software conventions



.






- .





- , .





- .





- SIMD



FPU



.





, - .








All Articles