What is the difference between far pointers and nearest pointers?

Can someone tell me the difference between far pointers and near pointers in C?

+48
c pointers
Nov 17 '09 at 16:06
source share
6 answers

In x86 16-bit architecture, four registers are used to indicate the corresponding segments:

  • DS โ†’ data segment
  • CS โ†’ code segment
  • SS โ†’ stack segment
  • ES โ†’ additional segment

The logical address of this architecture is written segment:offset . Now, to answer the question:

  • Next to the pointers are referenced (as an offset) to the current segment.

  • Further pointers use segment information and offset to indicate segments. Therefore, to use them, DS or CS must be changed to the specified value, the memory will be dereferenced, and then the original DS / CS value will be restored. Please note that the arithmetic of pointers to them does not change the segmented part of the pointer, so offset overflow will simply wrap it.

  • And then there are huge pointers that are normalized to have the highest possible segment for a given address (as opposed to long pointers).

In 32-bit and 64-bit architectures, memory models use segments differently or do not work at all.

+42
Nov 17 '09 at 16:17
source share

Since no one mentioned DOS, forgot about the old DOS PC computers and looked at it from a general point of view. Then, very simplified, it looks like this:




Any processor has a data bus, which is the maximum amount of data that the processor can process in one command, i.e. equal to the size of its registers. The width of the data bus is expressed in bits: 8 bits or 16 bits or 64 bits, etc. This is where the term โ€œ64-bit processorโ€ comes from - this refers to the data bus.

Any processor has an address bus, as well as a specific bus width, expressed in bits. Any memory location on your computer that the CPU is directly accessible to has a unique address. The address bus is large enough to cover the entire address memory.

For example, if your computer has 65536 bytes of address memory, you can cover them with a 16-bit address bus, 2 ^ 16 = 65536.

Most often, but not always, the data bus width is wider than the address bus width. Itโ€™s nice if they are the same size, since it saves both the set of processor instructions and the programs written for it more clearly. If the CPU needs to calculate the address, it is convenient if this address is small enough to be placed inside the processor registers (often called index registers when it comes to addresses).

The non-standard keywords far and near are used to describe pointers on systems where you need to address memory beyond the normal processor address bus width.

For example, it may be convenient for a processor with a 16-bit data bus to also have a 16-bit address bus. But on the same computer, more than 2 ^ 16 = 65536 bytes = 64 KB of address memory may be required.

The processor will usually have special instructions (which are slightly slower), which allows it to address memory beyond these 64kb. For example, a CPU can split its large memory into pages n (also sometimes called banks, segments, and other such terms, which may mean different from one processor to another), where each page is 64 KB. It will then have a โ€œpageโ€ register, which must be set first before accessing this extended memory. Similarly, it will have special instructions when calling / returning from routines in extended memory.

In order for the C compiler to generate the correct CPU instructions when working with such extended memory, the non-standard keywords near and far were invented. Non-standard ones, as they are, are not specified by the C standard, but they are the actual industry standard, and almost every compiler somehow supports them.

far refers to memory located in extended memory outside the address bus width. Since this applies to addresses, most often you use it when declaring pointers. For example: int * far x; means "give me a pointer pointing to extended memory." And then the compiler finds out that it must generate special instructions necessary to access such memory. Similarly, function pointers that far use generate special instructions for navigating to / from extended memory. If you did not use far , you would get a pointer to regular, addressable memory, and you would end up pointing to something completely different.

near is mainly included for consistency with far ; it refers to anything in the address memory, which is equivalent to a regular pointer. Thus, this is basically a useless keyword, except in some rare cases when you want code to be placed in standard address memory. Then you can explicitly label something as near . The most typical case is low-level hardware programming, where you write interrupt service routines. They are called by hardware from a fixed-width interrupt vector that matches the width of the address bus. This means that the interrupt service routine must be in standard addressable memory.




The most famous use of far and near is perhaps the old MS DOS computer mentioned, which is currently considered quite ancient and therefore has little interest.

But these keywords exist on more modern processors! In particular, in embedded systems, where they exist for almost every 8 and 16-bit family of microcontrollers on the market, since these microcontrollers usually have an address bus width of 16 bits, but sometimes more than 64 KB of memory.

Whenever you have a processor where you need to address memory beyond the address bus, you will need far and near . As a rule, such decisions are not approved, since it is very painful to program on them and always take into account the extended memory.

One of the main reasons that arose the need to develop a 64-bit PC was, in fact, that 32-bit PCs reached the point where their memory usage began to hit the address bus limit: they can only access 4Gb of RAM. 2 ^ 32 = 4.29 billion bytes = 4 GB. To enable the use of more RAM, then it was necessary either to use some burdensome advanced memory solution, for example, in the days of DOS, or to expand computers, including the address bus, up to 64 bits.

+35
Jan 11 '16 at 15:45
source share

Far and near pointers were used on older platforms such as DOS.

I do not think they are relevant on modern platforms. But you can find out about them here and here (as indicated by other answers). Basically, the far pointer is a way to expand the address memory on a computer. IE, addresses more than 64 thousand. Memory on a 16-bit platform.

+22
Nov 17 '09 at 16:14
source share

The pointer basically contains addresses. As we all know, Intel's memory management is divided into 4 segments. Therefore, when the address pointed to by the pointer is inside the same segment, then it is the nearest pointer and therefore only 2 bytes are required for the offset. On the other hand, when the pointer points to an address that is outside the segment (which means in another segment), then this pointer is a far pointer. It consists of 4 bytes: two for the segment and two for the offset.

+4
Jan 29 '12 at 16:18
source share

Four registers are used to designate four segments in the 16-bit x86 segmented memory architecture. DS (data segment), CS (code segment), SS (stack segment), and ES (optional segment). The logical address on this platform is the recorded segment: offset, in hexadecimal format.

Next to the pointers are referenced (as an offset) to the current segment.

Further pointers use segment information and offset to indicate segments. Therefore, to use them, DS or CS must be changed to the specified value, the memory will be dereferenced, and then the original DS / CS value will be restored. Please note that the arithmetic of pointers to them does not change the segmented part of the pointer, so offset overflow will simply wrap it.

And then there are huge pointers that are normalized to have the highest possible segment for a given address (as opposed to long pointers).

In 32-bit and 64-bit architectures, memory models use segments differently or do not work at all.

0
Jan 08 '13 at 11:29
source share

Well, in DOS, it was fun to deal with registers. And segments. All about the maximum possibilities of counting RAM.

Today it almost does not matter. All you need to read is the difference between virtual / user space and the kernel.

Since win nt4 (when they stole ideas from * nix), Microsoft programmers started using what was called user / kernel memory spaces. And since then has avoided direct access to physical controllers. Since then, the problem has been resolved with direct access to memory segments. - Everything became R / W through the OS.

However, if you insist on understanding and manipulating far / near pointers, look at the source of the Linux kernel and how it works - you are likely to return, I think.

And if you still need to use CS (code segment) / DS (data segment) in DOS. Look at them:

https://en.wikipedia.org/wiki/Intel_Memory_Model http://www.digitalmars.com/ctg/ctgMemoryModel.html

I would like to point out the perfect answer below .. by Lundin. I was too lazy to answer correctly. Lundin gave a very detailed and reasonable explanation for thumbs!

0
Jan 11 '16 at 2:36 on
source share



All Articles