Nah, it was still all zero. The x86 segmented addressing scheme is very unusual (a lot of people abhor it as an abomination).
A 20-bit address was composed of two 16-bit values (segment:offset) summed as:
(segment << 4) + offset
The offset may be zero (or NULL), meaning that you are referring to the beginning of a memory segment (with a granularity of one paragraph, or 16 bytes). However, an x86 NULL pointer is actually zero in both segment and offset --making it point to the hardware interrupt address table (located in the first 1024 bytes of memory). [The interrupts are for both hardware and software events --it is just that the location of the table itself is a hardware requirement.]
The memory itself is protected, so special instructions are required to modify it --meaning attempts to dereference a NULL pointer will fail (and generate an interrupt :-P ).
The 0:0 nature of PC pointers has caused many programmers (I was one of them) to assume that NULL pointers always have a cleared bit pattern. This is not always the case on other hardware. On other hardware, the bit pattern for a NULL int* may differ from the bit pattern for a NULL char*. In fact, pointers don't even have to be the same size. This was the case in DOS, since a FAR pointer was a pointer that included both the segment and offset parts, and a NEAR pointer was a pointer that only included the offset part (and was reliant on the current segment context [CS, DS, ES, or SS, depending on what you are dereferencing] to be used properly).
Gets messy fast, doesn't it?
What this means is that you cannot use things like memset() to initialize structures containing pointers. For example, given:
1 2 3 4 5 6 7 8 9
|
typedef enum { Neuter, Male, Female } Sex_t;
typedef struct
{
char* name;
int age;
Sex_t gender;
}
Person_t;
| |
Then the following is wrong:
1 2 3 4 5 6
|
{
Person_t john;
memset( &john, 0, sizeof( Person_t ) );
// Any code that follows may fail.
}
| |
The char* also needs proper initialization:
1 2 3 4 5 6 7
|
{
Person_t john;
memset( &john, 0, sizeof( Person_t ) );
john.name = 0; // or NULL, whichever you like
// Alright, everything is now good to go.
}
| |
:-)