An effective address is the value which is used by a fetch or store operation to specify which memory location is to be accessed by the operation from the perspective of the entity (i.e. process, thread, interrupt handler, kernel component, etc) issuing the operation.

For example:

  • if a register contains the value 10000 and an instruction is executed which fetches the contents of the memory location specified by the contents of the register then the effective address for the fetch operation is 10000.

  • if a register contains the value 10000 and an instruction is executed which stores a value into the memory location which is 120 memory locations beyond the location specified by the contents of the register then the effective address for the store operation is 10120.
From a slightly different perspective:
  • if an instruction fetches the contents of the variable called A then the effective address of the fetch operation is the address of the variable called A from the perspective of the entity issuing the fetch operation.

  • if an instruction stores a value into the contents of the tenth element of the array called V then the effective address of the store operation is the address of the tenth element of the array called V from the perspective of the entity issuing the store operation.

  • if an instruction stores a value into the contents of the memory location specified by the pointer variable called P then the effective address of the store operation is the contents of the pointer variable called P.
Note the use of the phrase "from the perspective of the entity issuing the xxx operation" in the first two of the last set of three examples. Memory locations accessible by multiple entities don't necessarily have the same effective address when considered from the perspective of each of the entities. For example, two processes might share a region of memory between them. Although care is generally taken to avoid the situation, it is possible to share a memory region such that the address of the region is not the same for all particpants. In such a situation, the effective address of each memory location in the shared region will be different depending upon which entity is accessing the location. Hence, in the general case, the effective address of a memory location is only meaningful if specified from the perspective of a particular entity capable of accessing the location1.

Effective addresses and the concept of virtual memory

If a processor doesn't support the concept of virtual memory or if the virtual memory feature is currently disabled (i.e. turned off) when a fetch or a store operation is issued by the processor then the effective address of the operation is equal to the physical address of the location in the processor's physical memory (i.e. DRAM, core, SRAM, whatever).

On the other hand, if a processor supports the concept of virtual memory and the virtual memory feature is enabled (i.e. turned on) when a fetch or a store operation is issued by the processor then the effective address of the operation is translated by the processor's memory mapping unit into a physical address which specifies the location in the processor's physical memory which is accessed by the operation.

Why the "effective address" term exists

The "effective address" term is a coined term which was coined to unambiguously describe the concept defined in the first paragraph of this writeup.

The "effective address" term would have almost certainly been coined to replace the more common but ambiguous "virtual address" term. Although the term "virtual address" may have been unambiguous when it was itself "coined", it has become ambiguous because hardware engineers and software developers have been using the term in ambiguous ways for at least the past thirty years (the uncertainty in this paragraph exists because the author of this writeup wonders if it is possible that the "effective address" term was defined before the concept of "virtual memory" even existed).

For example, one relatively common definition of "virtual address" is

the address which is translated to a physical address by the virtual address mapping facility
This definition of "virtual address" is essentially equivalent to the definition of "effective address", as defined and used by this writeup, when a system is running with virtual address mapping turned on (e.g. a Unix system whenever a user-level process is executing). Unfortunately, this writeup's definition of "effective address" encompasses more than the above definition of "virtual address' (i.e. the two are different concepts).

Another definition of "virtual address" can be found in IBM's official description of how a PowerPC processor maps effective addresses into physical addresses. Briefly, on a 32-bit PowerPC processor (or a 64-bit PowerPC processor operating in 32-bit mode), the 32-bit effective address is first translated into a 52-bit address which is then translated into a physical address (the size of the physical address depends on exactly which version of PowerPC processor is being used).

IBM's official documentation for how this translation works uses the term "virtual address" to refer to this intermediate 52-bit address. I.e. within the PowerPC processor context, IBM's definition of "virtual address" is fundamentally incompatible with their definition of "effective address" (IBM's use of this definition of "virtual memory" is quite similar if not equivalent to definitions of "virtual memory" used by a number of other hardware vendors). On the other hand, IBM's definition of "effective" address in the PowerPC context is identical to this writeup's definition of "effective address".

The bottom line is quite simple: regardless of whether or not it might have been unambiguous at one time in the past, the term "virtual address" is now an ambiguous term in the context of virtual memory.

It should be noted that even if the term "virtual address" were unambiguous, there would still be a need for the term "effective address" as the term "virtual address" makes little sense in a context in which the processor either doesn't support the concept of virtual memory or the virtual memory feature is disabled.


1It can actually get even more complicated as a region of memory can, in many hardware and software implementations, be "visible" to a single process at more than one place in the process's memory space. The result is that each of the the memory locations in the region would have more than one effective address from the perspective of the process.

The following program attempts to demonstrate this situation (it may not succeed depending on details of how shmat is implemented on a particular system):

#include <stdio.h>
#include <sys/ipc.h>
#include <sys/shm.h>

main()
{
    int shmid;
    void *addr1, *addr2;

    /* Allocate a shared memory segment of at least 100 bytes */

    shmid = shmget( IPC_PRIVATE, 100, IPC_CREAT | 0600 );
    if ( shmid == -1 ) {
        perror("shmget failed");
        exit(1);
    }

    /*
     * Attach the shared memory segment at an arbitrary location
     * in our address space
     */

    addr1 = shmat( shmid, NULL, 0 );
    if ( ((long)addr1) == -1 ) {
        perror("shmat 1 failed");
        exit(1);
    }

    /*
     * Attach the same shared memory segment again at an arbitrary
     * location in our address space
     */

    addr2 = shmat( shmid, NULL, 0 );
    if ( ((long)addr2) == -1 ) {
        perror("shmat 2 failed");
        exit(1);
    }

    /*
     * Did we get two different locations?
     */

    if ( addr1 == addr2 ) {

        printf("addr1 is equal to addr2 (0x%p)\n",addr1);

    } else {

        printf("addr1 is 0x%p and addr2 is 0x%p\n",addr1,addr2);
        strcpy((char *)addr1,"one");
        strcpy((char *)addr2,"two");
        printf("value at addr1 is \"%s\"\n",addr1);

    }
    exit(0);
}
If the output of this program is something along the lines of:
addr1 is 0x0x40017000 and addr2 is 0x0x40018000
value at addr1 is "two"
then the shared memory segment associated with shmid has two different effective addresses from the perspective of the process as evidenced by the fact that storing a value (i.e. the string "two") into the location referred to by addr2 has changed the data at the location referred to by addr1.

If the output is along the lines of:

addr1 is equal to addr2 (0x40017000)
then the underlying operating system has returned the same address from both calls to shmat (it isn't clear to me if such an implementation would be "correct").

If the output is something along the lines of:

addr1 is 0x0x40017000 and addr2 is 0x0x40018000
value at addr1 is "one"
then something truly bizarre has happened (probably at the hardware level with possible causes including a cache coherency problem or a "broken" / "unusual" implementation of virtual memory).

Log in or register to write something here or to contact authors.