0

I have been studying x86-64 assembly and the memory layout of programs.

I have run into examples of the virtual address space of a program where the lower portion (0x00000000-0x00010000) is marked as reserved. But I cannot find an explanation for this.

I have two questions

  1. Why is this portion reserved. Can I really not access this from my program? This lower portion is counted as user space memory. So I don't understand why I would not be able to use it
  2. What is this reserved portion used for?
TPens
  • 59
  • 2
  • 4
    The first 64 kB are reserved so dereferencing a null pointer or a pointer derived from a null pointer is likely to cause a program crash. – fuz Jan 06 '21 at 10:52
  • On linux you can tune it via `/proc/sys/vm/mmap_min_addr`. – Jester Jan 06 '21 at 11:39
  • @fuz: Reserved *by the Linux kernel*, not by the x86-64 ISA. https://wiki.debian.org/mmap_min_addr points out that WINE may need to use that range for 16-bit Windows binaries. – Peter Cordes Jan 06 '21 at 20:02

1 Answers1

0

Can I really not access this from my program?

In 32-bit mode, x86 CPUs can use "paging", in 64-bit mode (the operating systems of) x86 CPUs must use this feature.

Greatly simplified, "paging" is a feature of larger CPUs (devices like the "Arduino" don't have this feature) that allows telling the CPU which address in the hardware RAM is actually accessed by some address.

Paging has been invented to handle the following situation:

Let's say you write some application program (maybe a text editor) that stores some value at address 0x123456 and you run this program twice at the same time.

In this case you will normally expect that one program does not overwrite the data stored by the other program although both programs store the data at address 0x123456.

Using "paging" the operating system tells the CPU that one program shall actually access some address (maybe 0x200456) in RAM hardware when accessing address 0x123456 and the other program shall access another address (maybe 0x300456) in RAM hardware when accessing address 0x123456, so the two programs don't overwrite the data of the other program although both programs use the same address (0x123456).

The operating system may also tell the CPU that some memory area (for example 0-0x1000) is not used at all. This means that the CPU will not perform any memory access when trying to access that address but it "raises an exception" which means that the operating system is informed by calling some function in the operating system.

The operating system may then change the configuration of the "paging" and continue the program or stop the program and print some error message.

"Reserved" obviously means, that the operating system will stop the program with some error message.

What is this reserved portion used for?

I think that "reserved" here just means: "Not used" and not: "Reserved for future use".

Why is this portion reserved. ...

As user "fuz" already suggested in his comment, in most modern programming languages the address zero is used to specify that an argument is not specified.

Some example:

This function returns the length of some file if a file name is specified. If no file name is specified, the length of the last file opened is returned. The register rcx shall be the address where the file name is stored; if the register rcx is zero, this means that no file name is specified.

In this example, you would have a problem if the name of the file you are interested in is stored at address zero.

For this reason many operating systems do not use the "low" memory area (starting at 0) so it is guaranteed that the address "zero" does not specify any valid data.

Martin Rosenau
  • 17,897
  • 3
  • 19
  • 38
  • A good reason for reserving a whole range near 0 is arrays: `return arr[x];` You want that to still fault if `arr` is NULL and `x` is not tiny. Otherwise you'd wonder why not just reserve the zero page itself. (Linux also reserves the very top page of virtual address space: [Why can't I mmap(MAP\_FIXED) the highest virtual page in a 32-bit Linux process on a 64-bit kernel?](https://stackoverflow.com/q/47712502)) – Peter Cordes Jan 06 '21 at 20:07
  • I feel like this answer takes too long to get to the point (and doesn't spend enough time there). It doesn't even mention NULL pointers, an important concept in many languages, as part of your discussion of making sure that `0` doesn't get used as a valid address. Perhaps at least a TL:DR at the top, before you get into explaining what paging and memory-protection is. (If that's necessary at all). I kinda think that fuz's comment is a better overall answer than this, even though it's so brief. At least for readers that already understand some basics about paging. – Peter Cordes Jan 06 '21 at 20:22
  • @PeterCordes Unfortunately, the OP asked multiple questions at once. The question "Can I really not access this from my program?" cannot be answered without explaining what paging is (and unfortunately, this is the longest part of my answer). When I was writing my answer, I was thinking about the case `arr[x]` but I didn't mention it because my answer would have been even longer in this case. – Martin Rosenau Jan 06 '21 at 21:51
  • Ok that's fair, looking at that phrase in the question does make me reconsider my guess at the OP's level of understanding of virtual memory and that fact that any unmapped memory will page-fault. – Peter Cordes Jan 06 '21 at 21:54
  • @PeterCordes I didn't mention the term "`NULL` pointer" because it is named differently in different programming languages (examples are `nil` or `nothing`). The OP asked about assembly language, so I didn't want to use programming language specific terms and I was only talking about "the address zero" which has a special meaning. – Martin Rosenau Jan 06 '21 at 21:56
  • That's also fair, but a lot of low-level stuff gets documented using C conventions, e.g. many language ABIs are built on top of a C calling convention doc. Up to you whether you find that convincing or not, just my 2 cents. The phrase "NULL dereference" should ring a bell for almost every programmer who's heard of a similar concept, though. But you don't seem to mention helping to catch accidental deref of a 0 error code, only avoiding the case where a valid address would have the same 0 value as an error code. So that's another thing IMO missing here. But I guess you say intentionally so. – Peter Cordes Jan 06 '21 at 22:01