Will the overflow flag be set if you add a negative integer to a negative integer and produce a positive result?

I like this question a lot, I think it is very useful. But due to the time passed I cannot edit and format it. Nevertheless, here is my take on it (I like posting long, detailed and verbose answers).

Unsigned binary ("normal" binary)

If you have 4 bits available to represent a binary number, then you can represent the following unsigned numbers:

(0) - 0000
(1) - 0001
(2) - 0010
...
(15) - 1111

So basically, if we have N bits available, the smallest number we can write down is 0, and the largest is 2^N-1 (in total 2^N numbers).

Two's complement

PCs require usage of both positive and negative integers. Most PCs use "two's complement" to represent binary numbers [1]. According to many people, it is the simplest and most convenient way to represent signed numbers (so both positives and negatives).

Now, when using signed numbers, we need to reserve 1 bit for the sign. Two's complement enables us to do this very simply:

  1. The sign is kept as the prefix, so the MSB of the binary number (i.e. the "first bit" from the left side). 0 is used for positives, 1 for negatives.

  2. Positive numbers are unaltered.

  3. Negative numbers are "continued" on top of positives.

So, for example, if we have 4 bits available:

    (1)  -  0 001
    (2)  -  0 010
    (3)  -  0 100
        ...
    (6)  -  0 110
    (7)  -  0 111
    (-8) -  1 000
    (-7) -  1 001
        ...
    (-1) -  1 110
    (0)  -  1 111

As we be seen, all negatives start with the MSB being "1". The smallest number we can write down is 2^(N-1), and the largest is 2^(N-1) - 1.

In the table above I presented the numbers by first presenting the positives, and then the negatives. I did this to emphasize that the negatives are "continued" on top of the positives. It's easy to see that the positives are exactly the same as they were when usign unsigned binary, but they have the prefix "0". This is why the largest positive is 7, when using a 4 bit two's complement notation. When using unsigned binary, the largest 3 bit number we can represent is 7 (111). When using two's complement (with 4 bits available), 1 space is reserved for the sign, so effectively, we have 3 bits to represent the numbers value, and thus 0111 is the largest positive number we can represent, and that is 7.

Addition

Without going into too much detail, two's complement has a nice advantage - addition, subtraction and multiplication are done the same way as when usign unsigned binary.

e.g. if we want to sum 3 + 4, when using two's complement, with 4 bits available, we'd have:

3 = 0011
4 = 0100
    ----
7 = 0111

Overflow - answer to your question

Overflow occurs when the result of an arithmetic operation cannot fit into the result register [2].

Basically, if you sum two big positives, you might not have enough "bits" to fit the result into, and it might appear as if the result is negative. That is when the overflow flag is set. The same applies for when you subtract a positive number from a negative. The latter can also be defined as: when you add two negatives together and get a positive - that is overflow as well.

In the code from the question, the two registers R0 and R1 contain:

R0 = 0X80000000 (-2147483648)
R1 = 0X40000000 (1073741824)

These numbers are written using 8 hexadecimal characters == 32 bits. So, using 32 bits to represent two's complement, we have:

R0      = 1000 0000 0000 0000 0000 0000 0000 0000 
R1      = 0100 0000 0000 0000 0000 0000 0000 0000
R0 - R1 = 0100 0000 0000 0000 0000 0000 0000 0000

So what happpened here? Well, from what we learned by now R0 contains the smallest negative integer that we can write down in two's complement. So subtracting even 1 from it will result in overflow! And we know overflow occured, since after subtracting a positive number from a negative our result ended up being positive. And we know this because R0 has prefix "1" - it's negative. R1 has prefix "0" - it's positive. So, negative - positive = must be negative. In our case the prefix turned out to be "0" - positive, which means overflow happened for sure.

Bonus: Can I make a full circle?

You might ask yourself: but what if I sum or subtract two numbers, so that I make such a "big" overflow and end up with the correct sign again? (e.g. imagine you sum 7 + 7, creating an overflow, but the result ends up being +2 in binary? How would you detect that an overflow had happened when the result is the same sign?)

When its only addition and subtraction (and let's stay with those 2 only), we can easily show what the maximum and minimum numbers that we can get from those 2 operations are:

(again a 4 bit example)

Positives

R0 = 0111 (7) (largest positive integer)
R1 = 0111 (7) (largest positive integer)
R1 + R2 = 1110 (-2)

Negatives

R0 = 1000 (-8) (smallest negative integer)
R1 = 1000 (-8) (smallest negative integer)
R0 + R1 = 0000 (0)

The reason why I've given this example is to show that if you attempt to do the worst case (sum the two largest integers or sum the two smallest integers), you cannot make a full circle, i.e. the result will be of opposite sign. So,in the case of two operands, you're guaranteed to be good, i.e. if an overflow occurs, the sign of the result will be different. It's not possible to sum two large integers, to create an overflow, to pass through all the negative values and end up with a positive again.

Is it possible to set the overflow flag if you add a negative integer to a negative integer?

It is possible to set the overflow flag if you add a negative integer to a negative integer. It is possible to set the overflow flag if you add a positive integer to a negative integer.

Will the overflow flag be set if you add a positive integer to a positive integer and produce a negative result?

Basically, if you sum two big positives, you might not have enough "bits" to fit the result into, and it might appear as if the result is negative. That is when the overflow flag is set. The same applies for when you subtract a positive number from a negative.

When you move a 16 bit constant or an 8 bit?

When you move a 16-bit constant or an 8-bit constant into a 64-bit register, the upper bits of the destination operand are cleared.

Which of the following are the basic types of operands?

Three kinds of operands are generally available to the instructions: register, memory, and immediate. Indirect operands are available only to jump and call instructions.