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
.
, - .