# xorpd assembly riddle 0x02

xorpd has some riddle-like pieces of assembly code here. In this post, I’ll analyze this one.

I present to you the riddle number 0x02:

`neg rax`

sbb rax,rax

neg rax

In order to understand this one we first need to understand **neg** and **sbb **instructions. Let’s check Intel’s manuals:

*Integer Subtraction with Borrow (**aka sbb)** definition from **Intel’s manual**:*

Adds the source operand (second operand) and the carry (CF) flag, and subtracts the result from the destination operand (first operand). The result of the subtraction is stored in the destination operand

`DEST ← (DEST — (SRC + CF));`

*Two’s Complement Negation (**aka neg)** definition from **Intel’s manual**:*

Replaces the value of operand (the destination operand) with its two’s complement. (This operation is equivalent to subtracting the operand from 0.)

`IF DEST = 0 `

THEN CF ← 0;

ELSE CF ← 1;

FI;

DEST ← [– (DEST)]

Now you may ask, *how’s **the two’s complement** obtained?* It’s obtained just by flipping every bit and then adding 1 to the result. Here are some examples:

00110101 ==(flip)==> 11001010 ==(+1)==> 11001011

11001011 is the 2’s complement of 0011010111110000 ==(flip)==> 00001111 ==(+1)==> 00010000

00010000 is the 2’s complement of 11110000

Now that we grasp what each instruction does let’s analyze the code line by line

**Line 1: neg rax**

This computes the two’s complement, places the result into **rax** and updates the Carry Flag (**CF**) accordingly.

Example 1:Suppose the original value from rax on line 1 was 101neg rax ; rax is now = !rax+1 = (!101)+1 = 010+1 =011

;CF=1

Example 2:Suppose the original value from rax on line 1 was 000neg rax ; rax is now = !rax+1 = (!000)+1 = 111+1 =000

;CF=0

## Line 2: **sbb rax, rax**

This op performs subtraction between **rax** and itself + the **CF** (which is 0 if the original value from **rax** was 0, or 1 otherwise).

Following Example 1 (original rax value was 101):sbb rax, rax ; This can be expressed as:

; 1. 011 - (011+CF)CF=1 in this case, from prev op

; 2. 011 - (011+1) <--|

; 3. 011 - 100

; 4.111A borrow occurred here

Following Example 2 (original rax value was 000):sbb rax, rax ; This can be expressed as:

; 1. 000 - (000+CF)CF=0 in this case, from prev op

; 2. 000 - (000+0) <--|

; 3. 000 - 000

; 4.000

## Line 3: **neg rax**

Same as in line 1, of course, but just with updated values from previous ops:

Following Example 1 (original rax value was 101):

neg rax ; rax is now = !rax+1 = (!111)+1 = 000+1 =001

Following Example 2 (original rax value was 000):

neg rax ; rax is now = !rax+1 = (!000)+1 = 111+1 =000

## Conclusion

As a final conclusion, we can say that this piece of code sets **rax** to **0** if its original value was 0 or to **1** if it was otherwise. I can imagine this to be a sort of integer to boolean conversion. In a high-level programming language this could be expressed as:

`func foo(n *int) bool {`

return *n != 0

}