When compiling this:
// external definitions
int value1 = 0;
static int value2 = 0;
the gcc compiler generates the following assembly:
BSS is the segment containing data initialized at run time where as data segment contains data initialized in the program binary.
Now static variables are always initialized whether done explicitly in program or not. But there are two separate categories, initialized (DS) and uninitialized (BSS) statics.
All values present in BSS are those which are not initialized in the code of program and hence initialized when program is loaded at run time to 0 (if integer), null for pointers etc.
So when you initialize with 0, the value goes to BSS where as any other value assigned will allocate the variable in Data segment.
An interesting consequence is, the size of data initialized in BSS will not be included in program binary, where as that of the one in data segment is included.
Try allocating a large static array and use it in a program. See the executable size when it is not initialized explicitly in code. Then initialize it with non zero values like
static int arr[1000] = {2};
The size of executable in the latter case will be significantly greater