The Fed doesn't pay me enough to put up with this, but ok... here is byte code for x86 that translates either a decimal or hexadecimal string to a binary value (yes, I actually wrote the byte code, and yes, I can read and write x86 machine encodings in hex):
31C053515657555231F68A0280F8307C1080F8397F0B2C3083C6015083C201EBE9C7C50A000000C 7C10100000031DB89F783FE00741058F7E101C383EE0189C8F7E589C1EBEB89D85A01FA5D5F5E59 5BC331C053515657555231F68A0280F8307C0980F8397F042C30EB0C80F8417C1080F8467F0B2C4 B83C6015083C201EBDBC7C510000000EB9F
The decimal reader is at offset 0 and expects a non-digit terminated string at an address in the EDX register. The hex reader is at offset 136 and expects the same input. Both routines return the answer in EAX register. Total bytes: 136.
Congrats, this is a really inefficient piece of code:
- you are loading the data from memory byte by byte... Ever heard of 64-bit registers and corresponding mem access instructions, and subsequent sequences of mask and shifts without loop?
- you do the operations byte by byte. I mean, of course because you load the data byte by byte... But see, if you had loaded 8 bytes at once in a 64-bit register, you could have substracted '0x30 30 30 30 30 30 30 30' all at once, in one single instruction. Then you wouldn't need to test anymore the lower boundary, because the operation will project the valid range [0x30:0x39] to [0x00:0x09] that you can use directly, and lower invalid range [0x00:0x2F] to [0xD0:0xFF] which is greater than 0x09 and will therefore fail the upper boundary test. You'll get a carry on previous digit when that happens so you may need to backtrack a little bit, in particular if previous digits were 0, but that will happen only once for the last dword of the chain because we are at the exit condition anyway. And that is if you aren't using SIMD instructions...
- and even assuming you want to do it sequentially, you are testing each digit against its boundaries with 2x CMP (against 0x30 and 0x39), and then after you found the digit is valid, you do sub 0x30... Wasteful. If you had done the sub rightaway at the beginning, you could test the sign flag, and you didn't need to do a CMP 0x30.
- you increment the source index ESI at each loop... but you don't use it to address your mem access, instead of which you also increment EDX that you dereference directly.
- you.. well... enough..
This is probably one of the most inefficient implementation of atoi I have seen ever.
The fact you bothered writing it in machine code directly is both self-explanatory for poor performance, and baffling because:
1) it totally underperforms what the most crapy compiler on earth would have achieved
2) you would have got exactly the same results by writing it in ASM directly and assembling it (which I suspect you did anyway)
3) you wasted a stupendous amount of time doing it
4) this is totally vain to say the least
Not sure what you are trying to prove, and to whom you are trying to prove it.
But if it's a question of ego, I definitely recommand that you undertake the creation of a new alt-coin that will demonstrate your ideas.
That way you can prove to yourself and to everyone here that having a high IQ yields a bit more than a nice mensa certificate to put on your wall and added bragging power in troll threads.
┌─[x]─────────────────────────── /tmp/blop ────────────────────────────────5───┐
│00000000 31c0 xor eax, eax │
│00000002 53 push ebx │
│00000003 51 push ecx │
│00000004 56 push esi │
│00000005 57 push edi │
│00000006 55 push ebp │
│00000007 52 push edx │
│00000008 31f6 xor esi, esi │
│0000000a 8a02 mov al, [edx] │
│0000000c 80f830 cmp al, 0x30 │
│0000000f 7c10 jl 0x21 │
│00000011 80f839 cmp al, 0x39 │
│00000014 7f0b jg 0x21 │
│00000016 2c30 sub al, 0x30 │
│00000018 83c601 add esi, 0x1 │
│0000001b 50 push eax │
│0000001c 83c201 add edx, 0x1 │
│0000001f ebe9 jmp 0xa │
│00000021 c7c50a000000 mov ebp, 0xa │
│00000027 c7c101000000 mov ecx, 0x1 │
│0000002d 31db xor ebx, ebx │
│0000002f 89f7 mov edi, esi │
│00000031 83fe00 cmp esi, 0x0 │
│00000034 7410 jz 0x46 │
│00000036 58 pop eax │
│00000037 f7e1 mul eax, ecx │
│00000039 01c3 add ebx, eax │
│0000003b 83ee01 sub esi, 0x1 │
│0000003e 89c8 mov eax, ecx │
│00000040 f7e5 mul eax, ebp │
│00000042 89c1 mov ecx, eax │
│00000044 ebeb jmp 0x31 │
│00000046 89d8 mov eax, ebx │
│00000048 5a pop edx │
│00000049 01fa add edx, edi │
│0000004b 5d pop ebp │
│0000004c 5f pop edi │
│0000004d 5e pop esi │
│0000004e 59 pop ecx
│0000004f 5b pop ebx
│00000050 c3 ret
│00000051 31c0 xor eax, eax
│00000053 53 push ebx
│00000054 51 push ecx
│00000055 56 push esi
│00000056 57 push edi
│00000057 55 push ebp
│00000058 52 push edx
│00000059 31f6 xor esi, esi ▒
│0000005b 8a02 mov al, [edx] ▒
│0000005d 80f830 cmp al, 0x30 ▒
│00000060 7c09 jl 0x6b ▒
│00000062 80f839 cmp al, 0x39 ▒
│00000065 7f04 jg 0x6b ▒
│00000067 2c30 sub al, 0x30 ▒
│00000069 eb0c jmp 0x77 ▒
│0000006b 80f841 cmp al, 0x41 ▒
│0000006e 7c10 jl 0x80 ▒
│00000070 80f846 cmp al, 0x46 ▒
│00000073 7f0b jg 0x80 ▒
│00000075 2c4b sub al, 0x4b ▒
│00000077 83c601 add esi, 0x1 ▒
│0000007a 50 push eax ▒
│0000007b 83c201 add edx, 0x1 ▒
│0000007e ebdb jmp 0x5b ▒
│00000080 c7c510000000 mov ebp, 0x10 ▒
│00000086 eb9f jmp 0x27 v
└─── view 0x00000086/134 ──────────────────────────────────────────────────────┘