Daily Dose of x86-64 - II
Tags: beginners, assembly, flag, binary
Published: 2023-01-09 21:35:11

**<u>Overflow and Carry Flags </u>**

Before we start learning flags, we need to know, how negative numbers stored in memory. The type that it stores negative numbers are **signed** integers. So lets start...

---

Think about an 8 bit memory. Normally 256 positive number can be stored inside of that memory, from 0 to 255. That type is **unsigned byte(uint8_t)**.

```
0   -> 0000 0000
255 -> 1111 1111
```

When we want to store negative values in 8 bit memory, **Most Significant Bit(MSB)** assigned as a **Sign bit** (leftmost bit), where the value 1 represents negative (sign bit = 1, integer is negative) and value 0 represents positive. This type is signed byte(int8_t).

**<u>1</u>**111 1111 -> MSB

```
0    -> 0000 0000
127  -> 0111 1111
-1   -> 1111 1111        
-128 -> 1000 0000       
```
 
In **unsigned** type **MSB**'s value equals to (+2^7) = 128 
`1001 0000  = (2^7 * 1) + (2^5 * 1)  = 128 + 32 = 160`
<u>8 bit unsigned integer(uint8_t) stores from 0 to 255.</u>

 
In **signed** type **MSB**'s value equals to (-2^7) = -128 and other bits still have positive values. 
`1001 0000  = (2^7 * -1) + (2^5 * 1) = -128 + 32 = -96` 
<u>8 bit signed integer(int8_t) stores from -128 to 127.</u>

---

In x86-64 assembly language, there is a instruction called **neg**, if the value is positive **neg** instruction makes it negative and if it is negative **neg** makes it positive, basically multiplying the value by -1. What actually it does is, taking two’s complement of that value. How we take two’s complement?

It is easy, we will flip all bits in integer (one’s complement) and add 1 (two’s complement).


![neg instruction](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/na9v81noyfxxns21z1y5.png)

```
0011 0000 = +48
1100 1111 = -49 (one’s complement)
1101 0000 = -48 (two’s complement)
```
```
1111 1111 = -1
0000 0000 =  0 (one’s complement)
0000 0001 = +1 (two’s complement)
```

---

Now that we have a better understanding of how the negative values stored in memory, we can go on with flags. It is better to continue with examples..


![Overflow Flag - 1](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ts8uhsl5oqx25g4tbts7.png)

In general explanation, **Overflow Flag (OF)** set (we call the verb set when a flags value returns 1 and clear when the value is 0) in **signed** integers when its value exceeds limits of signed integer. For example **AL** register's (8 bit) limits are -128 and 127 when we store **signed** values inside of it. 
We create a variable called var1 in data section and gave it a value 1000 0001b = -127d. We assign that value to **AL** register and subtract 3. Result is needs to be -130 but -130 exceeds the limits so Overflow Flag will set. But how it actually happens? 

---

Forget about exceeding limits for now. We will explain setting Overflow Flag with a different way.
```
1000 0001(-127) - 0000 0011(3) = 0111 1110(126)
```
0111 1110 = result is 126 and because of 126 is a positive value,
**MSB = 0**.

But the real result needs to be -130 which is a negative value,
**MSB = 1**.

Because of MSBs are **NOT SAME** and the type is a **signed integer**, Overflow Flag will set.

---

![Overflow Flag - 2](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/1a5qjb4lf7ojmkd7hjkx.png)

Exceeding 8 bit integers positive limit (127), results sign bit changes from positive to negative.
```
0111 1101 (125) + 0000 0101(5) = 1000 0010 (-126)
```

Results **MSB = 1** (negative), but normally it has to be positive, 125 + 5 = 130 **MSB = 0** (positive). Because of **MSBs** are NOT SAME and the type is **signed integer**, Overflow Flag will set.

---
Lets check Carry Flag.. 


![Carry Flag - 1](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/hp6rkb4fb382krhaojv5.png)

Carry flag used for **unsigned integers**. We will use 8 bit **unsigned integers (uint8_t)** as variables. 8 bit unsigned integer can store values from 0 to 255.

To understand Carry Flag, we need to ask ourselves about if there was one more bit(9th bit) in our 8 bit memory, could we carry 1(binary) to that bit or could we barrow 1(binary) from that, while we are doing addition and subtraction.

In examples inside the image above,

`1111 1110(254) + 0000 0111(7) = 0000 0101 (5)`, normally the result should be 261 but because of there was not 9th bit, that 1(binary), we need to carry will go to **Carry Bit** and it will set Carry Flag.

`0000 0101 (5) - 0000 1000(8) = 1111 1101 (253)`, normally we need to **barrow** 1(binary) from the 9th bit but there is no 9th bit so it will go to **Barrow Bit** and will set Carry Flag.

---

<u>Useful Links</u>

[One's Complement, Two's Complement, and Signed Magnitude](https://www.youtube.com/watch?v=Z3mswCN2FJs)

[Two's Complement Representation of Negative Numbers](https://www.youtube.com/watch?v=mRvcGijXI9w)

[Overflow and Carry Flags](https://www.youtube.com/watch?v=p0nMksY3SJo)

[The CARRY flag and OVERFLOW flag in binary arithmetic](http://teaching.idallen.com/dat2343/10f/notes/040_overflow.txt)