Or make an array with 2 billion uint64 entries all containing this constant:
0xC3C033C340C033
Then cast the array as if it was a uint32_t* add the number you want to check, cast it again as a function pointer of a function returns a int and voilà
It should take 16G of space to encode but it should require only a single page fault to load from disk.
This uses a GCC extension. If you can't use that or if it doesn't work you can easily create an ELF object file that contains a data section with that number repeated 2 billion times.
Explaination:
That magic number is actually two 32-bit numbers juxtaposed:
The first one is 0xC340C033, which encodes the following instructions:
xor eax, eax ; 33 C0
inc eax ; 40
ret ; C3
This effectively returns 1 in the eax register (which is compatible with the C calling convention)
The second number is similar but it doesn't include the "inc" instruction.
When casting as a int array we end up with an array with alternating function bodies. At even positions we have functions that return 1 (true) and at odd positions it returns 0 (false)
The interesting thing is each of those function bodies fit into a 32-bit number. A single jump to an arbitrary address would require larger array.
Of course, it's silly to do this for even/odd but it can be useful to understand how this works.
Go kids, build your own forths!
(Disclaimer: I haven't tried out any of the above and typed this on my phone while walking in the woods, so I'd be surprised if it actually works without some touches, but the gist of the idea should work)
0xC3C033C340C033
Then cast the array as if it was a uint32_t* add the number you want to check, cast it again as a function pointer of a function returns a int and voilà
It should take 16G of space to encode but it should require only a single page fault to load from disk.
This uses a GCC extension. If you can't use that or if it doesn't work you can easily create an ELF object file that contains a data section with that number repeated 2 billion times.Explaination:
That magic number is actually two 32-bit numbers juxtaposed:
The first one is 0xC340C033, which encodes the following instructions:
This effectively returns 1 in the eax register (which is compatible with the C calling convention)The second number is similar but it doesn't include the "inc" instruction.
When casting as a int array we end up with an array with alternating function bodies. At even positions we have functions that return 1 (true) and at odd positions it returns 0 (false)
The interesting thing is each of those function bodies fit into a 32-bit number. A single jump to an arbitrary address would require larger array.
Of course, it's silly to do this for even/odd but it can be useful to understand how this works.
Go kids, build your own forths!
(Disclaimer: I haven't tried out any of the above and typed this on my phone while walking in the woods, so I'd be surprised if it actually works without some touches, but the gist of the idea should work)
Edit: fixes