3 ms·
Do you mean some quirk unique to these CPUs or do they simply have RAM mapped at this address? The latter is nothing unusual, x86 has it as well.
by qb45 11y ago
Do you mean some quirk unique to these CPUs or do they simply have RAM mapped at this address?
The latter is nothing unusual, x86 has it as well.
- CountSessine 11y agoLike many embedded cores, Cortex-M's don't have an MMU - everyone sees physical memory. In fact, I believe that's the chief distinguishing feature of the 3 core levels - Cortex-M's have no MMU, Cortex-A's have memory paging, and I think Cortex-R's are in between and have memory segments like MIPS. So if the board designer wired everything up to map RAM at address 0, then yes, you'd be able to dereference a pointer to address 0. Completely beside the point, though. Dereferencing NULL is always undefined behaviour in C.
- amluto 11y agoI'm a bit curious how a pointer with value 0 ended up being banned by C. Specifically, on x86 real mode (which includes modern systems early in boot before switching to protected mode), there's a hardware defined data structure at address zero: the "Interrupt Vector Table". Maybe everyone who wrote real-mode systems software either ignored that bit of the C standard, or they fudged around it (IIRC the IVT is an array and the first entry doesn't matter, so you can start a few bytes past zero), or they used assembly to access it.
- qb45 11y agoIt seems that 0 wasn't a usable address on PDP-11 so K&R decided it's fine to use it as null pointer constant. And of course dereferencing 0 isn't impossible in practice on arches which support this. Compilers for such machines usually can be coerced to generate code which accesses 0, you just have to live with the fact that your code isn't considered "valid, portable C" anymore.
- tzs 11y agoIn C, these two code fragments do not necessarily give the same result (assume pointers and longs are the same size): long zero = 0; struct IVT * ivt_ptr = (struct IVT *)zero; and struct IVT * ivt_ptr = 0; /* or (struct IVT *)0 if you like that better stylistically */ The former gives you a pointer whose bits are all 0. The latter gives you a null pointer. On systems where 0 is a valid memory address the compiler should pick some other address that is not valid. Similarly, these two are not necessarily the same: if ( ivt_ptr == 0 ) ... and if ( ivt_ptr == (struct IVT *)zero ) ... /* or if ((long)ivt_ptr == zero ) ... */ 0 only represents the null pointer in C when it is the constant 0. See this for more information: http://c-faq.com/null/ http://c-faq.com/null/
- qb45 11y ago> On systems where 0 is a valid memory address the compiler should pick some other address that is not valid. Not necessarily. Null dereference is undefined behavior so it may as well access some valid memory. Even on platforms where 0 is a valid address, practical compilers tend to use 0 as null constant because it simplifies implementation (easy to check for null, matches the C syntax without WTFs). This comes at the cost of making some small part of memory unusable to portable C code (nobody will believe you when you return 0 from malloc if 0 happens to be considered null), but that's fine because such memory is typically used for machine-specific, nonportable stuff anyway.