1. Configuración de convenciones de compilación, direccionamiento y llamada.
1.1. .
.
x64 software conventions
RCX
.
1.2. .
. .
.
x64
x32
. .
/LARGEADDRESSAWARE:NO
.
2. Constantes de texto y alias.
2.1.
() «» :
BUFF_STR equ esp - xmmword * 4
2.2. .
, , «» «» :
DWORD
INT
, , «» «» :
; CUR_CHAR equ ecx ; DOT_CHAR equ edx ; HASH_STR equ r8d ; END_CHAR equ HASH_STR ; N_Z_CHAR equ r9d ; OFF_CHAR equ N_Z_CHAR ; END_FRAC equ r10d ; EXP_CHAR equ END_FRAC ; LEN_NUMB equ r11d ; LEN_CELL equ LEN_NUMB ; HASH_MUL equ ebx ; MANT_ARG equ r8 ; LOGB_ARG equ r9d ; MANT_MUL equ r10 ; LOGB_MUL equ r11d ;
3. Sección de datos
. «» , ,
, :
.
SIMD
, :
.data Xmm_HT byte 10h dup (09h) Xmm_CR byte 10h dup (0Dh) Xmm_SP byte 10h dup (20h) Xmm_SL byte 10h dup ('/') Xmm_30 byte 10h dup ('0') Xmm_39 byte 10h dup ('9') Xmm_0001 word 8 dup (010Ah) Xmm_0010 dword 4 dup (10064h) Xmm_0100 qword 2 dup (100002710h) Mask_001 word 0044h, 0944h, 0D44h, 2044h, 0046h, 0946h, 0D46h, 2046h Mask_010 word 0064h, 0964h, 0D64h, 2064h, 0066h, 0966h, 0D66h, 2066h Mul_0001 qword 0E8D4A51000h Plus word 2B00h ; string byte ' ', 0Dh, 0Ah, '+-0098765432109876540.09876e-0248 '
.
4. Sección de código.
4.1. .
4.1.1.
4.1.1.1. .
—
.
—
.
—
.
,
, 15 . , , . .
3
3
-1
.
—
CUR_CHAR
.
—
CUR_CHAR
.
pcmpeqb xmm3, xmm3 sub CUR_CHAR, xmmword @@: add CUR_CHAR, xmmword
,
-
, 15 . , , . .
4.1.1.2. .
—
/
.
— ,
/
/
—
.
. «» .
0
1
/
2
.
— ,
/
/
—
0
.
movdqu xmm0,[CUR_CHAR] movdqa xmm1, xmm0 movdqa xmm2, xmm0 pcmpeqb xmm0, xmmword ptr Xmm_SP pcmpeqb xmm1, xmmword ptr Xmm_HT pcmpeqb xmm2, xmmword ptr Xmm_CR paddb xmm0, xmm1 paddb xmm0, xmm2
0
-1
0
. «» .
4.1.1.3. .
—
.
—
.
.
/
/
,
, , .
PTEST
AND
0
3
-1
CF=1
.
—
CF=1
.
ptest xmm0, xmm3 jc @b ;
.
/
/
SIMD
,
64
, , .
4.1.2. .
-
,
.
—
,
.
—
, , .
—
.
0
EAX
,
1
.
—
EAX
,
1
.
—
EAX
1
, , .
—
EAX
CUR_CHAR
.
pmovmskb eax, xmm0 not eax bsf eax, eax add CUR_CHAR, eax
4.1.3. .
—
.
—
.
—
.
, .
ZF=1
.
—
EAX
1
ZF=1
0
.
—
EAX
CUR_CHAR
.
cmp word ptr[CUR_CHAR - byte], 0A0Dh setz al add CUR_CHAR, eax
, .
4.1.4. .
—
.
—
.
—
:
EAX
.
—
ZF=1
EAX
0
.
—
ZF=1
:
movzx eax, byte ptr[CUR_CHAR] test al, al jz ErrorExit ;
4.2. .
4.2.1. .
—
.
—
.
—
.
, .
AL
.
—
AL
1
AL
0
.
—
EAX
CUR_CHAR
.
cmp al, '+' setz al add CUR_CHAR, eax
, .
4.2.2. .
—
.
—
.
—
.
—
.
,
, , .
, «» «» «» , , , .
.
—
AL
1
0
.
—
EAX
CUR_CHAR
.
—
EAX
ESP
.
cmp byte ptr[CUR_CHAR], '-' setz al add CUR_CHAR, eax add esp, eax
,
ESP
1
, , .
ESP
, «» «» «» , , , .
4.3. .
4.3.1. .
4.3.1.1. .
— , 16 ,
.
—
.
—
.
—
1.
,
.
0
.
—
1
2
.
—
0
9
.
—
0
1.
movdqu xmm0,[CUR_CHAR + xmmword] movdqa xmm2, xmm0 movdqa xmm3, xmm0 pcmpgtb xmm0, xmmword ptr Xmm_39 movdqa xmm1, xmm0
0
1
9
-1
,
0
.
4.3.1.2. .
—
,
,
.
—
.
,
,
.
2
,
2
0
-1
,
0
.
—
PANDN
0
AND
0
2
0
.
pcmpgtb xmm2, xmmword ptr Xmm_SL pandn xmm0, xmm2
0
0
9
,
,
-1
0
.
4.3.1.3. .
—
,
,
.
—
.
,
,
.
3
0
,
3
1
-1
,
0
.
—
PANDN
1
AND
1
3
1
.
pcmpgtb xmm3, xmmword ptr Xmm_30 pandn xmm1, xmm3
1
1
9
,
,
-1
0
.
4.3.1.4. .
—
.
—
16
16 ,
, 16
16 , ,
.
0
HASH_STR
.
—
1
N_Z_CHAR
pmovmskb HASH_STR, xmm0 pmovmskb N_Z_CHAR, xmm1
16
HASH_STR
16 ,
1
0
, 16
N_Z_CHAR
16 , ,
1
0
.
4.3.2. .
movdqu xmm0,[CUR_CHAR] movdqa xmm2, xmm0 movdqa xmm3, xmm0 pcmpgtb xmm0, xmmword ptr Xmm_39 movdqa xmm1, xmm0 pcmpgtb xmm2, xmmword ptr Xmm_SL pcmpgtb xmm3, xmmword ptr Xmm_30 pandn xmm0, xmm2 pandn xmm1, xmm3
4.3.3. .
—
.
— 16
.
—
.
—
.
— 16
.
—
.
, ,
,
, .
0
EAX
.
— 16
HASH_STR
HASH_STR
.
—
HASH_STR
EAX
.
—
1
EAX
.
— 16
N_Z_CHAR
N_Z_CHAR
.
—
N_Z_CHAR
EAX
.
pmovmskb eax, xmm0 shl HASH_STR, xmmword add HASH_STR, eax pmovmskb eax, xmm1 shl N_Z_CHAR, xmmword add N_Z_CHAR, eax
HASH_STR
1
0
, ,
N_Z_CHAR
1
,
0
, .
4.4. .
4.4.1. .
—
1,
.
—
.
—
.
—
.
.
,
,
,
.
HASH_STR
1,
EAX
ZF=1
.
—
ZF=1
.
—
ZF=0
.
—
ZF=0
.
bsf eax, HASH_STR jz ErrorExit test eax, eax jnz ErrorExit
.
BSF
,
1
0
BSF
0
ZF=0
,
1
,
ZF=1
.
4.4.2. .
—
.
—
,
.
—
.
—
.
—
.
HASH_STR
1
.
—
HASH_STR
,
DOT_CHAR
ZF=1
HASH_STR
.
—
ZF=1
.
—
ZF=0
.
—
ZF=0
.
not HASH_STR bsf DOT_CHAR, HASH_STR jz ErrorExit cmp byte ptr[CUR_CHAR + DOT_CHAR], '.' jnz ErrorExit
4.4.3. .
—
—
.
—
1 ()
.
—
,
, .
—
.
—
16 .
—
16 .
32
. .
N_Z_CHAR
EAX
—
N_Z_CHAR
.
—
0000
1 ()
BUFF_STR
.
—
0
,
N_Z_CHAR
, .
—
BUFF_STR
.
—
0
N_Z_CHAR
16 .
—
BUFF_STR
16 .
mov eax, N_Z_CHAR bsf N_Z_CHAR, N_Z_CHAR mov dword ptr[BUFF_STR - byte], 30303030h movdqu xmm0,[CUR_CHAR + N_Z_CHAR] movdqu [BUFF_STR + 00000000], xmm0 movdqu xmm0,[CUR_CHAR + N_Z_CHAR + xmmword] movdqu [BUFF_STR + 00000000 + xmmword], xmm0
32
N_Z_CHAR
BUFF_STR
. .
4.5. .
4.5.1. .
— , ,
.
— , ,
16
.
DOT_CHAR
0
.
— , ,
DOT_CHAR
16
1
.
movdqu xmm0,[CUR_CHAR + DOT_CHAR + byte] movdqu xmm1,[CUR_CHAR + DOT_CHAR + byte + xmmword]
4.5.2. .
—
, .
—
.
—
.
.
HASH_STR
DOT_CHAR
, .
—
HASH_STR
ZF=1
.
—
ZF=1
.
btr HASH_STR, DOT_CHAR bsf END_FRAC, HASH_STR jz ErrorExit
EXP_CHAR
.
4.5.3. .
4.5.3.1. .
—
.
—
.
,
,
.
END_FRAC
N_Z_CHAR
CF=1
N_Z_CHAR
END_FRAC
.
—
END_FRAC
N_Z_CHAR
CF=1
.
cmp END_FRAC, N_Z_CHAR cmovc N_Z_CHAR, END_FRAC
,
N_Z_CHAR
END_FRAC
,
N_Z_CHAR
END_FRAC
.
4.5.3.2. .
—
, , ,
.
—
.
—
.
, , .
N_Z_CHAR
DOT_CHAR
N_Z_CHAR
DOT_CHAR
, , ,
CF=1
.
—
LEN_NUMB
END_FRAC
.
—
LEN_NUMB
N_Z_CHAR
CF
.
cmp N_Z_CHAR, DOT_CHAR mov LEN_NUMB, END_FRAC sbb LEN_NUMB, N_Z_CHAR
LEN_NUMB
, , .
4.5.4. .
—
, .
—
.
—
.
—
.
—
16 , BUFF_STR
,
. «» , , .
DOT_CHAR
N_Z_CHAR
SF=0
, .
—
OFF_CHAR
20
.
—
SF=0
DOT_CHAR
OFF_CHAR
.
—
OFF_CHAR
BUFF_STR
.
—
OFF_CHAR
16 , BUFF_STR
sub DOT_CHAR, N_Z_CHAR mov OFF_CHAR, xmmword + dword cmovns OFF_CHAR, DOT_CHAR movdqu xmmword ptr[BUFF_STR + OFF_CHAR + 0000000], xmm0 movdqu xmmword ptr[BUFF_STR + OFF_CHAR + xmmword], xmm1
OFF_CHAR
,
OFF_CHAR
20
. «» , , .
4.5.5. .
—
.
—
.
—
16 ,
.
—
.
«» ,
,
. ,
.
.
2
.
—
LEN_NUMB
BUFF_STR
.
—
LEN_NUMB
16 ,
BUFF_STR
.
—
LEN_CELL
DOT_CHAR
.
movdqu xmm2, xmmword ptr Xmm_30 movdqu xmmword ptr[BUFF_STR + LEN_NUMB + 0000000], xmm2 movdqu xmmword ptr[BUFF_STR + LEN_NUMB + xmmword], xmm2 lea LEN_CELL, [DOT_CHAR * 2]
«» ,
,
LEN_NUMB
. ,
20
.
LEN_CELL
.
4.6. .
4.6.1. .
—
.
—
.
—
.
—
.
—
.
N_Z_CHAR
.
—
0
END_FRAC
.
—
END_FRAC
0
.
—
END_FRAC
0
.
—
0
1
.
xor N_Z_CHAR, N_Z_CHAR movd xmm0, dword ptr[CUR_CHAR + END_FRAC] pshuflw xmm0, xmm0, 0 pshufd xmm0, xmm0, 0 movdqa xmm1, xmm0
4.6.2. .
—
.
—
.
—
.
—
.
—
.
— ZF=0 .
0
-1
0
.
—
1
-1
0
.
—
0
1
0
.
—
1
1
-1
.
—
PTEST
AND
0
1
-1
ZF=0
.
— ZF=0 .
pcmpeqw xmm0, Mask_001 pcmpeqw xmm1, Mask_010 paddw xmm0, xmm1 pcmpeqb xmm1, xmm1 ptest xmm0, xmm1 jnz @f
4.6.3. .
—
.
—
.
—
EDX
END_FRAC
.
—
ZF=1
EDX
0
.
—
ZF=1[/INLINE .
movzx edx, word ptr[CUR_CHAR + END_FRAC]
test dl, dl
jz @f
4.7. .
4.7.1. .
—
.
—
.
—
.
5
EDX
.
—
ZF=0
EDX
.
—
ZF=0
.
btr edx, 5 cmp dl,'E' jnz ErrorExit
4.7.2.
4.7.2.1. .
—
,
.
—
.
—
,
/
.
—
.
—
.
. .
HASH_STR
EXP_CHAR
,
.
—
EXP_CHAR
1
.
—
HASH_STR
EXP_CHAR
,
/
CF=1
0
.
—
CF=1
EDX
Plus
.
—
EXP_CHAR
CF=1
.
btr HASH_STR, EXP_CHAR inc EXP_CHAR btr HASH_STR, EXP_CHAR cmovnc dx, Plus adc EXP_CHAR, 0
. .
4.7.2.2. .
—
.
—
.
—
.
—
.
—
.
—
.
—
.
—
,
.
ZF=1
DH
.
—
DL
1
ZF=1
.
—
ZF=1
DH
.
—
DH
1
ZF=1
.
—
8
DX
CF
.
—
LEN_CELL
CF
.
—
ZF=1
EDX
0
.
—
cmp dh,'+' setz dl cmp dh,'-' setz dh bt dx, 8 adc LEN_CELL, 0
LEN_CELL
,
LEN_CELL
.
4.7.3. .
—
—
.
—
.
—
, ,
.
—
.
—
EAX
N_Z_CHAR
N_Z_CHAR
EAX
4.4.3.
—
EAX
.
—
EAX
EXP_CHAR
.
—
EAX
, ,
-1
EAX
EXP_CHAR
1
0
.
—
EAX
1
.
—
mov N_Z_CHAR, eax xor eax, eax bts eax, EXP_CHAR add eax, -1 not eax and N_Z_CHAR, eax bsf N_Z_CHAR, N_Z_CHAR movdqu xmm0,[CUR_CHAR + N_Z_CHAR]
4.7.4. .
bsf END_CHAR, END_CHAR jz ErrorExit movzx eax, byte ptr[CUR_CHAR + END_CHAR] cmp eax, 20h ja ErrorExit add rdx,(1 + 1 shl 09h + 1 shl 0Dh + 1 shl 20h) bt rdx, rax jnc ErrorExit
4.8. - -
sub N_Z_CHAR, END_CHAR cmp N_Z_CHAR, -4 ; jnc ErrorExit @@: cmp byte ptr[BUFF_STR + 00000000 + xmmword + dword - byte],'5' mov dword ptr[BUFF_STR + 00000000 + xmmword + dword - byte],'0000' movd dword ptr[BUFF_STR + N_Z_CHAR + xmmword + qword - byte], xmm0
4.9.
; #region movdqu xmm0,[BUFF_STR + 0000000 - byte] movdqu xmm1,[BUFF_STR + xmmword - byte] psubb xmm0, xmm2 psubb xmm1, xmm2 pmaddubsw xmm1, xmmword ptr Xmm_0001 pmaddwd xmm1, xmmword ptr Xmm_0010 ; #endregion
4.10.
; #region movd rax, xmm1 sbb rax, -1 movd xmm1, eax shr rax, 20h movd xmm2, rbx mov ebx, eax neg eax sar LEN_CELL, 1 cmovc ebx, eax add ebx, LEN_CELL mov eax, ebx neg eax cmovns ebx, eax mov rax, 0A000000000000000h mov MANT_ARG, 0CCCCCCCCCCCCCCCCh cmovs MANT_ARG, rax mov eax, 3 mov LOGB_ARG, -3 cmovs LOGB_ARG, eax mov MANT_MUL, 1 mov LOGB_MUL, 0 shr HASH_MUL, 1 cmovc MANT_MUL, MANT_ARG cmovc LOGB_MUL, LOGB_ARG @@: jz @f mov rax, MANT_ARG mul rax bt rdx, 3Fh setnc cl adc LOGB_ARG, LOGB_ARG shld rdx, rax, cl mov MANT_ARG, rdx shr HASH_MUL, 1 jnc @b mov rax, rdx mul MANT_MUL bt rdx, 3Fh setnc cl adc LOGB_MUL, LOGB_ARG shld rdx, rax, cl mov MANT_MUL, rdx test HASH_MUL, HASH_MUL jmp @b @@: movd rbx, xmm2 ; #endregion
4.11. .
; #region psubb xmm0, xmm2 pmaddubsw xmm0, xmmword ptr Xmm_0001 pmaddwd xmm0, xmmword ptr Xmm_0010 pmulld xmm0, xmmword ptr Xmm_0100 phaddd xmm0, xmm0 movd eax, xmm0 imul rax, Mul_0001 pextrd edx, xmm0, 1 imul rdx, 02710h add rax, rdx movd edx, xmm1 add rax, rdx bsr rcx, rax add LOGB_MUL, ecx inc cl shrd rax, rax, cl ; #endregion
4.12. .
; #region mul MANT_MUL bt rdx, 3Fh setnc cl adc LOGB_MUL, 3FFh shld rdx, rax, cl shl rdx, 1 shrd rdx, r11, 11 shrd rdx, rsp, 1 btr esp, 0 movd xmm0, rdx ; #endregion
4.13. .
ret
4.14. ErrorExit
ErrorExit: ; #region mov ecx, -1 pcmpeqb xmm1, xmm1 psllq xmm1, 52 + 1 psrlq xmm1, 1 ret ; #endregion