5

In C/C++, it is not allowed to access data at address 0.

However, the physical memory are numbered from 0. And, in DOS era, the interrupt vector table was located at physical address 0. The first interrupt vector was the handler of the division-by-zero exception.

My question is:

Under what cases is it allowed to access physical address 0?

xmllmx
  • 39,765
  • 26
  • 162
  • 323
  • 16
    There is no such restriction in the standard of either language. A process can access physical address 0 if it is running under a non-protected virtual memory address space. The protection itself is implemented by the OS, using the MMU. All this has nothing to do with neither C nor C++. – barak manos Nov 04 '14 at 13:01
  • 7
    Most probably it will be in a zone protected by the OS; maybe even part of a ROM. – SJuan76 Nov 04 '14 at 13:01
  • As @SJuan76 pointed out, it's not a restriction from the language but a material restriction – CollioTV Nov 04 '14 at 13:04
  • What @barakmanos says. Address 0 is valid on my embedded systems. Any old thread can write it. – Martin James Nov 04 '14 at 15:47
  • 1
    @MartinJames: Like I said, a process can access physical address 0 if it is running under a non-protected virtual memory address space. If you are only running a single process with no virtual memory management (as is the case with many embedded systems, sometimes even without an OS + multiple threads), then obviously you can access any physical address. In fact, there is no need for logical addresses under such scenario. – barak manos Nov 04 '14 at 16:39
  • @barakmanos - yes. I was agreeing with you:) – Martin James Nov 04 '14 at 21:44

6 Answers6

8

To access physical address zero, it depends on which platform you are talking. The language has no idea on the underlying addressing model, it depends on the OS.

  • On bare metal environment, you have total control on the page table if paging is enabled, or just de-reference zero if paging is not enabled.
  • On some Unix and Linux variation, you do mmap and perhaps also open /dev/mem to get a non-null pointer with logical address non-zero but physical address zero, it may require some access rights.
  • I'm not sure on Windows.

PS. Other answers seems make a confusion on language level pointer and physical address.

Non-maskable Interrupt
  • 3,841
  • 1
  • 19
  • 26
  • I fail to make the link between your answer and [the fact](http://stackoverflow.com/questions/6793262/why-dereferencing-a-null-pointer-is-undefined-behaviour) that dereferencing a null pointer is deemed undefinded behaviour in 6.5.3.2/4 section of C99 standard. – Dmitry Grigoryev May 28 '15 at 11:21
  • We are not talking about de-referencing null pointer here. We talk about accessing physical address zero, which is possible by mapping it into a non-null virtual address. Furthermore the question by OP is not limited to C. – Non-maskable Interrupt May 28 '15 at 12:05
  • Is it possible to access address 0 in C/C++ without using paging, and avoiding undefined behaviour? – Dmitry Grigoryev May 28 '15 at 12:18
  • 1
    The short answer is No. As stated, the language itself has no idea on the underlying address model, so the question "access physical zero in C or C++" itself is meaningless, or at least platform-specific. If there is no paging, the only way to access physical zero is then using a null pointer, which is undefined behaviour - it may work, or may not work. – Non-maskable Interrupt May 28 '15 at 12:41
  • OUOH, There is one more extreme case which you can access physical zero on system without paging - on ancient 8086 machine which do memory wrapping on 1MB / A20. – Non-maskable Interrupt May 28 '15 at 12:44
4

Generally, the address space in virtual memory is managed by the operating system.

A freestanding C (or C++) implementation could certainly allow you to dereference (void*)0 in an implementation specific way. But beware of undefined behavior.

The C and C++ standards are very careful about the NULL pointer (and C++11 added the nullptr keyword for several good reasons).

A C compiler (at least a hosted implementation) is allowed to suppose that after a successful dereference a pointer is not null. Some optimizations in GCC are doing that.

Most hosted C or C++ implementations have a null pointer which is an all-zero-bits word, but that is not required by the standard (however, it is very common; it helps the compiler and the libc). However, pragmatically, a lot of software is supposing that NULL is represented by all-zero-bits (in theory it is a mistake).

I know no C implementation where NULL is not all-zero-bits, but that is not required. However, coding such a compiler would be a headache.

On some operating systems, an application can change its address space, e.g. with mmap(2) on POSIX or Linux.

If you really wanted, you could access address 0 in C, but you really should never want to do that.

Basile Starynkevitch
  • 223,805
  • 18
  • 296
  • 547
4

In C/C++, it is not allowed to access address 0.

Yes you can, as long as there's addressable memory there. On most platforms, there won't be.

Under what cases is it allowed to access physical address 0?

You can access any physical address if it's mapped into virtual memory. If there's anything sensitive there, then the OS probably won't allow that in user code. Within the kernel, it's just a case of setting up the page tables to include that address.

Mike Seymour
  • 249,747
  • 28
  • 448
  • 644
3

There's no specification in either C or C++ that would allow you to assign a specific physical address to a pointer. So your question about "how one would access address 0" could be translated to "how one would assign 0 address to a pointer" formally has no answer. You simply can't assign a specific address to a pointer in C/C++.

But you can get that effect through integer-to-pointer conversion:-

uintptr_t null_address = 0;
void *ptr = (void *) null_address;
ravi
  • 10,994
  • 1
  • 18
  • 36
1

The C Standard does not require that platforms provide access to any particular physical memory location, zero or otherwise. While it would be common on many embedded platforms for (char*)0x1234 to access physical location 0x1234, nothing in the C Standard requires that.

The C Standard also does not require that platforms do anything in particular if an attempt is made to access a null pointer. Consequently, if a compiler writer wanted to treat a null pointer dereference as an access to physical location zero, such behavior would be conforming.

Compilers where an access to address zero would be meaningful and useful will typically interpret a null pointer access as an access to location zero. The only problem would be with platforms where accesses to location zero are useful but compiler writers don't know that. That situation can generally only be handled by checking the compiler's documentation for ways to force the compiler to treat a null pointer like any other address.

supercat
  • 77,689
  • 9
  • 166
  • 211
0

Your question is a bit confusing. You ask whether it is possible to "access physical address zero." In a modern paged operating system, applications cannot specify physical addresses at all. Physical addresses can only be accessed through kernel mode.

In virtual memory systems, it became common not to map the first page of virtual memory into the process address space. Thus, accessing virtual address zero would trigger an access violation.

In such systems, it is usually possible for the application to map the first page to the process access space through system services. Even if the page is not there by default, it can be added by the application.

The answer is that it is possible to access physical memory address zero in kernel mode and it is possible to access virtual address zero IF the application maps that page to memory (and the OS allows that).

user3344003
  • 20,574
  • 3
  • 26
  • 62