Near and Far Pointers

Near and Far pointers

The near and far keywords have their origin in the segmented memory model that Intel had before. The near pointers could only access a block of memory originally around 64Kb in size called a segment whereas the far pointers could go outside of that range consisting of a segment and offset in that segment. The near pointers were much faster than far pointers so therefore in some contexts it paid off to use them.

Nowadays with virtual memory near and far pointers have no use.

EDIT:Sorry if I am not using the correct terms, but this is how I remembered it when I was working with it back in the day :-)

What is the difference between far pointers and near pointers?

On a 16-bit x86 segmented memory architecture, four registers are used to refer to the respective segments:

  • DS → data segment
  • CS → code segment
  • SS → stack segment
  • ES → extra segment

A logical address on this architecture is written segment:offset. Now to answer the question:

  • Near pointers refer (as an offset) to the current segment.

  • Far pointers use segment info and an offset to point across segments. So, to use them, DS or CS must be changed to the specified value, the memory will be dereferenced and then the original value of DS/CS restored. Note that pointer arithmetic on them doesn't modify the segment portion of the pointer, so overflowing the offset will just wrap it around.

  • And then there are huge pointers, which are normalized to have the highest possible segment for a given address (contrary to far pointers).

On 32-bit and 64-bit architectures, memory models are using segments differently, or not at all.

What are near, far and huge pointers?

In the old days, according to the Turbo C manual, a near pointer was merely 16 bits when your entire code and data fit in the one segment. A far pointer was composed of a segment as well as an offset but no normalisation was performed. And a huge pointer was automatically normalised. Two far pointers could conceivably point to the same location in memory but be different whereas the normalised huge pointers pointing to the same memory location would always be equal.

How to determine sizeof farpointer against near pointer?

Most modern operating systems use a flat memory model instead of a segmented memory model. This means that all pointers are large enough to point to the entire virtual address space of a process. For this reason, far pointers are no longer necessary and very uncommon nowadays.

This used to be different. 30 years ago, common consumer hardware was 16-bits which means that a far pointer consisted of a 16-bit segment pointer and a 16-bit offset pointer. That way, it was theoretically possible for a 16-bit system to address up to 4 GB of memory (which normally requires a 32-bit pointer).

Since you referred to the documentation of your Intel processor, I will make some further remarks about the current state of the x86/x64 architecture:

In 64-bit "long" mode, the segment registers CS, DS, ES and SS are forced to 0, so that segmentation is not possible. Only the FS and GS segment registers can still be used for segmented memory access (i.e. as part of a far pointer). However, both under Windows and Linux, these segment registers are not available to the common application programmer. They are only used internally by the operating system. See this link for further information.

This effectively means that, unless you want to write code for an actual operating system (or maybe a kernel-mode driver), you will never have to worry about far pointers. It is possible that your compiler does not even implement them.

far pointer declaration in Visual Studio

far was a keyword in the 16 bit Microsoft compiler (and possibly other old compilers). Nowadays in the 32/64 bit world this keyword has become obsolete and useless.

Normally the Windows header files define far as expanding to nothing.

If you include windows.h your code should compile.

If you cannot or don't want to include windows.h, you can just add #define far in your file or whatever appropriate header file of your project.

Or best remove far manually from your source files.

Related Topics

Leave a reply