## Signed and Unsigned additions in x86

Some basic knowledge of assembly, registers and flags is assumed.

We use an adder circuit in the CPU to do additions. To check for overflows and carry we have 2 flags. Consider we have a 5 bit system. If we do unsigned addition of say, 25 (11001) and 7(00111), the CPU will set the carry flag and the overflow flag to 1 and will set the resultant register value to 0. As the resultant number couldn’t be represented using 5 bits, we set the carry flag to 1. As the number exceeds the unsigned bit range we set the overflow flag it to 1.  So here carry flag and the overflow flag represent the same thing!

# How are signed integers represented?

Signed integers are represented differently, as we need 1 extra bit  to specify the sign. The simplest way to represent signed integers is by just setting the most significant to the sign bit and represent the unsigned integer in rest of the bits.

Consider an 8 bit environment.

+1  = 00000001
-20 = 10010100
-21 = 10010101

It’s convenient for us, but if you consider making a circuit to compute the result of a signed addition, it gets complicated. We’ll have to check the sign bits and then based on the sign bits we’ll do an addition or a subtraction. That requires us to have a subtractor circuit in our CPU as well.

It turns out we can do better than this if we represent negative numbers as two’s compliment. We still reserve the most significant bit for sign.

1   = 00000001
-21 = 11101011

Let’s now try to add -21 and 1:

111101011
000000001
---------
111101100
---------

This gives us: 11101100 (2’s complement = 000010100)

Which is -20 (according to our representation)

The circuit becomes less complicated. We can now do it using just an adder and less comparisons.

Lets try to add 2 negative integers

-20 = 11101100
-21 = 11101011
11101100
11101011
--------
11010111
--------

Which is -41. The carry flag will consider the last unsigned addition’s value, it simply asks if there is a carry from the previous addition. Which is yes for this case, so the carry flag is set. Overflow flag checks if the resultant value couldn’t be represented in 8 bits, -41 can be represented and hence the overflow flag is not set in this case.

Now, let’s try to add -121 and -8.

+121 = 01111001
+8   = 00001000
-121 = 10000111
-8   = 11111000
10000111
11111000
--------
11111111
--------

The resultant value = 11111111. The carry flag will again set to 1. The overflow flag will also set to 1 here as the resultant value = -127 – 8 = -129, can’t be represented in 8 bits (7 + 1 bit for sign).

## Get list of likes for any facebook post

Get list of users who have liked a particular post on facebook.

Go to graph explorer.

Step 2 – Getting post ID:

Clicking on the date attached (“September 12 at 6:50 pm”) to a post will take you to the post page from where you can get the ID.

Save the post id, we’ll use it in the next step to get the list of likes of a post.

Step 3 – Getting the list of likes:

To the run this python code you’ll have to install the requests library, should be as easy as “pip install requests”. Running this python code will get you the list of likes for a post in CSV format and will save it as <POST_ID>_likes.csv.

Enjoy!

## xchg rax, rax

I found this amazing book online xchg rax, rax by xorpd. It’s a collection of assembly riddles. The book contains 0x40 short assembly snippets, with no text.

I just started reading it and its amazing. I’ll update this blog post with explanations of the snippets that I explore.

xchg rax,rax - 0x00 explanation

Hint: It’s the 0th snippet.

The snippet just illustrates some different ways to set the registers to 0. It sets eax, ebx, ecx, edx, esi, edi and ebp to 0 in the same order.

[collapse]
xchg rax,rax - 0x01 explanation

Fibonacci

[collapse]
xchg rax,rax - 0x02 explanation

Sets rax to 0 if the initial value is 0. Otherwise it always sets it to 1.

[collapse]
xchg rax,rax - 0x03 explanation

Actually that code is a clever branchless way to do rax = min(rax, rdx).

sub rdx, rax ; rdx = rdx - rax; CF set if rdx < rax
sbb rcx, rcx ; rcx = all 1 bits if CF was set, 0 otherwise
and rcx, rdx ; rcx = rdx - rax if CF was set, 0 otherwise
add rax, rcx ; rax = rax + (rdx - rax) = rdx if CF was set, unchanged otherwise


A more readable branching version is:

cmp rdx, rax
jnc done ; if rdx - rax produced no carry, rax is smaller or equal
mov rax, rdx ; otherwise rdx is the smaller one
done:


It’s still just using CF for overflow checking.

[collapse]
xchg rax,rax - 0x04 explanation

0x20 in binary is 00100000

So, xoring a number with 0x20 will flip the 5th most significant bit. Now, if we see the ascii character’s representation in binary there is something interesting to note.

A  = 0100 0001
a  = 0110 0001
B  = 0100 0010
b  = 0110 0010

There we see. Flipping the fifth bit flips the case (lower/upper) of the letter.

[collapse]