Signed integers are represented on x86 via two's complement, where the sign bit has the value -(2^N)
. This results in a typical representable value range between -2^N
and 2^N - 1
(e.g. -32768
through 32767
).
I was curious what would occur if I took the minimum signed integer value on my system and multiply it by -1
in an attempt to "force" a maximum value greater than the maximum representable value of signed integers on my system.
#include <stdio.h>
#include <limits.h>
int main(void){
signed int x, y;
x = INT_MIN;
y = x * -1;
printf("%d\n%d\n", x, y);
return 0;
}
This resulted in the following output:
# gcc -std=c89 -pedantic int_min_test.c
# ./a.out
-2147483648
-2147483648
I was expecting an integer overflow (resulting in the typical value rollover), but it appears as if no operation took place regarding the multiplication of x
with -1
.
Is the multiplication of INT_MIN
with -1
a no-op in x86?
Using gcc 4.8.5, the line y = x * -1;
is computed using the following instruction:
neg %eax
The neg operation flips the bits of the word and then adds 1. For 32 bit 2's complement the result is:
0x80000000 # Start value
0x7FFFFFFF # Flip bits
0x80000000 # Add 1
As you see, the computer is doing exactly what you are telling it to do. This is not a no-op, as neg
modifies the AF
, CF
, OF
, PF
, SF
, and ZF
flags. It is just an artifact of the binary representation being used. As others have stated it is simply undefined behavior.