I seem to have difficulties to interpret the MasmLib help correctly. When I pass a string starting with a minus sign to atol and atodw, I get rubbish:
Positive, atodw: 12345
Positive, atol: 12345
Negative, atodw: 25312345
Negative, atol: -112345
Any explanation for this?
Thanks,
jj
include \masm32\include\masm32rt.inc
.code
StrPos db "12345", 0
StrNeg db "-12345", 0
start:
print "Positive, atodw: ", 9
invoke atodw, offset StrPos
print str$(eax), 13, 10
print "Positive, atol: ", 9
invoke atol, offset StrPos
print str$(eax), 13, 10
print "Negative, atodw: ", 9
invoke atodw, offset StrNeg
print str$(eax), 13, 10
print "Negative, atol: ", 9
invoke atol, offset StrNeg
print str$(eax), 13, 10
getkey
exit
end start
Running your code unchanged, atol works properly for me.
Clearly, atodw is not meant for signed strings, and should be documented as such.
atodw proc:
cmp al, 2D
jne proceed
should be 2DH or
cmp al, '-'
Quote from: Jimg on April 15, 2009, 02:51:33 PM
Running your code unchanged, atol works properly for me.
I get an extra 1:
Negative, atol: -112345My atol.asm has 1327 bytes, 13.08.2006
EDIT: Ze bug is here:
atol proc lpSrc:DWORD
xor eax, eax ; zero EAX
mov edx, [esp+4]
movzx ecx, BYTE PTR [edx]
add edx, 1
cmp ecx, "-" ; test for sign
jne lbl0
add eax, 1 ; set EAX if sign
if 1 ;
corrected movzx ecx, BYTE PTR [edx+1]
add edx, 2
else ;
original movzx ecx, BYTE PTR [edx]
add edx, 1
endif
lbl0:
push eax ; store sign on stack
...
Mine is 1445 bytes from 28 may 2008.
Time to update.
It still works and looks like-
atol proc lpSrc:DWORD
xor eax, eax ; zero EAX
mov edx, [esp+4]
movzx ecx, BYTE PTR [edx]
add edx, 1
cmp ecx, "-" ; test for sign
jne lbl0
add eax, 1 ; set EAX if sign
movzx ecx, BYTE PTR [edx]
add edx, 1
lbl0:
push eax ; store sign on stack
xor eax, eax ; so eax*10 will be 0 for first digit
lbl1:
sub ecx, 48
jc lbl2
lea eax, [eax+eax*4] ; mul eax by 5
lea eax, [ecx+eax*2] ; mul eax by 2 and add digit value
movzx ecx, BYTE PTR [edx] ; get next digit
add edx, 1
jmp lbl1
lbl2:
pop ecx ; retrieve sign
test ecx, ecx
jnz lbl3
ret 4
lbl3:
neg eax ; negative return value is sign set
ret 4
atol endp
Good catch Drizz, (and jj). Hard to believe it's been around this long with that error.
Very nice catch, JJ. I think it needs to be fixed via the next service pack. I guess not many people have been passing negative numbers to that algo else it may have been caught sooner. You are a very meticulous individual.
Paul
These are my results here :
Positive, atodw: 12345
Positive, atol: 12345
Negative, atodw: 25312345
Negative, atol: -12345
I found a newer version on my other machine...
Just for fun:
Intel(R) Celeron(R) M CPU 420 @ 1.60GHz (SSE3)
31 cycles for atodjj, offset StrNeg
45 cycles for atol, offset StrNeg
31 cycles for atodjj, offset StrNeg
45 cycles for atol, offset StrNeg
31 cycles for atodjj, offset StrPos
57 cycles for atol, offset StrPos
45 cycles for atodw, offset StrPos
31 cycles for atodjj, offset StrPos
57 cycles for atol, offset StrPos
43 cycles for atodw, offset StrPos
Positive, atodw: 123456789
Positive, atol: 123456789
Positive, atodjj: 123456789
Negative, atol: -123456789
Negative, atodjj: -123456789
Code sizes:
atodjj: 58
atol: 61
a2dw: 71
EDIT: A bit of shuffling, an unrolled loop - and voilà, it's speeding up :bg
[attachment deleted by admin]
New results: :lol
Intel(R) Core(TM)2 Duo CPU E8500 @ 3.16GHz (SSE4)
22 cycles for atodjj, offset StrNeg
18 cycles for a2dLingo, offset StrNeg
40 cycles for atol, offset StrNeg
22 cycles for atodjj, offset StrNeg
18 cycles for a2dLingo, offset StrNeg
40 cycles for atol, offset StrNeg
22 cycles for atodjj, offset StrPos
18 cycles for a2dLingo, offset StrPos
38 cycles for atol, offset StrPos
39 cycles for atodw, offset StrPos
22 cycles for atodjj, offset StrPos
18 cycles for a2dLingo, offset StrPos
38 cycles for atol, offset StrPos
42 cycles for atodw, offset StrPos
Positive, atodw: 123456789
Positive, a2dLingo: 123456789
Positive, atol: 123456789
Positive, atodjj: 123456789
Negative, atol: -123456789
Negative, atodjj: -123456789
Negative, a2dLingo: -123456789
Code sizes:
atodjj: 58
a2dLingo: 113
atol: 61
a2dw: 71
[attachment deleted by admin]
Not bad, my young friend, although it's a bit bloated, and on my archaic CPU it's on average a cycle slower :green
:U
Intel(R) Pentium(R) 4 CPU 3.40GHz (SSE3)
57 cycles for atodjj, offset StrNeg
54 cycles for a2dLingo, offset StrNeg
52 cycles for atol, offset StrNeg
53 cycles for atodjj, offset StrNeg
54 cycles for a2dLingo, offset StrNeg
52 cycles for atol, offset StrNeg
51 cycles for atodjj, offset StrPos
53 cycles for a2dLingo, offset StrPos
52 cycles for atol, offset StrPos
59 cycles for atodw, offset StrPos
51 cycles for atodjj, offset StrPos
55 cycles for a2dLingo, offset StrPos
52 cycles for atol, offset StrPos
59 cycles for atodw, offset StrPos
Positive, atodw: 123456789
Positive, a2dLingo: 123456789
Positive, atol: 123456789
Positive, atodjj: 123456789
Negative, atol: -123456789
Negative, atodjj: -123456789
Negative, a2dLingo: -123456789
Code sizes:
atodjj: 58
a2dLingo: 113
atol: 61
a2dw: 71
I split this topic and put the parts that definitely do not belong in the Campus here:
http://www.masm32.com/board/index.php?topic=11280.0