public static bool TryParseInt32(ReadOnlySpan<byte> text, out int value, out int bytesConsumed)
{
int textLength = text.Length;
if (textLength < 1) goto FalseExit;
int sign = 1;
int index = default;
int num = text[index];
if (num == '-')
{
sign = -1;
index++;
if (index >= textLength) goto FalseExit;
num = text[index];
}
else if (num == '+')
{
index++;
if (index >= textLength) goto FalseExit;
num = text[index];
}
int answer = default;
if (IsDigit(num))
{
if (num == '0')
{
do
{
index++;
if (index >= textLength) goto Done;
num = text[index];
} while (num == '0');
if (!IsDigit(num)) goto Done;
}
int len = textLength - index;
if (len < Int32OverflowLength)
{
switch (len)
{
case 9:
answer = (num - '0');
index = textLength - 8;
num = text[index];
if (!IsDigit(num))
{
goto Done;
}
goto case 8;
case 8:
answer = answer * 10 + (num - '0');
index = textLength - 7;
num = text[index];
if (!IsDigit(num))
{
goto Done;
}
goto case 7;
case 7:
answer = answer * 10 + (num - '0');
index = textLength - 6;
num = text[index];
if (!IsDigit(num))
{
goto Done;
}
goto case 6;
case 6:
answer = answer * 10 + (num - '0');
index = textLength - 5;
num = text[index];
if (!IsDigit(num))
{
goto Done;
}
goto case 5;
case 5:
answer = answer * 10 + (num - '0');
index = textLength - 4;
num = text[index];
if (!IsDigit(num))
{
goto Done;
}
goto case 4;
case 4:
answer = answer * 10 + (num - '0');
index = textLength - 3;
num = text[index];
if (!IsDigit(num))
{
goto Done;
}
goto case 3;
case 3:
answer = answer * 10 + (num - '0');
index = textLength - 2;
num = text[index];
if (!IsDigit(num))
{
goto Done;
}
goto case 2;
case 2:
answer = answer * 10 + (num - '0');
index = textLength - 1;
num = text[index];
if (!IsDigit(num))
{
goto Done;
}
goto case 1;
case 1:
answer = answer * 10 + (num - '0');
index = textLength;
goto Done;
}
}
else if (len == Int32OverflowLength)
{
switch (Int32OverflowLength)
{
case 10:
answer = (num - '0');
num = text[textLength - 9];
if (!IsDigit(num))
{
index = index + Int32OverflowLength - 9;
goto Done;
}
goto case 9;
case 9:
answer = answer * 10 + (num - '0');
num = text[textLength - 8];
if (!IsDigit(num))
{
index = index + Int32OverflowLength - 8;
goto Done;
}
goto case 8;
case 8:
answer = answer * 10 + (num - '0');
num = text[textLength - 7];
if (!IsDigit(num))
{
index = index + Int32OverflowLength - 7;
goto Done;
}
goto case 7;
case 7:
answer = answer * 10 + (num - '0');
num = text[textLength - 6];
if (!IsDigit(num))
{
index = index + Int32OverflowLength - 6;
goto Done;
}
goto case 6;
case 6:
answer = answer * 10 + (num - '0');
num = text[textLength - 5];
if (!IsDigit(num))
{
index = index + Int32OverflowLength - 5;
goto Done;
}
goto case 5;
case 5:
answer = answer * 10 + (num - '0');
num = text[textLength - 4];
if (!IsDigit(num))
{
index = index + Int32OverflowLength - 4;
goto Done;
}
goto case 4;
case 4:
answer = answer * 10 + (num - '0');
num = text[textLength - 3];
if (!IsDigit(num))
{
index = index + Int32OverflowLength - 3;
goto Done;
}
goto case 3;
case 3:
answer = answer * 10 + (num - '0');
num = text[textLength - 2];
if (!IsDigit(num))
{
index = index + Int32OverflowLength - 2;
goto Done;
}
goto case 2;
case 2:
answer = answer * 10 + (num - '0');
num = text[textLength - 1];
if (!IsDigit(num))
{
index = index + Int32OverflowLength - 1;
goto Done;
}
goto case 1;
case 1:
num -= '0';
if (WillOverFlow(answer, num, sign)) goto FalseExit;
answer = answer * 10 + num;
index = index + Int32OverflowLength;
goto Done;
}
}
else
{
index += Int32OverflowLength;
switch (Int32OverflowLength)
{
case 10:
answer = (num - '0');
num = text[index - 9];
if (!IsDigit(num))
{
index -= 9;
goto Done;
}
goto case 9;
case 9:
answer = answer * 10 + (num - '0');
num = text[index - 8];
if (!IsDigit(num))
{
index -= 8;
goto Done;
}
goto case 8;
case 8:
answer = answer * 10 + (num - '0');
num = text[index - 7];
if (!IsDigit(num))
{
index -= 7;
goto Done;
}
goto case 7;
case 7:
answer = answer * 10 + (num - '0');
num = text[index - 6];
if (!IsDigit(num))
{
index -= 6;
goto Done;
}
goto case 6;
case 6:
answer = answer * 10 + (num - '0');
num = text[index - 5];
if (!IsDigit(num))
{
index -= 5;
goto Done;
}
goto case 5;
case 5:
answer = answer * 10 + (num - '0');
num = text[index - 4];
if (!IsDigit(num))
{
index -= 4;
goto Done;
}
goto case 4;
case 4:
answer = answer * 10 + (num - '0');
num = text[index - 3];
if (!IsDigit(num))
{
index -= 3;
goto Done;
}
goto case 3;
case 3:
answer = answer * 10 + (num - '0');
num = text[index - 2];
if (!IsDigit(num))
{
index -= 2;
goto Done;
}
goto case 2;
case 2:
answer = answer * 10 + (num - '0');
num = text[index - 1];
if (!IsDigit(num))
{
index -= 1;
goto Done;
}
goto case 1;
case 1:
num -= '0';
if (WillOverFlow(answer, num, sign) || IsDigit(text[index])) goto FalseExit;
answer = answer * 10 + num;
goto Done;
}
}
goto Done;
}
FalseExit:
bytesConsumed = default;
value = default;
return false;
Done:
bytesConsumed = index;
value = answer * sign;
return true;
}
Last active
June 24, 2017 04:23
-
-
Save ahsonkhan/dba0afb3304de15be844111d0f8a3ea6 to your computer and use it in GitHub Desktop.
Loop unrolled int 32 parser
Disassembly
x86:
Current (no branch) - A:
int textLength = text.Length;
04BB1610 push ebp
04BB1611 mov ebp,esp
04BB1613 push edi
04BB1614 push esi
04BB1615 push ebx
04BB1616 sub esp,30h
04BB1619 mov dword ptr [ebp-30h],ecx
04BB161C mov dword ptr [ebp-34h],edx
04BB161F mov edi,dword ptr [ebp+0Ch]
04BB1622 mov ebx,edi
if (textLength < 1) goto FalseExit;
04BB1624 test ebx,ebx
04BB1626 jle 04BB18FA
int sign = 1;
04BB162C mov dword ptr [ebp-10h],1
int index = 0;
04BB1633 xor edx,edx
int num = text[index];
04BB1635 cmp edi,0
int num = text[index];
04BB1638 jbe 04BB1943
04BB163E mov ecx,dword ptr [ebp+8]
04BB1641 movzx eax,byte ptr [ecx]
if (num == '-')
04BB1644 cmp eax,2Dh
04BB1647 jne 04BB166D
{
sign = -1;
04BB1649 mov dword ptr [ebp-10h],0FFFFFFFFh
index++;
04BB1650 mov edx,1
if (index >= textLength) goto FalseExit;
04BB1655 cmp ebx,1
04BB1658 jle 04BB18FA
num = text[index];
04BB165E cmp edi,1
04BB1661 jbe 04BB1943
04BB1667 movzx eax,byte ptr [ecx+1]
04BB166B jmp 04BB168D
else if (num == '+')
04BB166D cmp eax,2Bh
04BB1670 jne 04BB168D
{
index++;
04BB1672 mov edx,1
if (index >= textLength) goto FalseExit;
04BB1677 cmp ebx,1
04BB167A jle 04BB18FA
num = text[index];
04BB1680 cmp edi,1
04BB1683 jbe 04BB1943
04BB1689 movzx eax,byte ptr [ecx+1]
}
int answer = 0;
04BB168D xor esi,esi
04BB168F mov dword ptr [ebp-1Ch],esi
04BB1692 lea esi,[eax-30h]
04BB1695 cmp esi,9
04BB1698 ja 04BB18FA
{
if (num == '0')
04BB169E cmp eax,30h
04BB16A1 jne 04BB16C9
{
do
{
index++;
04BB16A3 inc edx
if (index >= textLength) goto Done;
04BB16A4 cmp edx,ebx
if (index >= textLength) goto Done;
04BB16A6 jge 04BB1923
num = text[index];
04BB16AC cmp edx,edi
04BB16AE jae 04BB1943
04BB16B4 movzx eax,byte ptr [ecx+edx]
} while (num == '0');
04BB16B8 cmp eax,30h
04BB16BB je 04BB16A3
04BB16BD lea esi,[eax-30h]
04BB16C0 cmp esi,9
04BB16C3 ja 04BB1923
}
answer = num - '0';
04BB16C9 lea esi,[eax-30h]
04BB16CC mov dword ptr [ebp-1Ch],esi
index++;
04BB16CF inc edx
if (index >= textLength) goto Done;
04BB16D0 cmp edx,ebx
04BB16D2 jge 04BB1923
num = text[index];
04BB16D8 cmp edx,edi
04BB16DA jae 04BB1943
04BB16E0 movzx eax,byte ptr [ecx+edx]
04BB16E4 lea esi,[eax-30h]
04BB16E7 cmp esi,9
04BB16EA ja 04BB1923
index++;
04BB16F0 inc edx
answer = 10 * answer + num - '0';
04BB16F1 mov esi,dword ptr [ebp-1Ch]
04BB16F4 lea esi,[esi+esi*4]
04BB16F7 lea esi,[eax+esi*2-30h]
04BB16FB mov dword ptr [ebp-1Ch],esi
if (index >= textLength) goto Done;
04BB16FE cmp edx,ebx
04BB1700 jge 04BB1923
num = text[index];
04BB1706 cmp edx,edi
04BB1708 jae 04BB1943
04BB170E movzx eax,byte ptr [ecx+edx]
04BB1712 lea esi,[eax-30h]
04BB1715 cmp esi,9
04BB1718 ja 04BB1923
index++;
04BB171E inc edx
answer = 10 * answer + num - '0';
04BB171F mov esi,dword ptr [ebp-1Ch]
04BB1722 lea esi,[esi+esi*4]
04BB1725 lea esi,[eax+esi*2-30h]
04BB1729 mov dword ptr [ebp-1Ch],esi
if (index >= textLength) goto Done;
04BB172C cmp edx,ebx
04BB172E jge 04BB1923
num = text[index];
04BB1734 cmp edx,edi
04BB1736 jae 04BB1943
04BB173C movzx eax,byte ptr [ecx+edx]
04BB1740 lea esi,[eax-30h]
04BB1743 cmp esi,9
04BB1746 ja 04BB1923
index++;
04BB174C inc edx
answer = 10 * answer + num - '0';
04BB174D mov esi,dword ptr [ebp-1Ch]
04BB1750 lea esi,[esi+esi*4]
04BB1753 lea esi,[eax+esi*2-30h]
04BB1757 mov dword ptr [ebp-1Ch],esi
if (index >= textLength) goto Done;
04BB175A cmp edx,ebx
04BB175C jge 04BB1923
num = text[index];
04BB1762 cmp edx,edi
04BB1764 jae 04BB1943
04BB176A movzx eax,byte ptr [ecx+edx]
04BB176E lea esi,[eax-30h]
04BB1771 cmp esi,9
04BB1774 ja 04BB1923
index++;
04BB177A inc edx
answer = 10 * answer + num - '0';
04BB177B mov esi,dword ptr [ebp-1Ch]
04BB177E lea esi,[esi+esi*4]
04BB1781 lea esi,[eax+esi*2-30h]
04BB1785 mov dword ptr [ebp-1Ch],esi
if (index >= textLength) goto Done;
04BB1788 cmp edx,ebx
04BB178A jge 04BB1923
num = text[index];
04BB1790 cmp edx,edi
04BB1792 jae 04BB1943
04BB1798 movzx eax,byte ptr [ecx+edx]
04BB179C lea esi,[eax-30h]
04BB179F cmp esi,9
04BB17A2 ja 04BB1923
index++;
04BB17A8 inc edx
answer = 10 * answer + num - '0';
04BB17A9 mov esi,dword ptr [ebp-1Ch]
04BB17AC lea esi,[esi+esi*4]
04BB17AF lea esi,[eax+esi*2-30h]
04BB17B3 mov dword ptr [ebp-1Ch],esi
if (index >= textLength) goto Done;
04BB17B6 cmp edx,ebx
04BB17B8 jge 04BB1923
num = text[index];
04BB17BE cmp edx,edi
04BB17C0 jae 04BB1943
04BB17C6 movzx eax,byte ptr [ecx+edx]
04BB17CA lea esi,[eax-30h]
04BB17CD cmp esi,9
04BB17D0 ja 04BB1923
index++;
04BB17D6 inc edx
answer = 10 * answer + num - '0';
04BB17D7 mov esi,dword ptr [ebp-1Ch]
04BB17DA lea esi,[esi+esi*4]
04BB17DD lea esi,[eax+esi*2-30h]
04BB17E1 mov dword ptr [ebp-1Ch],esi
if (index >= textLength) goto Done;
04BB17E4 cmp edx,ebx
04BB17E6 jge 04BB1923
num = text[index];
04BB17EC cmp edx,edi
04BB17EE jae 04BB1943
04BB17F4 movzx eax,byte ptr [ecx+edx]
04BB17F8 lea esi,[eax-30h]
04BB17FB cmp esi,9
04BB17FE ja 04BB1923
index++;
04BB1804 inc edx
answer = 10 * answer + num - '0';
04BB1805 mov esi,dword ptr [ebp-1Ch]
04BB1808 lea esi,[esi+esi*4]
04BB180B lea esi,[eax+esi*2-30h]
04BB180F mov dword ptr [ebp-1Ch],esi
if (index >= textLength) goto Done;
04BB1812 cmp edx,ebx
04BB1814 jge 04BB1923
num = text[index];
04BB181A cmp edx,edi
04BB181C jae 04BB1943
04BB1822 movzx eax,byte ptr [ecx+edx]
04BB1826 lea esi,[eax-30h]
04BB1829 cmp esi,9
04BB182C ja 04BB1923
index++;
04BB1832 inc edx
answer = 10 * answer + num - '0';
04BB1833 mov esi,dword ptr [ebp-1Ch]
04BB1836 lea esi,[esi+esi*4]
04BB1839 lea esi,[eax+esi*2-30h]
04BB183D mov dword ptr [ebp-1Ch],esi
// Potential overflow
if (index >= textLength) goto Done;
04BB1840 cmp edx,ebx
04BB1842 jge 04BB1923
num = text[index];
04BB1848 cmp edx,edi
04BB184A jae 04BB1943
04BB1850 mov dword ptr [ebp-14h],edx
04BB1853 movzx eax,byte ptr [ecx+edx]
04BB1857 mov dword ptr [ebp-18h],eax
04BB185A lea esi,[eax-30h]
04BB185D cmp esi,9
04BB1860 ja 04BB191E
long lAnswer = (long)answer * 10 + num - '0';
04BB1866 mov esi,0Ah
04BB186B mov dword ptr [ebp-3Ch],esi
04BB186E mov esi,dword ptr [ebp-1Ch]
04BB1871 mov eax,esi
04BB1873 imul dword ptr [ebp-3Ch]
04BB1876 mov dword ptr [ebp-2Ch],eax
04BB1879 mov dword ptr [ebp-28h],edx
04BB187C mov esi,dword ptr [ebp-18h]
04BB187F mov eax,esi
04BB1881 mov edx,eax
04BB1883 sar edx,1Fh
04BB1886 add eax,dword ptr [ebp-2Ch]
04BB1889 adc edx,dword ptr [ebp-28h]
04BB188C mov esi,eax
04BB188E sub esi,30h
04BB1891 mov eax,edx
04BB1893 sbb eax,0
04BB1896 mov dword ptr [ebp-20h],esi
04BB1899 mov dword ptr [ebp-24h],eax
if (lAnswer > (long)Int32.MaxValue + (-1 * sign + 1) / 2) goto FalseExit;
04BB189C mov edx,dword ptr [ebp-10h]
04BB189F mov eax,edx
04BB18A1 neg eax
04BB18A3 inc eax
04BB18A4 mov esi,eax
04BB18A6 shr esi,1Fh
04BB18A9 add esi,eax
04BB18AB mov eax,esi
04BB18AD sar eax,1
04BB18AF mov esi,eax
04BB18B1 sar esi,1Fh
04BB18B4 add eax,7FFFFFFFh
04BB18B9 adc esi,0
04BB18BC cmp esi,dword ptr [ebp-24h]
04BB18BF jg 04BB18D9
04BB18C1 mov dword ptr [ebp-38h],ecx
04BB18C4 mov dword ptr [ebp-10h],edx
04BB18C7 jl 04BB18FA
04BB18C9 mov edx,dword ptr [ebp-20h]
04BB18CC cmp eax,edx
04BB18CE mov dword ptr [ebp-20h],edx
04BB18D1 mov ecx,dword ptr [ebp-38h]
04BB18D4 jb 04BB18FA
04BB18D6 mov edx,dword ptr [ebp-10h]
answer = (int)lAnswer;
04BB18D9 mov esi,dword ptr [ebp-20h]
index++;
04BB18DC mov eax,dword ptr [ebp-14h]
04BB18DF inc eax
if (index >= textLength) goto Done;
04BB18E0 cmp eax,ebx
04BB18E2 jge 04BB1914
if (!IsDigit(text[index])) goto Done;
04BB18E4 cmp eax,edi
04BB18E6 jae 04BB1943
04BB18E8 movzx ecx,byte ptr [ecx+eax]
04BB18EC add ecx,0FFFFFFD0h
04BB18EF cmp ecx,9
04BB18F2 mov dword ptr [ebp-1Ch],esi
04BB18F5 mov dword ptr [ebp-10h],edx
04BB18F8 ja 04BB1910
// Guaranteed overflow
goto FalseExit;
}
FalseExit:
bytesConsumed = default;
04BB18FA xor eax,eax
04BB18FC mov esi,dword ptr [ebp-34h]
04BB18FF mov dword ptr [esi],eax
value = default;
04BB1901 mov ecx,dword ptr [ebp-30h]
04BB1904 mov dword ptr [ecx],eax
04BB1906 lea esp,[ebp-0Ch]
04BB1909 pop ebx
04BB190A pop esi
04BB190B pop edi
04BB190C pop ebp
04BB190D ret 8
04BB1910 mov edx,eax
04BB1912 jmp 04BB1923
04BB1914 mov dword ptr [ebp-1Ch],esi
04BB1917 mov dword ptr [ebp-10h],edx
04BB191A mov edx,eax
04BB191C jmp 04BB1923
04BB191E mov edx,dword ptr [ebp-14h]
04BB1921 jmp 04BB1923
Done:
bytesConsumed = index;
04BB1923 mov esi,dword ptr [ebp-34h]
04BB1926 mov dword ptr [esi],edx
value = answer * sign;
04BB1928 mov esi,dword ptr [ebp-1Ch]
04BB192B imul esi,dword ptr [ebp-10h]
04BB192F mov ecx,dword ptr [ebp-30h]
04BB1932 mov dword ptr [ecx],esi
return true;
04BB1934 mov eax,1
04BB1939 lea esp,[ebp-0Ch]
04BB193C pop ebx
04BB193D pop esi
04BB193E pop edi
04BB193F pop ebp
04BB1940 ret 8
04BB1943 call 0FC6C4D0
04BB1948 int 3
Current (with branch) - D:
int textLength = text.Length;
04BB1960 push ebp
04BB1961 mov ebp,esp
04BB1963 push edi
04BB1964 push esi
04BB1965 push ebx
04BB1966 sub esp,2Ch
04BB1969 mov dword ptr [ebp-2Ch],ecx
04BB196C mov dword ptr [ebp-30h],edx
04BB196F mov edi,dword ptr [ebp+0Ch]
04BB1972 mov ebx,edi
if (textLength < 1) goto FalseExit;
04BB1974 test ebx,ebx
04BB1976 jle 04BB1C4D
int sign = 1;
04BB197C mov dword ptr [ebp-10h],1
int index = 0;
04BB1983 xor edx,edx
int num = text[index];
04BB1985 cmp edi,0
int num = text[index];
04BB1988 jbe 04BB1C91
04BB198E mov ecx,dword ptr [ebp+8]
04BB1991 movzx eax,byte ptr [ecx]
if (num == '-')
04BB1994 cmp eax,2Dh
04BB1997 jne 04BB19BD
{
sign = -1;
04BB1999 mov dword ptr [ebp-10h],0FFFFFFFFh
index++;
04BB19A0 mov edx,1
if (index >= textLength) goto FalseExit;
04BB19A5 cmp ebx,1
04BB19A8 jle 04BB1C4D
num = text[index];
04BB19AE cmp edi,1
04BB19B1 jbe 04BB1C91
04BB19B7 movzx eax,byte ptr [ecx+1]
04BB19BB jmp 04BB19DD
else if (num == '+')
04BB19BD cmp eax,2Bh
04BB19C0 jne 04BB19DD
{
index++;
04BB19C2 mov edx,1
if (index >= textLength) goto FalseExit;
04BB19C7 cmp ebx,1
04BB19CA jle 04BB1C4D
num = text[index];
04BB19D0 cmp edi,1
04BB19D3 jbe 04BB1C91
04BB19D9 movzx eax,byte ptr [ecx+1]
}
int answer = 0;
04BB19DD xor esi,esi
04BB19DF mov dword ptr [ebp-1Ch],esi
04BB19E2 lea esi,[eax-30h]
04BB19E5 cmp esi,9
04BB19E8 ja 04BB1C4D
{
if (num == '0')
04BB19EE cmp eax,30h
04BB19F1 jne 04BB1A19
{
do
{
index++;
04BB19F3 inc edx
if (index >= textLength) goto Done;
04BB19F4 cmp edx,ebx
if (index >= textLength) goto Done;
04BB19F6 jge 04BB1C71
num = text[index];
04BB19FC cmp edx,edi
04BB19FE jae 04BB1C91
04BB1A04 movzx eax,byte ptr [ecx+edx]
} while (num == '0');
04BB1A08 cmp eax,30h
04BB1A0B je 04BB19F3
04BB1A0D lea esi,[eax-30h]
04BB1A10 cmp esi,9
04BB1A13 ja 04BB1C71
}
answer = num - '0';
04BB1A19 lea esi,[eax-30h]
04BB1A1C mov dword ptr [ebp-1Ch],esi
index++;
04BB1A1F inc edx
if (index >= textLength) goto Done;
04BB1A20 cmp edx,ebx
04BB1A22 jge 04BB1C71
num = text[index];
04BB1A28 cmp edx,edi
04BB1A2A jae 04BB1C91
04BB1A30 movzx eax,byte ptr [ecx+edx]
04BB1A34 lea esi,[eax-30h]
04BB1A37 cmp esi,9
04BB1A3A ja 04BB1C71
index++;
04BB1A40 inc edx
answer = 10 * answer + num - 48;
04BB1A41 mov esi,dword ptr [ebp-1Ch]
04BB1A44 lea esi,[esi+esi*4]
04BB1A47 lea esi,[eax+esi*2-30h]
04BB1A4B mov dword ptr [ebp-1Ch],esi
if (index >= textLength) goto Done;
04BB1A4E cmp edx,ebx
04BB1A50 jge 04BB1C71
num = text[index];
04BB1A56 cmp edx,edi
04BB1A58 jae 04BB1C91
04BB1A5E movzx eax,byte ptr [ecx+edx]
04BB1A62 lea esi,[eax-30h]
04BB1A65 cmp esi,9
04BB1A68 ja 04BB1C71
index++;
04BB1A6E inc edx
answer = 10 * answer + num - 48;
04BB1A6F mov esi,dword ptr [ebp-1Ch]
04BB1A72 lea esi,[esi+esi*4]
04BB1A75 lea esi,[eax+esi*2-30h]
04BB1A79 mov dword ptr [ebp-1Ch],esi
if (index >= textLength) goto Done;
04BB1A7C cmp edx,ebx
04BB1A7E jge 04BB1C71
num = text[index];
04BB1A84 cmp edx,edi
04BB1A86 jae 04BB1C91
04BB1A8C movzx eax,byte ptr [ecx+edx]
04BB1A90 lea esi,[eax-30h]
04BB1A93 cmp esi,9
04BB1A96 ja 04BB1C71
index++;
04BB1A9C inc edx
answer = 10 * answer + num - 48;
04BB1A9D mov esi,dword ptr [ebp-1Ch]
04BB1AA0 lea esi,[esi+esi*4]
04BB1AA3 lea esi,[eax+esi*2-30h]
04BB1AA7 mov dword ptr [ebp-1Ch],esi
if (index >= textLength) goto Done;
04BB1AAA cmp edx,ebx
04BB1AAC jge 04BB1C71
num = text[index];
04BB1AB2 cmp edx,edi
04BB1AB4 jae 04BB1C91
04BB1ABA movzx eax,byte ptr [ecx+edx]
04BB1ABE lea esi,[eax-30h]
04BB1AC1 cmp esi,9
04BB1AC4 ja 04BB1C71
index++;
04BB1ACA inc edx
answer = 10 * answer + num - '0';
04BB1ACB mov esi,dword ptr [ebp-1Ch]
04BB1ACE lea esi,[esi+esi*4]
04BB1AD1 lea esi,[eax+esi*2-30h]
04BB1AD5 mov dword ptr [ebp-1Ch],esi
if (index >= textLength) goto Done;
04BB1AD8 cmp edx,ebx
04BB1ADA jge 04BB1C71
num = text[index];
04BB1AE0 cmp edx,edi
04BB1AE2 jae 04BB1C91
04BB1AE8 movzx eax,byte ptr [ecx+edx]
04BB1AEC lea esi,[eax-30h]
04BB1AEF cmp esi,9
04BB1AF2 ja 04BB1C71
index++;
04BB1AF8 inc edx
answer = 10 * answer + num - '0';
04BB1AF9 mov esi,dword ptr [ebp-1Ch]
04BB1AFC lea esi,[esi+esi*4]
04BB1AFF lea esi,[eax+esi*2-30h]
04BB1B03 mov dword ptr [ebp-1Ch],esi
if (index >= textLength) goto Done;
04BB1B06 cmp edx,ebx
04BB1B08 jge 04BB1C71
num = text[index];
04BB1B0E cmp edx,edi
04BB1B10 jae 04BB1C91
04BB1B16 movzx eax,byte ptr [ecx+edx]
04BB1B1A lea esi,[eax-30h]
04BB1B1D cmp esi,9
04BB1B20 ja 04BB1C71
index++;
04BB1B26 inc edx
answer = 10 * answer + num - '0';
04BB1B27 mov esi,dword ptr [ebp-1Ch]
04BB1B2A lea esi,[esi+esi*4]
04BB1B2D lea esi,[eax+esi*2-30h]
04BB1B31 mov dword ptr [ebp-1Ch],esi
if (index >= textLength) goto Done;
04BB1B34 cmp edx,ebx
04BB1B36 jge 04BB1C71
num = text[index];
04BB1B3C cmp edx,edi
04BB1B3E jae 04BB1C91
04BB1B44 movzx eax,byte ptr [ecx+edx]
04BB1B48 lea esi,[eax-30h]
04BB1B4B cmp esi,9
04BB1B4E ja 04BB1C71
index++;
04BB1B54 inc edx
answer = 10 * answer + num - '0';
04BB1B55 mov esi,dword ptr [ebp-1Ch]
04BB1B58 lea esi,[esi+esi*4]
04BB1B5B lea esi,[eax+esi*2-30h]
04BB1B5F mov dword ptr [ebp-1Ch],esi
if (index >= textLength) goto Done;
04BB1B62 cmp edx,ebx
04BB1B64 jge 04BB1C71
num = text[index];
04BB1B6A cmp edx,edi
04BB1B6C jae 04BB1C91
04BB1B72 movzx eax,byte ptr [ecx+edx]
04BB1B76 lea esi,[eax-30h]
04BB1B79 cmp esi,9
04BB1B7C ja 04BB1C71
index++;
04BB1B82 inc edx
answer = 10 * answer + num - '0';
04BB1B83 mov esi,dword ptr [ebp-1Ch]
04BB1B86 lea esi,[esi+esi*4]
04BB1B89 lea esi,[eax+esi*2-30h]
04BB1B8D mov dword ptr [ebp-1Ch],esi
// Potential overflow
if (index >= textLength) goto Done;
04BB1B90 cmp edx,ebx
04BB1B92 jge 04BB1C71
num = text[index];
04BB1B98 cmp edx,edi
04BB1B9A jae 04BB1C91
04BB1BA0 mov dword ptr [ebp-14h],edx
04BB1BA3 movzx eax,byte ptr [ecx+edx]
04BB1BA7 mov dword ptr [ebp-18h],eax
04BB1BAA lea esi,[eax-30h]
04BB1BAD cmp esi,9
04BB1BB0 ja 04BB1C0F
long lAnswer = (long)answer * 10 + num - '0';
04BB1BB2 mov esi,0Ah
04BB1BB7 mov dword ptr [ebp-38h],esi
04BB1BBA mov esi,dword ptr [ebp-1Ch]
04BB1BBD mov eax,esi
04BB1BBF imul dword ptr [ebp-38h]
04BB1BC2 mov dword ptr [ebp-28h],eax
04BB1BC5 mov dword ptr [ebp-24h],edx
04BB1BC8 mov esi,dword ptr [ebp-18h]
04BB1BCB mov eax,esi
04BB1BCD mov edx,eax
04BB1BCF sar edx,1Fh
04BB1BD2 add eax,dword ptr [ebp-28h]
04BB1BD5 adc edx,dword ptr [ebp-24h]
04BB1BD8 mov esi,eax
04BB1BDA sub esi,30h
04BB1BDD mov eax,edx
04BB1BDF sbb eax,0
if (sign < 0)
04BB1BE2 mov edx,dword ptr [ebp-10h]
04BB1BE5 test edx,edx
04BB1BE7 jge 04BB1C14
{
if (lAnswer > (long)Int32.MaxValue + 1) goto FalseExit;
04BB1BE9 test eax,eax
04BB1BEB mov dword ptr [ebp-10h],edx
04BB1BEE mov dword ptr [ebp-20h],esi
04BB1BF1 jg 04BB1C4D
04BB1BF3 mov eax,ecx
04BB1BF5 mov edx,dword ptr [ebp-14h]
04BB1BF8 mov dword ptr [ebp-14h],edx
04BB1BFB mov ecx,eax
04BB1BFD mov edx,dword ptr [ebp-10h]
04BB1C00 mov esi,dword ptr [ebp-20h]
04BB1C03 jl 04BB1C2F
04BB1C05 cmp esi,80000000h
04BB1C0B jbe 04BB1C2F
04BB1C0D jmp 04BB1C4D
04BB1C0F mov edx,dword ptr [ebp-14h]
04BB1C12 jmp 04BB1C71
}
else
{
if (lAnswer > Int32.MaxValue) goto FalseExit;
04BB1C14 test eax,eax
04BB1C16 jl 04BB1C2F
04BB1C18 mov dword ptr [ebp-34h],ecx
04BB1C1B mov dword ptr [ebp-20h],esi
04BB1C1E jg 04BB1C4D
04BB1C20 mov eax,dword ptr [ebp-20h]
04BB1C23 cmp eax,7FFFFFFFh
04BB1C28 mov esi,eax
04BB1C2A mov ecx,dword ptr [ebp-34h]
04BB1C2D ja 04BB1C4D
}
answer = (int)lAnswer;
04BB1C2F mov eax,dword ptr [ebp-14h]
04BB1C32 inc eax
if (index >= textLength) goto Done;
04BB1C33 cmp eax,ebx
04BB1C35 jge 04BB1C67
if (!IsDigit(text[index])) goto Done;
04BB1C37 cmp eax,edi
04BB1C39 jae 04BB1C91
04BB1C3B movzx ecx,byte ptr [ecx+eax]
04BB1C3F add ecx,0FFFFFFD0h
04BB1C42 cmp ecx,9
04BB1C45 mov dword ptr [ebp-1Ch],esi
04BB1C48 mov dword ptr [ebp-10h],edx
04BB1C4B ja 04BB1C63
// Guaranteed overflow
goto FalseExit;
}
FalseExit:
bytesConsumed = default;
04BB1C4D xor eax,eax
04BB1C4F mov esi,dword ptr [ebp-30h]
04BB1C52 mov dword ptr [esi],eax
value = default;
04BB1C54 mov ecx,dword ptr [ebp-2Ch]
04BB1C57 mov dword ptr [ecx],eax
04BB1C59 lea esp,[ebp-0Ch]
04BB1C5C pop ebx
04BB1C5D pop esi
04BB1C5E pop edi
04BB1C5F pop ebp
04BB1C60 ret 8
04BB1C63 mov edx,eax
04BB1C65 jmp 04BB1C71
04BB1C67 mov dword ptr [ebp-1Ch],esi
04BB1C6A mov dword ptr [ebp-10h],edx
04BB1C6D mov edx,eax
04BB1C6F jmp 04BB1C71
Done:
bytesConsumed = index;
04BB1C71 mov esi,dword ptr [ebp-30h]
04BB1C74 mov dword ptr [esi],edx
value = answer * sign;
04BB1C76 mov esi,dword ptr [ebp-1Ch]
04BB1C79 imul esi,dword ptr [ebp-10h]
04BB1C7D mov ecx,dword ptr [ebp-2Ch]
04BB1C80 mov dword ptr [ecx],esi
return true;
04BB1C82 mov eax,1
04BB1C87 lea esp,[ebp-0Ch]
04BB1C8A pop ebx
04BB1C8B pop esi
04BB1C8C pop edi
04BB1C8D pop ebp
04BB1C8E ret 8
04BB1C91 call 0FC6C4D0
04BB1C96 int 3
Combined (no branch) - B:
int textLength = text.Length;
04BB1CA8 push ebp
04BB1CA9 mov ebp,esp
04BB1CAB push edi
04BB1CAC push esi
04BB1CAD push ebx
04BB1CAE sub esp,24h
04BB1CB1 mov dword ptr [ebp-24h],ecx
04BB1CB4 mov dword ptr [ebp-28h],edx
04BB1CB7 mov esi,dword ptr [ebp+0Ch]
04BB1CBA mov edi,esi
if (textLength < 1) goto FalseExit;
04BB1CBC test edi,edi
04BB1CBE jle 04BB1F64
int sign = 1;
04BB1CC4 mov ebx,1
int index = 0;
04BB1CC9 xor eax,eax
int num = text[index];
04BB1CCB cmp esi,0
int num = text[index];
04BB1CCE jbe 04BB1FA7
04BB1CD4 mov ecx,dword ptr [ebp+8]
04BB1CD7 movzx edx,byte ptr [ecx]
if (num == '-')
04BB1CDA cmp edx,2Dh
04BB1CDD jne 04BB1D03
{
sign = -1;
04BB1CDF mov dword ptr [ebp-10h],0FFFFFFFFh
index++;
04BB1CE6 mov eax,1
if (index >= textLength) goto FalseExit;
04BB1CEB cmp edi,1
04BB1CEE jle 04BB1F64
num = text[index];
04BB1CF4 cmp esi,1
04BB1CF7 jbe 04BB1FA7
04BB1CFD movzx edx,byte ptr [ecx+1]
04BB1D01 jmp 04BB1D2A
else if (num == '+')
04BB1D03 cmp edx,2Bh
04BB1D06 jne 04BB1F7F
{
index++;
04BB1D0C mov eax,1
if (index >= textLength) goto FalseExit;
04BB1D11 cmp edi,1
04BB1D14 jle 04BB1F64
num = text[index];
04BB1D1A cmp esi,1
04BB1D1D jbe 04BB1FA7
04BB1D23 movzx edx,byte ptr [ecx+1]
04BB1D27 mov dword ptr [ebp-10h],ebx
}
int answer = 0;
04BB1D2A xor ebx,ebx
04BB1D2C mov dword ptr [ebp-14h],ebx
04BB1D2F lea ebx,[edx-30h]
04BB1D32 cmp ebx,9
04BB1D35 ja 04BB1F64
{
if (num == '0')
04BB1D3B cmp edx,30h
04BB1D3E jne 04BB1D66
{
do
{
index++;
04BB1D40 inc eax
if (index >= textLength) goto Done;
04BB1D41 cmp eax,edi
04BB1D43 jge 04BB1F87
num = text[index];
04BB1D49 cmp eax,esi
04BB1D4B jae 04BB1FA7
04BB1D51 movzx edx,byte ptr [ecx+eax]
} while (num == '0');
04BB1D55 cmp edx,30h
04BB1D58 je 04BB1D40
04BB1D5A lea ebx,[edx-30h]
04BB1D5D cmp ebx,9
04BB1D60 ja 04BB1F87
}
answer = num - '0';
04BB1D66 lea ebx,[edx-30h]
04BB1D69 mov dword ptr [ebp-14h],ebx
index++;
04BB1D6C inc eax
if (index >= textLength) goto Done;
04BB1D6D cmp eax,edi
04BB1D6F jge 04BB1F87
num = text[index];
04BB1D75 cmp eax,esi
04BB1D77 jae 04BB1FA7
04BB1D7D movzx edx,byte ptr [ecx+eax]
04BB1D81 lea ebx,[edx-30h]
04BB1D84 cmp ebx,9
04BB1D87 ja 04BB1F87
index++;
04BB1D8D inc eax
answer = 10 * answer + num - '0';
04BB1D8E mov ebx,dword ptr [ebp-14h]
answer = 10 * answer + num - '0';
04BB1D91 lea ebx,[ebx+ebx*4]
04BB1D94 lea ebx,[edx+ebx*2-30h]
04BB1D98 mov dword ptr [ebp-14h],ebx
if (index >= textLength) goto Done;
04BB1D9B cmp eax,edi
04BB1D9D jge 04BB1F87
num = text[index];
04BB1DA3 cmp eax,esi
04BB1DA5 jae 04BB1FA7
04BB1DAB movzx edx,byte ptr [ecx+eax]
04BB1DAF lea ebx,[edx-30h]
04BB1DB2 cmp ebx,9
04BB1DB5 ja 04BB1F87
index++;
04BB1DBB inc eax
answer = 10 * answer + num - '0';
04BB1DBC mov ebx,dword ptr [ebp-14h]
04BB1DBF lea ebx,[ebx+ebx*4]
04BB1DC2 lea ebx,[edx+ebx*2-30h]
04BB1DC6 mov dword ptr [ebp-14h],ebx
if (index >= textLength) goto Done;
04BB1DC9 cmp eax,edi
04BB1DCB jge 04BB1F87
num = text[index];
04BB1DD1 cmp eax,esi
04BB1DD3 jae 04BB1FA7
04BB1DD9 movzx edx,byte ptr [ecx+eax]
04BB1DDD lea ebx,[edx-30h]
04BB1DE0 cmp ebx,9
04BB1DE3 ja 04BB1F87
index++;
04BB1DE9 inc eax
answer = 10 * answer + num - '0';
04BB1DEA mov ebx,dword ptr [ebp-14h]
04BB1DED lea ebx,[ebx+ebx*4]
04BB1DF0 lea ebx,[edx+ebx*2-30h]
04BB1DF4 mov dword ptr [ebp-14h],ebx
if (index >= textLength) goto Done;
04BB1DF7 cmp eax,edi
04BB1DF9 jge 04BB1F87
num = text[index];
04BB1DFF cmp eax,esi
04BB1E01 jae 04BB1FA7
04BB1E07 movzx edx,byte ptr [ecx+eax]
04BB1E0B lea ebx,[edx-30h]
04BB1E0E cmp ebx,9
04BB1E11 ja 04BB1F87
index++;
04BB1E17 inc eax
answer = 10 * answer + num - '0';
04BB1E18 mov ebx,dword ptr [ebp-14h]
04BB1E1B lea ebx,[ebx+ebx*4]
04BB1E1E lea ebx,[edx+ebx*2-30h]
04BB1E22 mov dword ptr [ebp-14h],ebx
if (index >= textLength) goto Done;
04BB1E25 cmp eax,edi
04BB1E27 jge 04BB1F87
num = text[index];
04BB1E2D cmp eax,esi
04BB1E2F jae 04BB1FA7
04BB1E35 movzx edx,byte ptr [ecx+eax]
04BB1E39 lea ebx,[edx-30h]
04BB1E3C cmp ebx,9
04BB1E3F ja 04BB1F87
index++;
04BB1E45 inc eax
answer = 10 * answer + num - '0';
04BB1E46 mov ebx,dword ptr [ebp-14h]
04BB1E49 lea ebx,[ebx+ebx*4]
04BB1E4C lea ebx,[edx+ebx*2-30h]
04BB1E50 mov dword ptr [ebp-14h],ebx
if (index >= textLength) goto Done;
04BB1E53 cmp eax,edi
04BB1E55 jge 04BB1F87
num = text[index];
04BB1E5B cmp eax,esi
04BB1E5D jae 04BB1FA7
04BB1E63 movzx edx,byte ptr [ecx+eax]
04BB1E67 lea ebx,[edx-30h]
04BB1E6A cmp ebx,9
04BB1E6D ja 04BB1F87
index++;
04BB1E73 inc eax
answer = 10 * answer + num - '0';
04BB1E74 mov ebx,dword ptr [ebp-14h]
04BB1E77 lea ebx,[ebx+ebx*4]
04BB1E7A lea ebx,[edx+ebx*2-30h]
04BB1E7E mov dword ptr [ebp-14h],ebx
if (index >= textLength) goto Done;
04BB1E81 cmp eax,edi
if (index >= textLength) goto Done;
04BB1E83 jge 04BB1F87
num = text[index];
04BB1E89 cmp eax,esi
04BB1E8B jae 04BB1FA7
04BB1E91 movzx edx,byte ptr [ecx+eax]
04BB1E95 lea ebx,[edx-30h]
04BB1E98 cmp ebx,9
04BB1E9B ja 04BB1F87
index++;
04BB1EA1 inc eax
answer = 10 * answer + num - '0';
04BB1EA2 mov ebx,dword ptr [ebp-14h]
04BB1EA5 lea ebx,[ebx+ebx*4]
04BB1EA8 lea ebx,[edx+ebx*2-30h]
04BB1EAC mov dword ptr [ebp-14h],ebx
if (index >= textLength) goto Done;
04BB1EAF cmp eax,edi
04BB1EB1 jge 04BB1F87
num = text[index];
04BB1EB7 cmp eax,esi
04BB1EB9 jae 04BB1FA7
04BB1EBF movzx edx,byte ptr [ecx+eax]
04BB1EC3 lea ebx,[edx-30h]
04BB1EC6 cmp ebx,9
04BB1EC9 ja 04BB1F87
index++;
04BB1ECF inc eax
answer = 10 * answer + num - '0';
04BB1ED0 mov ebx,dword ptr [ebp-14h]
04BB1ED3 lea ebx,[ebx+ebx*4]
04BB1ED6 lea ebx,[edx+ebx*2-30h]
04BB1EDA mov dword ptr [ebp-14h],ebx
// Potential overflow
if (index >= textLength) goto Done;
04BB1EDD cmp eax,edi
04BB1EDF jge 04BB1F87
num = text[index];
04BB1EE5 cmp eax,esi
04BB1EE7 jae 04BB1FA7
04BB1EED movzx edx,byte ptr [ecx+eax]
04BB1EF1 lea ebx,[edx-30h]
04BB1EF4 cmp ebx,9
04BB1EF7 ja 04BB1F87
if (answer > Int32.MaxValue / 10 + 1) goto FalseExit; // Overflow
04BB1EFD mov ebx,dword ptr [ebp-14h]
04BB1F00 cmp ebx,0CCCCCCDh
04BB1F06 jg 04BB1F64
answer = answer * 10 + num - '0';
04BB1F08 lea ebx,[ebx+ebx*4]
04BB1F0B lea ebx,[edx+ebx*2-30h]
if ((uint)answer > (uint)Int32.MaxValue + (-1 * sign + 1) / 2) goto FalseExit; // Overflow
04BB1F0F mov edx,dword ptr [ebp-10h]
04BB1F12 neg edx
04BB1F14 inc edx
04BB1F15 mov dword ptr [ebp-1Ch],edx
04BB1F18 shr edx,1Fh
04BB1F1B add edx,dword ptr [ebp-1Ch]
04BB1F1E sar edx,1
04BB1F20 mov dword ptr [ebp-18h],edx
04BB1F23 sar edx,1Fh
04BB1F26 mov dword ptr [ebp-30h],edx
04BB1F29 mov edx,dword ptr [ebp-18h]
04BB1F2C add edx,7FFFFFFFh
04BB1F32 mov dword ptr [ebp-20h],edx
04BB1F35 mov edx,dword ptr [ebp-30h]
04BB1F38 adc edx,0
04BB1F3B test edx,edx
04BB1F3D jg 04BB1F4C
04BB1F3F mov dword ptr [ebp-2Ch],ecx
04BB1F42 jl 04BB1F64
04BB1F44 cmp dword ptr [ebp-20h],ebx
04BB1F47 mov ecx,dword ptr [ebp-2Ch]
04BB1F4A jb 04BB1F64
index++;
04BB1F4C inc eax
if (index >= textLength) goto Done;
04BB1F4D cmp eax,edi
04BB1F4F jge 04BB1F7A
if (!IsDigit(text[index])) goto Done;
04BB1F51 cmp eax,esi
04BB1F53 jae 04BB1FA7
04BB1F55 movzx ecx,byte ptr [ecx+eax]
04BB1F59 add ecx,0FFFFFFD0h
04BB1F5C cmp ecx,9
04BB1F5F mov dword ptr [ebp-14h],ebx
04BB1F62 ja 04BB1F87
// Guaranteed overflow
goto FalseExit;
}
FalseExit:
bytesConsumed = default;
04BB1F64 xor eax,eax
04BB1F66 mov edx,dword ptr [ebp-28h]
04BB1F69 mov dword ptr [edx],eax
value = default;
04BB1F6B mov ecx,dword ptr [ebp-24h]
04BB1F6E mov dword ptr [ecx],eax
04BB1F70 lea esp,[ebp-0Ch]
04BB1F73 pop ebx
04BB1F74 pop esi
04BB1F75 pop edi
04BB1F76 pop ebp
04BB1F77 ret 8
04BB1F7A mov dword ptr [ebp-14h],ebx
04BB1F7D jmp 04BB1F87
04BB1F7F mov dword ptr [ebp-10h],ebx
04BB1F82 jmp 04BB1D2A
Done:
bytesConsumed = index;
04BB1F87 mov edx,dword ptr [ebp-28h]
04BB1F8A mov dword ptr [edx],eax
value = answer * sign;
04BB1F8C mov ebx,dword ptr [ebp-14h]
04BB1F8F imul ebx,dword ptr [ebp-10h]
04BB1F93 mov ecx,dword ptr [ebp-24h]
04BB1F96 mov dword ptr [ecx],ebx
return true;
04BB1F98 mov eax,1
return true;
04BB1F9D lea esp,[ebp-0Ch]
04BB1FA0 pop ebx
04BB1FA1 pop esi
04BB1FA2 pop edi
04BB1FA3 pop ebp
04BB1FA4 ret 8
04BB1FA7 call 0FC6C4D0
04BB1FAC int 3
Combined (branch) - C:
int textLength = text.Length;
04BB1FC0 push ebp
04BB1FC1 mov ebp,esp
04BB1FC3 push edi
04BB1FC4 push esi
04BB1FC5 push ebx
04BB1FC6 sub esp,10h
04BB1FC9 mov dword ptr [ebp-18h],ecx
04BB1FCC mov dword ptr [ebp-1Ch],edx
04BB1FCF mov eax,dword ptr [ebp+0Ch]
04BB1FD2 mov esi,eax
if (textLength < 1) goto FalseExit;
04BB1FD4 test esi,esi
04BB1FD6 jle 04BB225F
int sign = 1;
04BB1FDC mov edi,1
int index = 0;
04BB1FE1 xor ebx,ebx
int num = text[index];
04BB1FE3 cmp eax,0
int num = text[index];
04BB1FE6 jbe 04BB229D
04BB1FEC mov ecx,dword ptr [ebp+8]
04BB1FEF movzx edx,byte ptr [ecx]
if (num == '-')
04BB1FF2 cmp edx,2Dh
04BB1FF5 jne 04BB201B
{
sign = -1;
04BB1FF7 mov dword ptr [ebp-10h],0FFFFFFFFh
index++;
04BB1FFE mov ebx,1
if (index >= textLength) goto FalseExit;
04BB2003 cmp esi,1
04BB2006 jle 04BB225F
num = text[index];
04BB200C cmp eax,1
04BB200F jbe 04BB229D
04BB2015 movzx edx,byte ptr [ecx+1]
04BB2019 jmp 04BB2042
else if (num == '+')
04BB201B cmp edx,2Bh
04BB201E jne 04BB2234
{
index++;
04BB2024 mov ebx,1
if (index >= textLength) goto FalseExit;
04BB2029 cmp esi,1
04BB202C jle 04BB225F
num = text[index];
04BB2032 cmp eax,1
04BB2035 jbe 04BB229D
04BB203B movzx edx,byte ptr [ecx+1]
04BB203F mov dword ptr [ebp-10h],edi
}
int answer = 0;
04BB2042 xor edi,edi
04BB2044 mov dword ptr [ebp-14h],edi
04BB2047 lea edi,[edx-30h]
04BB204A cmp edi,9
04BB204D ja 04BB225F
{
if (num == '0')
04BB2053 cmp edx,30h
04BB2056 jne 04BB207E
{
do
{
index++;
04BB2058 inc ebx
if (index >= textLength) goto Done;
04BB2059 cmp ebx,esi
04BB205B jge 04BB227D
num = text[index];
04BB2061 cmp ebx,eax
04BB2063 jae 04BB229D
04BB2069 movzx edx,byte ptr [ecx+ebx]
} while (num == '0');
04BB206D cmp edx,30h
04BB2070 je 04BB2058
04BB2072 lea edi,[edx-30h]
04BB2075 cmp edi,9
04BB2078 ja 04BB227D
}
answer = num - '0';
04BB207E lea edi,[edx-30h]
04BB2081 mov dword ptr [ebp-14h],edi
index++;
04BB2084 inc ebx
if (index >= textLength) goto Done;
04BB2085 cmp ebx,esi
04BB2087 jge 04BB227D
num = text[index];
04BB208D cmp ebx,eax
04BB208F jae 04BB229D
04BB2095 movzx edx,byte ptr [ecx+ebx]
04BB2099 lea edi,[edx-30h]
04BB209C cmp edi,9
04BB209F ja 04BB227D
index++;
04BB20A5 inc ebx
answer = 10 * answer + num - '0';
04BB20A6 mov edi,dword ptr [ebp-14h]
answer = 10 * answer + num - '0';
04BB20A9 lea edi,[edi+edi*4]
04BB20AC lea edi,[edx+edi*2-30h]
04BB20B0 mov dword ptr [ebp-14h],edi
if (index >= textLength) goto Done;
04BB20B3 cmp ebx,esi
04BB20B5 jge 04BB227D
num = text[index];
04BB20BB cmp ebx,eax
04BB20BD jae 04BB229D
04BB20C3 movzx edx,byte ptr [ecx+ebx]
04BB20C7 lea edi,[edx-30h]
04BB20CA cmp edi,9
04BB20CD ja 04BB227D
index++;
04BB20D3 inc ebx
answer = 10 * answer + num - '0';
04BB20D4 mov edi,dword ptr [ebp-14h]
04BB20D7 lea edi,[edi+edi*4]
04BB20DA lea edi,[edx+edi*2-30h]
04BB20DE mov dword ptr [ebp-14h],edi
if (index >= textLength) goto Done;
04BB20E1 cmp ebx,esi
04BB20E3 jge 04BB227D
num = text[index];
04BB20E9 cmp ebx,eax
04BB20EB jae 04BB229D
04BB20F1 movzx edx,byte ptr [ecx+ebx]
04BB20F5 lea edi,[edx-30h]
04BB20F8 cmp edi,9
04BB20FB ja 04BB227D
index++;
04BB2101 inc ebx
answer = 10 * answer + num - '0';
04BB2102 mov edi,dword ptr [ebp-14h]
04BB2105 lea edi,[edi+edi*4]
04BB2108 lea edi,[edx+edi*2-30h]
04BB210C mov dword ptr [ebp-14h],edi
if (index >= textLength) goto Done;
04BB210F cmp ebx,esi
04BB2111 jge 04BB227D
num = text[index];
04BB2117 cmp ebx,eax
04BB2119 jae 04BB229D
04BB211F movzx edx,byte ptr [ecx+ebx]
04BB2123 lea edi,[edx-30h]
04BB2126 cmp edi,9
04BB2129 ja 04BB227D
index++;
04BB212F inc ebx
answer = 10 * answer + num - '0';
04BB2130 mov edi,dword ptr [ebp-14h]
04BB2133 lea edi,[edi+edi*4]
04BB2136 lea edi,[edx+edi*2-30h]
04BB213A mov dword ptr [ebp-14h],edi
if (index >= textLength) goto Done;
04BB213D cmp ebx,esi
04BB213F jge 04BB227D
num = text[index];
04BB2145 cmp ebx,eax
04BB2147 jae 04BB229D
04BB214D movzx edx,byte ptr [ecx+ebx]
04BB2151 lea edi,[edx-30h]
04BB2154 cmp edi,9
04BB2157 ja 04BB227D
index++;
04BB215D inc ebx
answer = 10 * answer + num - '0';
04BB215E mov edi,dword ptr [ebp-14h]
04BB2161 lea edi,[edi+edi*4]
04BB2164 lea edi,[edx+edi*2-30h]
04BB2168 mov dword ptr [ebp-14h],edi
if (index >= textLength) goto Done;
04BB216B cmp ebx,esi
04BB216D jge 04BB227D
num = text[index];
04BB2173 cmp ebx,eax
04BB2175 jae 04BB229D
04BB217B movzx edx,byte ptr [ecx+ebx]
04BB217F lea edi,[edx-30h]
04BB2182 cmp edi,9
04BB2185 ja 04BB227D
index++;
04BB218B inc ebx
answer = 10 * answer + num - '0';
04BB218C mov edi,dword ptr [ebp-14h]
04BB218F lea edi,[edi+edi*4]
04BB2192 lea edi,[edx+edi*2-30h]
04BB2196 mov dword ptr [ebp-14h],edi
if (index >= textLength) goto Done;
04BB2199 cmp ebx,esi
if (index >= textLength) goto Done;
04BB219B jge 04BB227D
num = text[index];
04BB21A1 cmp ebx,eax
04BB21A3 jae 04BB229D
04BB21A9 movzx edx,byte ptr [ecx+ebx]
04BB21AD lea edi,[edx-30h]
04BB21B0 cmp edi,9
04BB21B3 ja 04BB227D
index++;
04BB21B9 inc ebx
answer = 10 * answer + num - '0';
04BB21BA mov edi,dword ptr [ebp-14h]
04BB21BD lea edi,[edi+edi*4]
04BB21C0 lea edi,[edx+edi*2-30h]
04BB21C4 mov dword ptr [ebp-14h],edi
if (index >= textLength) goto Done;
04BB21C7 cmp ebx,esi
04BB21C9 jge 04BB227D
num = text[index];
04BB21CF cmp ebx,eax
04BB21D1 jae 04BB229D
04BB21D7 movzx edx,byte ptr [ecx+ebx]
04BB21DB lea edi,[edx-30h]
04BB21DE cmp edi,9
04BB21E1 ja 04BB227D
index++;
04BB21E7 inc ebx
answer = 10 * answer + num - '0';
04BB21E8 mov edi,dword ptr [ebp-14h]
04BB21EB lea edi,[edi+edi*4]
04BB21EE lea edi,[edx+edi*2-30h]
04BB21F2 mov dword ptr [ebp-14h],edi
// Potential overflow
if (index >= textLength) goto Done;
04BB21F5 cmp ebx,esi
04BB21F7 jge 04BB227D
num = text[index];
04BB21FD cmp ebx,eax
04BB21FF jae 04BB229D
04BB2205 movzx edx,byte ptr [ecx+ebx]
04BB2209 lea edi,[edx-30h]
04BB220C cmp edi,9
04BB220F ja 04BB227D
if (answer > Int32.MaxValue / 10 + 1) goto FalseExit; // Overflow
04BB2211 mov edi,dword ptr [ebp-14h]
04BB2214 cmp edi,0CCCCCCDh
04BB221A jg 04BB225F
answer = answer * 10 + num - '0';
04BB221C lea edi,[edi+edi*4]
04BB221F lea edi,[edx+edi*2-30h]
if (sign < 0)
04BB2223 mov edx,dword ptr [ebp-10h]
04BB2226 test edx,edx
04BB2228 jge 04BB223C
{
if ((uint)answer > (uint)Int32.MaxValue + 1) goto FalseExit; // Overflow
04BB222A cmp edi,80000000h
04BB2230 jbe 04BB2244
04BB2232 jmp 04BB225F
04BB2234 mov dword ptr [ebp-10h],edi
04BB2237 jmp 04BB2042
}
else
{
if ((uint)answer > Int32.MaxValue) goto FalseExit; // Overflow
04BB223C cmp edi,7FFFFFFFh
04BB2242 ja 04BB225F
}
index++;
04BB2244 inc ebx
if (index >= textLength) goto Done;
04BB2245 cmp ebx,esi
04BB2247 jge 04BB2275
if (!IsDigit(text[index])) goto Done;
04BB2249 cmp ebx,eax
04BB224B jae 04BB229D
04BB224D movzx eax,byte ptr [ecx+ebx]
04BB2251 add eax,0FFFFFFD0h
04BB2254 cmp eax,9
04BB2257 mov dword ptr [ebp-14h],edi
04BB225A mov dword ptr [ebp-10h],edx
04BB225D ja 04BB227D
// Guaranteed overflow
goto FalseExit;
}
FalseExit:
bytesConsumed = default;
04BB225F xor eax,eax
04BB2261 mov edx,dword ptr [ebp-1Ch]
04BB2264 mov dword ptr [edx],eax
value = default;
04BB2266 mov ecx,dword ptr [ebp-18h]
04BB2269 mov dword ptr [ecx],eax
04BB226B lea esp,[ebp-0Ch]
04BB226E pop ebx
04BB226F pop esi
04BB2270 pop edi
04BB2271 pop ebp
04BB2272 ret 8
04BB2275 mov dword ptr [ebp-14h],edi
04BB2278 mov dword ptr [ebp-10h],edx
04BB227B jmp 04BB227D
Done:
bytesConsumed = index;
04BB227D mov edx,dword ptr [ebp-1Ch]
04BB2280 mov dword ptr [edx],ebx
value = answer * sign;
04BB2282 mov edi,dword ptr [ebp-14h]
04BB2285 imul edi,dword ptr [ebp-10h]
04BB2289 mov ecx,dword ptr [ebp-18h]
04BB228C mov dword ptr [ecx],edi
return true;
04BB228E mov eax,1
04BB2293 lea esp,[ebp-0Ch]
04BB2296 pop ebx
04BB2297 pop esi
04BB2298 pop edi
04BB2299 pop ebp
04BB229A ret 8
04BB229D call 0FC6C4D0
04BB22A2 int 3
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
cc @jkotas
Different Implementations
Current (no branch) - A:
Current (with branch) - D:
Combined (no branch) - B:
Combined (branch) - C:
Performance Results
Disassembly
x64:
Current (no branch) - A:
Current (with branch) - D:
Combined (no branch) - B:
Combined (branch) - C: