On the next page of xchg rax, rax, we’re given a very simple program:

.loop:
    xadd     rax,rdx
    loop     .loop

We know from the previous post how loop works. Each time it loops it decrements the rcx register. So we know that we need to set the register to something other than zero if we want to tinker with it, so I set it to 10.

The xadd is the instruction of interest, and that is entirely the body of the loop. xadd is exchange and add.

The Intel x86-64 reference manual describes it as “Exchanges the first operand (destination operand) with the second operand (source operand), then loads the sum of the two values into the destination operand.”

So all we are doing in the loop is adding and exchanging the values in the rax and rdx register. The book offers no hints on what the code is supposed to do, so the best we can do here is tinker with the value of the registers and see if the results are anything clever. We can make some guesses though. If the registers are both zero, we can figure that nothing interesting will ever happen. The loop will keep adding zeros until the loop counter reaches zero.

You might recognize what this does just by looking at the assembly. As a hint, set rax to 1, and rdx to 1, and watch the value of rax. Here are the values of rax after each iteration of the loop:

Initial:
rax = 0x0000000000000001
rdx = 0x0000000000000001
rcx = 0x000000000000000a

Next:
rax = 0x0000000000000002
rdx = 0x0000000000000001
rcx = 0x0000000000000009

Next: 
rax = 0x0000000000000003
rdx = 0x0000000000000002
rcx = 0x0000000000000008

Next: 
rax = 0x0000000000000005
rdx = 0x0000000000000003
rcx = 0x0000000000000007

Next: 
rax = 0x0000000000000008
rdx = 0x0000000000000005
rcx = 0x0000000000000006

Next: 
rax = 0x000000000000000d
rdx = 0x0000000000000008
rcx = 0x0000000000000005

And so on until rcx reaches zero.

You might recognize this as the Fibonacci sequence. Just about any developer at one point has tried implementing the Fibonacci sequence, either to learn a new language, for fun, or for school.

I find it impressive that using assembly you can accomplish this with a single instruction and a loop.