5

I have more or less 0 knowledge in low-level topics, so forgive my possible ignorance.

I know that in languages such as C, pointers hold 'memory addresses', i.e. strings (or binary data?) written in hex such as 0x52A132F3.

Judging by the term 'memory address', I assume this number actually leads to some place in memory. But I'm having a hard time understanding what a 'place in memory' actually is and how a hexadecimal number can 'lead' to it. (A Java programmer here..)

So two questions:

  1. Do the memory addresses point to places on the CPU itself, or anywhere in the computer?
  2. Is memory 'ordered' in hardware in some way that it makes sense to refer to it using an 'ordinal' number, such as 0x52A132F3? How is memory ordered in hardware, and how and why does it make sense to access it using a numerical value?
9
  • 4
    The mouseover reads "This question does not show any research effort" - have you at least read through the wikipedia page or done a google search and shown that you comprehend that - or if you are having issues with particular parts?
    – user40980
    Commented Sep 4, 2014 at 16:05
  • 4
    I would also suggest reading Is a question that specifically asks for a summary of a broad topic valuable to Stack Exchange? and Why is research important?
    – user40980
    Commented Sep 4, 2014 at 16:20
  • 2
    This is a narrow topic which I'm sure is useful to a lot of people. Commented Sep 4, 2014 at 16:31
  • 4
    @KarlBielefeldt that doesn't absolve the OP from doing some basic research to avoid having us restate what is in a Wikipedia article and commonly searchable. The required level of expert knowledge to answer this question is that of high school reading comprehension. Its utility for people is independent of if it is a good Stack Exchange question.
    – user40980
    Commented Sep 4, 2014 at 16:46
  • 4
    "more or less 0 knowledge in low-level topics" -- start with How Do Computers Work? (side note lack of research effort in this question feels pretty appalling)
    – gnat
    Commented Sep 4, 2014 at 18:17

6 Answers 6

2

While pointers often refer to memory addresses, the concept itself is separate. I'm going to focus on the underlying "low level" concept of memory addresses, since that's what you seem to be asking about.

Do the memory addresses point to places on the CPU itself, or anywhere in the computer?

While the term memory address can conceivably refer to part of the CPU's onboard memory, in this case it does not.

These addresses refer to the common "memory" of the computer, which is usually the RAM, but in modern OSes, may be abstracted away to be physical memory or some virtual memory that actually goes elsewhere. You'll also occasionally see memory addresses refer to memory off on a video card, or other hardware.

Is memory 'ordered' in hardware in some way that it makes sense to refer to it using an 'ordinal' number, such as 0x52A132F3?

Yes.

Even if the memory isn't strictly contiguous (see physical/virtual memory above, in addition to the different chips of RAM), the hardware and then the OS will abstract that away into something that looks like an infinitely long tape. That then is ordered memory that is addressable linearly.

Each address will then have a certain amount of data it can store (a byte is common, but not universal!). Different addressing schemes are possible of course, but would be inefficient since computers are really good at doing integer math.

7
  • So in most computers, the first adress is 0x0? And then adding 1 byte to it brings you to 0x1 (since each address stores a byte)?
    – Aviv Cohn
    Commented Sep 4, 2014 at 16:29
  • @prog - eh... yes, though in practical terms, 0x0 is generally reserved for null by the OS.
    – Telastyn
    Commented Sep 4, 2014 at 16:35
  • I see. Going a bit off topic here, but can you give me a reason you'd want to do pointer arithmetic in C? What can you do with it?
    – Aviv Cohn
    Commented Sep 4, 2014 at 16:38
  • 2
    @prog - that's a fairly broad subject. The simplest case would be the relation between pointers and arrays. A more useful case is when you want to work with some subset of a serialized structure (say, bytes 2 and 3 of your TCP header) as its own data (the destination port in this example). By using pointer trickery, you can avoid copying the subset out of the array it's in. There's a number of (mostly evil) things you can do with it.
    – Telastyn
    Commented Sep 4, 2014 at 16:42
  • 2
    @Prog: In C, array[value] is just syntactic sugar for *(array + value).
    – Rufflewind
    Commented Sep 5, 2014 at 4:27
10

On your motherboard, you have a CPU and a bunch of wires (called a bus) that go to your RAM, which comes separately on sticks that are relatively easy to replace. You can think of the memory address as controlling 32 of those wires. 0x52A132F3 translates to 01010010101000010011001011110011 in binary. Each 1 means the CPU puts a voltage (1.5 volts for DDR3) onto that corresponding wire, which tells the RAM chip which memory to send back to the CPU.

This is an oversimplification because of things like cache and virtual memory pages, and systems might support more or less than 4Gb of RAM, and so have more or fewer address wires, but it's a useful model for how to think about memory addresses, and simpler embedded systems work that way.

Hexadecimal is used because for a 32-bit number it is always 8 digits including possibly leading zeros. It's also easy to convert to binary. Also, you can write cool addresses like 0xDEADBEEF or 0xABBACAFE, which are sometimes useful for debugging. Mostly you can think of it as an index into a very big array of all the memory on your system.

1
  • A beautiful answer, which I presume would not have surfaced if not for @Prog's "unresearched" question. Thanks! Commented Sep 6, 2014 at 2:07
5

First, that a pointer contains a memory address is an implementation detail. That's not how it's defined in the standard. The standard works very, very hard to be vague with regards to the hardware so that C can run on the weirdest, most exotic architectures around. For example, you can't assume two pointers of different types have the same representation (except for char* and void*), or that pointers to objects have the same representation as pointers to functions.

To address your actual question:

  1. Memory addresses point to places in memory. Memory is external to the CPU.*
  2. A process sees memory as a continuous sequence of addressable units (usually 8-bit bytes). So, yes, you can compare memory addresses. As a side note, unless you're running on bare metal, the fact that a process has a continuous segment of memory to work with is just an illusion the OS provides. In reality the memory a process sees is mapped to different ranges of hardware memory and potentially disk space. In other words, memory address 1 for a process doesn't necessarily map to hardware address 1. You don't really need to concern yourself with this unless you want to know how OSs work.

In short, just think of memory as an array of bytes and a memory address as an index into that array.

*Yes, I know CPUs have caches.

1

I would put this in simpler analogy. If you send a letter you just put an address on envelop and put that in post box. But how is that actually going to the specific address? The PostMan (or the delivery boy) actually know what physical location those few lines written over the envelop turns to (assuming you haven't visited the location personally)

CPU works the same way and uses Memory Address to bring in data it needs to process. Here Memory Refers to RAM (the storage CPU refers to for processing data). CPU also have memory in itself called Registers that it uses for doing processing. And yes Memory Address are ordered and thats why CPU can access them randomly using the Memory Address and not loop through or go one by one to get an item in Memory.

1
  • 2
    Cache and Registers are two separate things. Cache is a small, fast copy of parts of RAM and may or may not actually be physically part of the CPU. The key points of it are being faster than RAM, being between the CPU and RAM, and (at least ideally) being synchronized with RAM. Registers are actually part of the CPU and are used for direct processing (some architectures can directly manipulate RAM with non load/store instructions). Registers can be directly manipulated by the programmer in Assembly. Cache is managed by the CPU, though careful planning can influence cache usage.
    – 8bittree
    Commented Sep 4, 2014 at 17:04
1

1. Do the memory addresses point to places on the CPU itself, or anywhere in the computer?

No. On all modern operating systems, virtual address spaces are used. Each program has its own address space. Pointer values are addresses in this address space. Addresses in this address space are mapped to physical memory by the OSes memory manager.

This mapping is sparse: only needed addresses are mapped. In addition, some addresses cannot be mapped to physical memory (think segmentation fault or general protection error).

This mapping is volatile: the same address may point to different parts of physical memory at different points in time.

2. Is memory 'ordered' in hardware in some way that it makes sense to refer to it using an 'ordinal' number, such as 0x52A132F3?

Not in a way that a program can rely on. The memory manager can map these addresses in any way it sees fit (see: Virtual Memory).

How is memory ordered in hardware,

Different computers will setup physical memory in different ways. The setup only needs to make sense to the memory manager.

and how and why does it make sense to access it using a numerical value?

The numerical values used by addresses make things easier. Think about arrays, using a numerical address, it's easy lookup the value at a particular index just by adding the base address and index (which is why most languages have arrays starting at 0).

This base address plus index calculation is called offsetting. Offsetting is use to get fields out of a structure, get parameter values of functions, looping, branching, and so much more. I have trouble imagining how computing would be done without numerical addresses.

1

mailing a letter is by far the best way to describe this, you have a name, number, street, town, zip code, maybe a suite number or other depending on where you live.

The letter leaves your house with all of this information on it and the post offices pick apart these items first leaving your house then some first level inspection to broadly figure out is it leaving this post office, is it leaving this town, etc. a number of decisions and sorts along the way to get it to the postal person for that street/area and they sort it by house then deliver it.

The processor and the programmer (you indirectly but with a significant amount of help from the operating system) are you in your house, you have some reference material (your address book) of addresses to things (well lets say the operating system does not necessarily you) some of these things are just ram some are peripherals or control and status registers, etc. there is some boundary in the processor or outside where this flatish address space lives, that boundary is your yard between your house and your mailbox on the curb. the address is tossed onto this bus and then the postman takes over, layers of logic pick apart the address to determine where it needs to go back into the chip or out to peripherals or memory on the board.

So generically yes address can point to things in the cpu and to things outside the cpu. Hardware designers generally dont like to make the work excessively difficult so usually one or a chunk of consecutive bits in the address are used to route the transaction. some high bits might determine on chip or off for example and then some next bits down might determine ram from peripherals, and then once routed to a periperhals some more bits down may determine where in the peripheral. there are also generally gaps do an lspci and look at the address ranges, just because a peripheral wants 32MB doesnt mean it has 32mb worth of individual things to talk to, it is just a nice power of 2 for logic to make decisions on once at the peripheral they may be wasteful if they choose with those bits for accessing a small number of things or efficient.

again the operating system, layered itself, has directly or indirectly the knowledge about that board and processor and generally hides it from you, you normally dont just poke a uart register, you instead call a function at the application layer which calls kernel functions which then eventually get to those registers that make the signals wiggle on the uart or whatever interface. mmus if you have one virtualize addresses so that your application or every application may feel like it starts at some address like 0x0000 and has 0x000 to N bytes of memory to itself so that all programs can be compiled the same way but a translation in hardware and software (operating system) convert your 0x1234 address to some other address before it hits that magic boundary where it leaves the house and hits the mailbox in the post office domain where they just follow the rules for delivery same way every time (hardware).

Not the answer you're looking for? Browse other questions tagged or ask your own question.