Hello everyone,
I found a procedure which converts dwords to ascii charachters. But I couldnt understand it(especially the codes between the dashed lines).
Could someone explain it to me?
dwtoa proc dwValue:DWORD, lpBuffer:DWORD
push ebx
push esi
push edi
mov eax, dwValue
mov edi,
test eax,eax
jnz sign
zero:
mov word ptr ,30h
jmp dtaexit
sign:
jns pos
mov byte ptr ,'-'
neg eax
add edi, 1
;-------------------------------\
pos:
mov ecx, 3435973837 ; what is this number for?
mov esi, edi
.while (eax > 0)
mov ebx,eax
mul ecx
shr edx, 3
mov eax,edx
lea edx,
add edx,edx
sub ebx,edx
add bl,'0'
mov ,bl
add edi, 1
.endw
-----------------------------------/
mov byte ptr ,
.while (esi < edi)
sub edi, 1
mov al,
mov ah,
mov , al
mov , ah
add esi, 1
.endw
dtaexit:
pop edi
pop esi
pop ebx
ret
dwtoa endp
Thanks.
I found a procedure which converts dwords to ascii charachters. But I couldnt understand it(especially the codes between the dashed lines).
Could someone explain it to me?
dwtoa proc dwValue:DWORD, lpBuffer:DWORD
push ebx
push esi
push edi
mov eax, dwValue
mov edi,
test eax,eax
jnz sign
zero:
mov word ptr ,30h
jmp dtaexit
sign:
jns pos
mov byte ptr ,'-'
neg eax
add edi, 1
;-------------------------------\
pos:
mov ecx, 3435973837 ; what is this number for?
mov esi, edi
.while (eax > 0)
mov ebx,eax
mul ecx
shr edx, 3
mov eax,edx
lea edx,
add edx,edx
sub ebx,edx
add bl,'0'
mov ,bl
add edi, 1
.endw
-----------------------------------/
mov byte ptr ,
.while (esi < edi)
sub edi, 1
mov al,
mov ah,
mov , al
mov , ah
add esi, 1
.endw
dtaexit:
pop edi
pop esi
pop ebx
ret
dwtoa endp
Thanks.
pos:
mov ecx, 0CCCCCCCDh ; = 8 * 1/10
mov ecx, 0CCCCCCCDh ; = 8 * 1/10
Down to the "pos:" label, it prints a "-" if the number is negative (and makes that number positive).
Then, keeps in ECX the value 8 * 2^32 / 10 . It'll be later used as fast division by 10, by simple multiplication with ECX: "mul ecx | shr edx,3". Notice that after "mul", the EDX part of the 64-bit result is taken.
The "lea edx, | add edx,edx" part is just multiplying EDX by 10.
So basically this segment:
means
EBX = EAX % 10;
EAX = EAX / 10;
Notice though, that this calculates the digits in reverse. So, if dwValue=123456, then right now lpBuffer="654321". The ".while (esi < edi)" loop reverses the string to appear correctly.
Then, keeps in ECX the value 8 * 2^32 / 10 . It'll be later used as fast division by 10, by simple multiplication with ECX: "mul ecx | shr edx,3". Notice that after "mul", the EDX part of the 64-bit result is taken.
The "lea edx, | add edx,edx" part is just multiplying EDX by 10.
So basically this segment:
mov ebx,eax
mul ecx
shr edx, 3
mov eax,edx
lea edx,
add edx,edx
sub ebx,edx
means
EBX = EAX % 10;
EAX = EAX / 10;
Notice though, that this calculates the digits in reverse. So, if dwValue=123456, then right now lpBuffer="654321". The ".while (esi < edi)" loop reverses the string to appear correctly.
Find Agner Fog's Optimization manual (Optimizing subroutines in assembly language An optimization guide for x86 platforms.pdf). The February 13th 2008 edition, page 120, the division by a constant value is explained. The header of the subject is (Integer division by a constant (all processors)).
Find Agner Fog's Optimization manual (Optimizing subroutines in assembly language An optimization guide for x86 platforms.pdf). The February 13th 2008 edition, page 120, the division by a constant value is explained. The header of the subject is (Integer division by a constant (all processors)).
Here is a good place to start your search for that optimization manual:
http://www.freetechbooks.com/about330.html
Hi Ultrano,
Could u pls expand your explanations(the theory behind the algo in a plain language)?
And XCHG i had a look at that optimization manual but it is not explanatory for me :)
Thanks.
Could u pls expand your explanations(the theory behind the algo in a plain language)?
And XCHG i had a look at that optimization manual but it is not explanatory for me :)
Thanks.