It’s a global pointer. It has to be, because a local zero is an alias for the start of the turf’s private region.
The language does not in fact require a NULL to be binary zero – the “0” in “p = 0” is a token, not a value. Thus “p = (void*)(x-x)” is not guaranteed to leave p NULL. However, nearly all modern machines do in fact use binary zero for NULL, and we do too.