Why is the memory address printed with {: p} so much larger than my RAM specifications?

I want to print the memory cell (address) of a variable with:

let x = 1; println!("{:p}", &x); 

This prints the hex value 0x7fff51ef6380 , which is in decimal format 140734568031104 .

My computer has 16 GB of RAM, so why is this a huge amount? Does the x64 architecture use a large interval sequence instead of a simple 1 increment to access a memory location?

On x86, usually the first place starts with 0, then 1, 2, etc., so the largest number you can have is about 4 billion, so the address number is always equal to or less than 4 billion.

Why is this not true with x64?

+7
memory rust
source share
2 answers

What you see here is the effect of virtual memory . Memory management is difficult, and it becomes increasingly difficult when the operating system and tens of hundreds of processes must share memory. To cope with this enormous complexity, the concept of virtual memory was used. I will just briefly explain the basics here; the topic is much more complicated, and you should also read about it elsewhere.

On most modern computers, every process believes that it owns an (almost) full memory space. But processes never deal with physical addresses, but with virtual ones. These virtual addresses are mapped to physical each time the process actually reads from memory. This translation of addresses is done by the so-called MMU (memory management module). Rules for address mapping are configured by the operating system.

When the PC boots, the operating system creates the original mapping. Each time you start a process, the operating system adds several pieces of physical memory to the process and changes the display accordingly. Thus, the process has a memory that can be played.

In x86_64, the address space is 64 bits wide, so each process considers that it owns all these 2 ^ 64 addresses. Of course, this is not so:

  • There are no PCs in the world with such a large memory. (In fact, most processors today can simply use 280 TB of RAM, because they can only use 48 bits internally for addressing physical memory. And even these 280 TB are enough, apparently.)
  • Even if you have so much memory, there are other processes that also use part of this memory.

So what happens when you try to read an address that is not displayed (which in the 64-bit territory is the vast majority of addresses)? MMU causes a page error. This causes the processor to notify the operating system of this.

I mean, in x86, usually the first place starts with 0, then 1, 2, etc., so the largest number you can have is about 4 billion.

This is true, but it is also true if your x86 system has less than 4 GB of RAM. Virtual memory has been around for quite some time.


So, a short description of why you see such large addresses. Again, note that here I have examined in detail a lot of details.

+11
source share

The pointers your program works with are in the virtual address space . x86-64 uses 64-bit pointers. This was one of AMD64's main goals, as well as adding more integer and XMM registers. You are right that the i386 has only 32-bit pointers that cover only 4 GB of address space in each process.

0x7fff51ef6380 looks like a stack pointer, which I think makes sense for this code.

Linux on x86-64 (for example) pushes the stack at the top of the lower canonical address range : current x86-64 hardware only implements 48-bit virtual addresses, and this is a mechanism to prevent software dependent on it. This allows you to expand the address space in the future without breaking the software.

The amount of fiscal RAM in your system has nothing to do with it. You will see (approximately) the same number in the x86-64 system with 128 MB of RAM, +/- stack address space allocation randomization (ASLR) .

+6
source share

All Articles