I am working through the riddles of "xchg rax,rax" (xchg.xorpd.net). Those are riddles about x86_64 assembly, where you have to understand what code pieces do. This is riddle number 0x15:
mov rdx,0xffffffff80000000
add rax,rdx
xor rax,rdx
It seems like this code is meant to enhance the value inside rax in some way, though I don't fully understand how. I tried to give in some inputs and outputs, but I didn't yet manage to understand what this code does. What is this 0xffffffff80000000 number? Could someone point me in the correct direction to the solution? I'm really curious about this one.
I'm not sure what "enhance" is supposed to mean, but assuming the upper half of
rax
is zero, it sign-extendseax
intorax
.First, observe that adding 0x80000000 and then xoring with 0x80000000 would do exactly nothing to
eax
. They both invert the highest bit, and an even number of inversions cancel out.But it's 64bit, so something happens: the addition can carry into the lowest bit of the upper half.
To make it simpler, let's pretend they wrote this:
Now the first two instructions sign-extend to 33 bits, putting a copy of the sign of
eax
in the lowest bit of the upper half ofrax
. So the upper half is either 0 or 1, depending on the sign ofeax
.The last two lines now look a lot like the usual
-x = ~(x - 1)
, but applied only to the upper half, turning that 1 into all ones.And these steps can be combined, which gives you the original code.
Alternatively, you can think of it as not cutting
rax
in half, but cutting it "just below half", so the negation deal is applied to a 33 bit number starting at the highest bit ofeax
.