Referring to memory addresses in C

Thread Starter

richard3194

Joined Oct 18, 2011
193
Hi. I'm pretty much an absolute beginner in programming. I've ordered a book for absolute beginners. But, before it arrives I wonder about how a programmer references a memory location in C.

Here is where I'm at: In the olden days, because the address register was only 16 bits, the maiximum addressable memory
was 64KB. Then came in Segmentation & Offset which allowed up to 1MB of addressable memory with a 16 bit register.

BEFORE SEGMENT & OFFSET
If a programmer needed to reference a specific memory address, or a range of addresses, I presume that they used hexadecimal notation. That is, say, something like FFFD in code (or FFFDh). Unless a decimal number was acceptable.

AFTER SEGMENT & OFFSET
If a programmer needed to reference a specific memory address, or a range of addresses, I presume they used Segment & Offfset notation. That is, say, something like 0000:FFFD or F000:FFFD in code. Unless a decimal number was acceptable.

I wonder also, could a programmer put the result of adding the segement and offset, such as FFFFD (after segement .* 16) to reference a memory address?

I'm really a beginner because I don't even know if programmers still rely on Segment & Offset today. I suppose so, if the appropriate MCU register is 16 bits. Unless something has superseded Segment & Offset. I suppose this must be the case, for how could a MCU address say a 8MB SD card.

Thanks for any assistance rendered. Richard
 
Last edited:

MrChips

Joined Oct 2, 2009
34,632
First of all it is a misconception and misunderstanding that the address has to be in hexadecimal notation.

You can enter the address in any notation you choose, binary, decimal, or hexadecimal, as long as you follow the rules of the compiler to indicate to the compiler which notation you are using. The usage of different number notations makes no difference to the compiler. The purpose of different notations benefits human programmers only. The bottom line is all numbers are converted to binary in the computer.

The usage of segment & offset is a function of the compiler and whether the compiler is limited to 64k memory segments.
Compilers that I am familiar with have no limitation and addresses can occupy 64-bit address space.
 

dl324

Joined Mar 30, 2015
18,226
I'm really a beginner because I don't even know if programmers still rely on Segment & Offset today. I suppose so, if the appropriate MCU register is 16 bits. Unless something has superseded Segment & Offset. I suppose this must be the case, for how could a MCU address say a 8MB SD card.
Memory segmentation pretty much became a non-issue in the 80's when the addressing range was extended beyond 16 bits. In the early 2000's, we were hitting the 2GB limits because sizes were using signed 32 bit integers. Now that limitation is gone.
 

John P

Joined Oct 14, 2008
2,051
I assume you're working on a real computer, and not a microcontroller. If you're writing code for a computer, you basically don't have to care about actual memory addresses, because your compiler and operating system will do all that for you. If you have a program that works with a predictable amount of data, you simply set up arrays of defined size, and address them by index within the array, without caring about where the data actually goes in the computer's memory space. If you have variable amounts of data, you can use dynamically allocated memory, which the program can use as needed and then discard. But even then, you probably won't care what the actual memory address is, and you certainly can't expect it to be the same every time the program runs.
 

MrSoftware

Joined Oct 29, 2013
2,273
What platform are you coding for? The answer to your question is somewhat platform dependent. These days, if you're coding an application that runs in user space for a modern 64-bit intel processor running an OS such as windows or linux, the memory space is virtualized anyway so you just use the address that you want to access. For example if you want to access the byte at 12GiB, then just use the address 0x300000000.

If you're writing low level kernel code, or for a microcontroller or some other processor then the answer might be different.
 

bogosort

Joined Sep 24, 2011
696
C itself is mostly agnostic when it comes to memory addressing, as memory addresses are just numbers. Since variables are essentially just human-friendly identifiers associated with various memory addresses, C lets us store, read, and write memory addresses using variables. For instance, in the code below I associate the pointer 'p' with the memory address 0x600960 and then write to it:

C:
#include <stdio.h>

char foo[] = "hello";

int main(void)
{
  unsigned char *p = (unsigned char *)0x600960;

  printf( "foo equals: %s\n", foo );
  printf( "address of foo: %p\n", &foo );

  *p = 'j';

  printf( "foo now equals: %s\n", foo );

  return 0;
}
Running this on my x64 Linux box results in:

Code:
foo equals: hello
address of foo: 0x600960
foo now equals: jello
The real question is which platform you're compiling for, namely, whether the C implementation is hosted (by an OS) or freestanding ("bare metal"). In most hosted environments, the processor can't/won't give you access to the raw memory. Instead, you'll be interfacing through a virtual memory system with several layers of hardware and software abstraction. Each program will be mapped to its own identical virtual memory space (e.g., they'll all start at 0x400000) and any addresses you deal with will be virtual. The upshot is that you can't do any damage (other than generate a bunch of SEGFAULTs); the downside is that doing interesting things with hardware requires help from kernel land.

On the other hand, in freestanding environments -- such as in simple MCUs or in certain privileged modes in hosted environments -- reading/writeing from raw memory is straightforward, as far as C is concerned. The details will all depend on the actual hardware you're compiling for.
 

Thread Starter

richard3194

Joined Oct 18, 2011
193
Hi. In my early foray into computing memory, I've come across Segment and Offset from a microprocessor (PC) perspective. But, actually, my main interest is in MCU's (I'm wanting to eventually design something using an MCU). So, given MCU's are my main focus, the thought occurs to me, is Segmentation and Offset still in use, considering we can buy 8 and 16 bit MCU's. Also, I am aware that today we might want to use memory beyond 1 MB, so, I wonder, does that mean Segmentation and Offset is no good when you wish to use memory beyong 1MB capacity. With an MCU.
 
Last edited:

MrChips

Joined Oct 2, 2009
34,632
Segmentation & offset was the common memory architecture with Intel 8086 microprocessors.

Embedded microcontrollers are designed to get the job done with minimum amount of hardware. You don't have to worry about memory addressing.
For a small MCU, the addressing space will match the amount of memory required for the application. When the application requires more memory, you will choose an MCU that supplies the amount of memory required. The MCU will provide the appropriate linear addressing space. Memory segmentation is a anomaly of the past and should have been buried a long time ago.
 

Thread Starter

richard3194

Joined Oct 18, 2011
193
Hi. So, when I progress a bit further and start getting to know about and program any modern MCU 8 bit, 16 bit, I will not be using segment and offset notion. Even when memory capacity of the memory chip is above 1MB. In cases where I might want to specify a memory address.

And from what I gather if a memory address is wriiten or returned, it will likely be in the notation:

0x600960 (for example)
 
Last edited:

bogosort

Joined Sep 24, 2011
696
And from what I gather if a memory address is wriiten or returned, it will likely be in the notation:

0x600960 (for example)
As MrChips said, the representation (base) of the number doesn't matter; it's just generally easier to use hexadecimal than other bases when writing out big numbers, such as typical memory addresses.
 

Thread Starter

richard3194

Joined Oct 18, 2011
193
What I'm thinking is this: Segmentation and Offset was created to allow access to 1Mb of memory with only 16 bit registers. That had an impact on the notation used by the programmer, inasmuch as he/she could start writing in the form F000:FFFD (as example) in the compiler. But, that it is just as easy to write 0xFFFFD or FFFFDh as the address. In cases where one might want to specify a particular byte address.

Now, it has been said that Segmentation and Offset is a defunct way of specifying a memory address.

So, as to MCU's I think we might consider two options:

1) If the approriate MCU register is only 16 bits, we access memory above 1MB by some scheme that in NOT Segmentation and Offset.

OR

2) We simply select an MCU that has a register than allows access to 1MB of memory and above.

Somewhere along the line I'll be getting to SD cards, which have lots of memory capacity. How is so much memory accessed. Some in the GB of memory.
 
Last edited:

WBahn

Joined Mar 31, 2012
32,714
Hi. I'm pretty much an absolute beginner in programming. I've ordered a book for absolute beginners. But, before it arrives I wonder about how a programmer references a memory location in C.

Here is where I'm at: In the olden days, because the address register was only 16 bits, the maiximum addressable memory
was 64KB. Then came in Segmentation & Offset which allowed up to 1MB of addressable memory with a 16 bit register.

BEFORE SEGMENT & OFFSET
If a programmer needed to reference a specific memory address, or a range of addresses, I presume that they used hexadecimal notation. That is, say, something like FFFD in code (or FFFDh). Unless a decimal number was acceptable.

AFTER SEGMENT & OFFSET
If a programmer needed to reference a specific memory address, or a range of addresses, I presume they used Segment & Offfset notation. That is, say, something like 0000:FFFD or F000:FFFD in code. Unless a decimal number was acceptable.

I wonder also, could a programmer put the result of adding the segement and offset, such as FFFFD (after segement .* 16) to reference a memory address?

I'm really a beginner because I don't even know if programmers still rely on Segment & Offset today. I suppose so, if the appropriate MCU register is 16 bits. Unless something has superseded Segment & Offset. I suppose this must be the case, for how could a MCU address say a 8MB SD card.

Thanks for any assistance rendered. Richard
Segment:Offset was how a particular company handled address limitations on particular families of microprocessors (most notably the Intel 8086 and its near descendants).

Some microcontrollers have similar issues, particularly 8-bit microcontrollers. How it is dealt with depends on the MCU family. Some MCU's have a "page" register and writing code for such MCU's (especially in Assembly) can be challenging).
 

bogosort

Joined Sep 24, 2011
696
2) We simply select an MCU that has a register than allows access to 1MB of memory and above.

Somewhere along the line I'll be getting to SD cards, which have lots of memory capacity. How is so much memory accessed. Some in the GB of memory.
Option 2) is the way to go. If you'll be accessing large memory spaces, there are several excellent 32-bit MCUs that will make it easy and natural to do. A nice starter development board is the Teensy line, which integrate a 32-bit ARM MCU and several peripheral devices. Development can be done in the user friendly Arduino IDE, with all the libraries and support that comes with it.

https://www.pjrc.com/teensy/
 

MrSoftware

Joined Oct 29, 2013
2,273
Someone correct me if I'm mistaken, but I would expect any modern MCU to have plenty of address space to address all of the on-chip memory. It's when you add relatively large external memory modules that have memory locations too large to address with the native processor register size that things might get more complicated. I haven't worked with any 8-bit MCU's, but my guess is they are typically used for really basic things that aren't expected to require a lot of memory.
 

MrChips

Joined Oct 2, 2009
34,632
When accessing data on the SD card, you need not worry about segment and offset. You will access a file as if it were a hard disk drive and will most likely be using a library function supplied by the MCU manufacturer or IDE platform supplier. At the basic level, you will supply a starting address and the number of memory blocks you wish to access.
 

MrChips

Joined Oct 2, 2009
34,632
Someone correct me if I'm mistaken, but I would expect any modern MCU to have plenty of address space to address all of the on-chip memory. It's when you add relatively large external memory modules that have memory locations too large to address with the native processor register size that things might get more complicated. I haven't worked with any 8-bit MCU's, but my guess is they are typically used for really basic things that aren't expected to require a lot of memory.
+1.
That is what I said before. For small MCUs you have enough memory space to get the job done, typically 1KB to 64KB of memory. When you need more memory you go to a higher end MCU that may have as much as 1MB memory. When you have large memory storage requirements, e.g. data logging, you can add SD cards and you use file access library functions to read/write to the card. The advantage here is you can remove the card for data access and insert a new card at your convenience.
 

Thread Starter

richard3194

Joined Oct 18, 2011
193
Hi. Are we saying then, that if I wanted to access 4GB of SD memory I'd be looking to buy an MCU with a 32 bit address register? Inasmch as a 32 bit address register can access 4GB without any special arrangements? Or, does use of an SD card allow one to not think that way? I'm in a world where the size of an address register is determining the address space. And where an address is a byte address.
 
Last edited:

MrChips

Joined Oct 2, 2009
34,632
Hi. Are we saying then, that if I wanted to access 4GB of memory I'd be looking to buy an MCU with a 32 bit address register? Inasmch as a 32 bit address register can access 4GB without any special arrangements? Or, does use of an SD card allow one to not think that way? I'm in a world where the size of an address register is determining the address space.
Why do you need 4GB of memory on an MCU?

If you need an SD card, you will buy an MCU that has an SD card interface. It doesn't matter if it is an 8-bit MCU or a 64-bit MCU. The SD card interface will take care of the addressing.
 

Thread Starter

richard3194

Joined Oct 18, 2011
193
Aah, that information about it doesn't matter whether it's an 8 bit MCU or 64 bit MCU if the MCU has a SD card interface is exactly what I needed to tease out. I would not have guessed that from the little I know about memory addressing. My project involves audio. In reality I might need 4MB of SD memory.. Thanks.
 

MrChips

Joined Oct 2, 2009
34,632
Aah, that information about it doesn't matter whether it's an 8 bit MCU or 64 bit MCU if the MCU has a SD card interface is exactly what I needed to tease out. I would not have guessed that from the little I know about memory addressing. My project involves audio. In reality I might need 4MB of SD memory.. Thanks.
Think of an SD card like an old fashioned audio tape recording machine. It doesn't matter how long is the recording tape. You tell the interface where the data begins and how many blocks of data you need to read or write.
 
Top