Using the old fashioned (unsigned) multiplication instruction in x64 assembly multiplies RAX (64 bit register) by a 64 bit register. The answer is stored in RDX:RAX (i.e. the answer is 128 bits). Is there any way, using native c++ to get the value in RDX (higher 64 bits)? One I can think of is:
right/(limit/left) e.g. if we are limited to a byte then 97*123 would overflow:
97/(255/123) = 46 times, which is RDX's (if it was one byte) value. But this is too inefficient. Is there a fast way?
"native c++" doesn't have 128-bit types, but it defines the rules for when such types are provided by the compiler. If your compiler is one of those that implements them (and a lot of them actually do), you can write it in C++:
1 2 3 4 5 6 7 8
//volatiles to defeat optimizations
volatile uint64_t a = rand();
volatile uint64_t b = rand();
volatile uint64_t r;
int main()
{
r = ( __int128(a)*b ) >> 64;
}
g++
main:
movq a(%rip), %rdx
movq b(%rip), %rax
mulq %rdx
xorl %eax, %eax // prepare the return value for main()
movq %rdx, r(%rip) // copy RDX to r
ret
^ Yea, I've been working on a big integer library recently and have found the lack of a 128 bit integer data type in Visual Studio baffling, especially when it's so easy to handle such numbers in x64 assembly.