我有一个以ASCII存储在内存中的数字,并希望将其转换为二进制值(乘以100)。
所以1.23可以用ASCII格式存储在内存中,格式为0x312E3233,这应该转换为二进制值123.
我目前有以下内容,但有更有效的方法吗?
mov eax,[esi]
xor eax, 0x302E3030
mov edx, eax
and edx, 0x000000FF
shr eax,8
jz skip
mov ecx,eax
and ecx, 0x000000FF
imul ecx, 10
add edx, ecx
shr eax,8
jz skip
shr eax,8
imul eax,100
add edx, eax
skip:
ascii源由esi。
引用在标签"跳过"时,edx具有二进制值。
答案 0 :(得分:2)
如果例程可以使用零值,则最好不要包括那些条件跳转。 BSWAP应该比移位2倍快.IMUL可以改为LEA / ADD组合。
mov eax,[esi]
mov edx,eax
and edx,0x0000000F
mov ecx,eax
shr ecx,8
and ecx,0x0000000F
;;;imul ecx,10
lea ecx,[ecx+ecx*4]
add ecx,ecx
add edx,ecx
bswap eax
and eax,0x0000000F
;;;imul eax,100
lea eax,[eax+eax*4]
add eax,eax
lea eax,[eax+eax*4]
add eax,eax
add edx,eax
skip:
编辑
原始问题从未说过输入范围是[0.00,1.00]。 实际上给出的例子( 1.23 )超出了这个范围,所以我理解了整个范围是隐含的。这是我不再包括那些条件跳跃的主要原因。
在实际地址模式下测试Pentium 133上的每个人的代码都会显示这些执行时间。
sudhanshu bahuguna Rudy Velthuis user3144770
[0.00,9.99] 19.640 sec 18.921 sec 19.161 sec
[0.00,1.00] 13.244 sec 11.460 sec 19.161 sec
经过多次测试后,我发现用着名的LEA / ADD组合代替imul ecx,10
是非常有利可图的。另一方面,替换imul eax,100
会使事情变得更糟(大约相同的数量)。我意识到,考虑到有限的输入范围,最后jz skip
是至关重要的。所以我在两个答案中都介绍了所有这些发现并获得了这些执行时间。
sudhanshu bahuguna Rudy Velthuis (2) user3144770 (2)
[0.00,9.99] 19.640 sec 17.843 sec 17.364 sec
[0.00,1.00] 13.244 sec 11.448 sec 12.035 sec
仍然没有被这些结果所淹没,我想出了一个更快的解决方案,总是在9.580秒内执行。
movzx eax, byte [esi+3]
add eax,eax
lea eax,[eax+eax*4-480]
add al,[esi+1]
add eax,eax
lea eax,[eax+eax*4-480]
movzx edx, byte [esi]
lea edx,[eax+edx-48]
答案 1 :(得分:0)
一些简单的事情可以改善这一点。摆脱相对较慢的imul
并使用lea
和add
:
mov eax,[esi]
xor eax,0x302E3030
mov edx,eax
jz skip
and edx,0x000000FF
shr eax,8
jz skip
mov ecx,eax
and ecx,0x000000FF
lea ecx,[ecx+4*ecx]
add ecx,ecx
add edx,ecx
shr eax,8
jz skip
shr eax,8
lea eax,[eax+4*eax]
lea eax,[eax+4*eax]
add eax,eax
add eax,eax
add edx,eax
skip:
在现代处理器上,它可能并没有产生巨大的差异,但它仍然应该引人注目。