My Cup Overflows

overflow

When performing math (even basic addition and subtraction) with signed numbers an overflow problem sometimes arises. The Arduino microcontroller indicates the existence of an overflow error by setting the overflow flag in the SREG. Here’s a demonstration of the overflow problem with a simple addition operation:

volatile int8_t n1=0x70; //112
volatile int8_t n2=0x35; //53
volatile int8_t answer;

void setup() {
  Serial.begin(9600);
  
  asm(
    "add %1, %2 \n"
  
    : "=r" (answer) : "r" (n1), "r" (n2)
  );
  
  Serial.print("answer = "); Serial.println(answer);
}

The result to the above addition is, “answer = -91”, or 0xA5 hexadecimal. That’s wrong! The reason the answer turns out wrong is because the result is larger than an 8-bit register can hold.

The largest “signed 8-bit number” is +127, or 0x7f hexadecimal. However, this operation did set the Status Register Overflow Flag (V flag) to warn us that the result is erroneous. But, it’s completely up to us, the programmer to deal with this issue.

What’s Your Sign?

In “8-bit signed number” operations, the overflow flag is set when either of the following two conditions occur:

• There is a carry from bit 6 to bit 7, but no carry out of bit 7 (C flag not set).
• There is a carry out of bit 7 (C flag set), but no carry from bit 6 to bit 7.

I bring these two cases to your attention, because we can perform addition on two negative numbers with the sign bit remaining correct, yet the addition could still overflow. For example, when adding -2 (0x80) and -128 (0xFE), the result becomes 0x7E (+126), which again is incorrect.

When adding two numbers with different signs, the absolute value of the result is a smaller number than the absolute value of the operands prior to the addition. In this case, an overflow is impossible.

Therefore, an overflow is only possible when adding two numbers with the same sign. Furthermore, when adding two “same-signed numbers”, the sign of the result must be the same. The conclusion here is, for signed number addition, if the overflow flag is set, the result is invalid, and in unsigned addition, if the carry flag is set, the result is invalid. In signed number operations, overflow is possible, and overflow corrupts the result and negates the sign bit.

See my tutorial on Arduino Inline Assembly Math here.

About Jim Eli

µC experimenter
This entry was posted in arduino, assembly language, avr, avr inline assenbly and tagged , , , , , . Bookmark the permalink.

Leave a comment