far pointer

M

Meenu

Hi,
Can two different far pointers contain two different addresses but
refer to the same location in memory?
 
E

Emmanuel Delahaye

Meenu wrote on 29/07/05 :
Can two different far pointers contain two different addresses but
refer to the same location in memory?

Your question is implementation-specific, hence off-topic on c.l.c.

<OT>
If you are referring to the x86 16-bit real mode, yes.
</>

--
Emmanuel
The C-FAQ: http://www.eskimo.com/~scs/C-faq/faq.html
The C-library: http://www.dinkumware.com/refxc.html

"There are 10 types of people in the world today;
those that understand binary, and those that dont."
 
K

Keith Thompson

Emmanuel Delahaye said:
Meenu wrote on 29/07/05 :

Your question is implementation-specific, hence off-topic on c.l.c.

<OT>
If you are referring to the x86 16-bit real mode, yes.
</>

If two pointers refer to the same location in memory, they contain the
same address, though they might contain two different representations
of the same address.

If "far pointers" don't work this way, they're not really pointers.
 
A

Alexei A. Frounze

Keith Thompson said:
If two pointers refer to the same location in memory, they contain the
same address, though they might contain two different representations
of the same address.

If "far pointers" don't work this way, they're not really pointers.

I'm more than sure that writing a 32-bit long using the following two far
pointers (pointing to the same physical memory) will yield different
results:
0x1000:0xFFFE
0x1FFF:0x000E
That's because of a wrap around about offset 0 in 1st case. The compiler
would normally not modify the segment part, hence the CPU will write to
physical addrs:
0x1FFFE,0x1FFFF,0x10000,0x10001
instead of:
0x1FFFE,0x1FFFF,0x20000,0x20001

Old borland C/C++ DOS compilers also have "huge" varieant of far pointers,
which I believe work very much like 32-bit physical addresses with obvious
limitations of the 16-bit real mode addressing scheme anyway.

Alex
 
S

Stan Milam

Grumble said:
There are no "far pointers" in ISO C.

On an unrelated note, have you read the FAQ list yet?
http://www.eskimo.com/~scs/C-faq/top.html

What he said. But, yes, they can be different, but they will ultimately
evaluate to the same address. How? One can be normalized and the other
non-normal, or you can have two non-normal with different segment/offset
combinations that result in the same absolute address.
 
M

Malcolm

Meenu said:
Hi,
Can two different far pointers contain two different addresses but
refer to the same location in memory?
In C we can compare two pointers for equality, and if they point to the same
address they will compare as equal.
However there is another restriction, which is that pointers must be
calculated within the object (array, to all intents and purposes) to which
they point. If you play silly games with absolute addresses or wild
calculations, you can defeat C's pointer representation, and it is posible
that two pointers may point to the same location, but have different bit
representations, and not compare as equal.

eg

/* OK */
int x[256];

int *ptr1 = x;
int *ptr2 = x + 128;

while(ptr2 != ptr1)
ptr2--;

/* silly game, may work as expected may go horribly wrong */
int x[128];
int y[128];

int *ptr1 = x;
int *ptr2 = y;

while(ptr2 != ptr1)
ptr2--;
 
K

Keith Thompson

Malcolm said:
In C we can compare two pointers for equality, and if they point to the same
address they will compare as equal.
However there is another restriction, which is that pointers must be
calculated within the object (array, to all intents and purposes) to which
they point. If you play silly games with absolute addresses or wild
calculations, you can defeat C's pointer representation, and it is posible
that two pointers may point to the same location, but have different bit
representations, and not compare as equal.

[example snipped]

Right. The requirement (like any semantic requirement) applies only
as long as you haven't invoked undefined behavior.
 
P

pete

Keith said:
Malcolm said:
In C we can compare two pointers for equality,
and if they point to the same address they will compare as equal.
However there is another restriction, which is that pointers must be
calculated within the object
(array, to all intents and purposes) to which
they point. If you play silly games with absolute addresses or wild
calculations, you can defeat C's pointer representation,
and it is posible
that two pointers may point to the same location,
but have different bit
representations, and not compare as equal.

[example snipped]

Right. The requirement (like any semantic requirement) applies only
as long as you haven't invoked undefined behavior.

I'm reading Malcolm as being wrong.
The restriction that pointers must be calculated within the object,
has nothing to do with comparing pointers for equality.
 
K

Keith Thompson

pete said:
Keith said:
Malcolm said:
Can two different far pointers contain two different addresses but
refer to the same location in memory?

In C we can compare two pointers for equality,
and if they point to the same address they will compare as equal.
However there is another restriction, which is that pointers must be
calculated within the object
(array, to all intents and purposes) to which
they point. If you play silly games with absolute addresses or wild
calculations, you can defeat C's pointer representation,
and it is posible
that two pointers may point to the same location,
but have different bit
representations, and not compare as equal.

[example snipped]

Right. The requirement (like any semantic requirement) applies only
as long as you haven't invoked undefined behavior.

I'm reading Malcolm as being wrong.
The restriction that pointers must be calculated within the object,
has nothing to do with comparing pointers for equality.

I didn't take a very close look at the example, but I think it
involved setting a pointer to the beginning of an array object and
then decrementing it.

If you want to compare two pointer values using "<", "<=", ">", or
">=", both pointers must point into the same object (or just past the
end of it). If you want to compare two pointer values using "=" or
"!=", they just both have to be valid, i.e., each has to point into
*some* object, not necessarily the same one (or just past the end of
some object, and there's a special case allowing two objects to be
adjacent).

I'm not sure whether that's what Malcolm was referring to.
 
P

pete

If two pointers point to the same location,
they will compare equal regardless of whether or not
the bit patterns are the same.
[example snipped]

Right.
The requirement (like any semantic requirement) applies only
as long as you haven't invoked undefined behavior.

I'm reading Malcolm as being wrong.
The restriction that pointers must be calculated within the object,
has nothing to do with comparing pointers for equality.

I didn't take a very close look at the example, but I think it
involved setting a pointer to the beginning of an array object and
then decrementing it.

If you want to compare two pointer values using "<", "<=", ">", or
">=", both pointers must point into the same object (or just past the
end of it). If you want to compare two pointer values using "=" or
"!=", they just both have to be valid, i.e., each has to point into
*some* object, not necessarily the same one (or just past the end of
some object, and there's a special case allowing two objects to be
adjacent).

I'm not sure whether that's what Malcolm was referring to.
 
G

Gordon Burditt

In C we can compare two pointers for equality,
If two pointers point to the same location,
they will compare equal regardless of whether or not
the bit patterns are the same.

If two pointers *that you could create without invoking undefined
behavior* point to the same location, they will compare equal
regardless of whether or not the bit patterns are the same.

That means that if you are working with a x86 machine in real mode,
with 16-bit segment and 16-bit offset, and you're allowing objects
larger than 64k, that you (the implementor) have to do somewhat
complicated and slow code to do pointer math, and you probably have
to normalize two pointers as part of comparing them for equality.

If, on the other hand, you do NOT allow objects larger than 65535
bytes, the implementation can just do simple pointer math (involving
only the offset), and as long as the implementation doesn't allow
a legitimate way to GET pointers to the same object with different
segment register contents, and comparison can just do a bit-by-bit
comparison (although for equality it still has to compare 32 bits.

Gordon L. Burditt
 
M

Malcolm

pete said:
I'm reading Malcolm as being wrong.
The restriction that pointers must be calculated within the object,
has nothing to do with comparing pointers for equality.
Example restored.

/* OK */
int x[256];

int *ptr1 = x;
int *ptr2 = x + 128;

while(ptr2 != ptr1)
ptr2--;

/* silly game, may work as expected may go horribly wrong */
int x[128];
int y[128];

int *ptr1 = x;
int *ptr2 = y;

while(ptr2 != ptr1)
ptr2--;

These could easily compile to exactly the same machine code.
What the hacker who wrote the second example is relying on is that array y
is probably next to array x in memory. As he decrements, ptr2 will
eventually count down to ptr1, which is the start of x. If we write a value
as we loop, array x will be set.
Unfortunately, it could happen that x and y are in different segments on a
DOS machine. Therefore the array will be set, as before, but the loop won't
terminate properly because ptr1 and ptr2 don't compare as equal, despite
pointing to the same physical location. This only happens because we've
managed to defeat C's pointer management system. It can't happen if we do
things properly, as in example 1.
 
C

CBFalconer

Malcolm said:
pete said:
I'm reading Malcolm as being wrong.
The restriction that pointers must be calculated within the
object, has nothing to do with comparing pointers for equality.
Example restored.

/* OK */
int x[256];

int *ptr1 = x;
int *ptr2 = x + 128;

while(ptr2 != ptr1)
ptr2--;

/* silly game, may work as expected may go horribly wrong */
int x[128];
int y[128];

int *ptr1 = x;
int *ptr2 = y;

while(ptr2 != ptr1)
ptr2--;

These could easily compile to exactly the same machine code.
What the hacker who wrote the second example is relying on is that
array y is probably next to array x in memory. As he decrements,
ptr2 will eventually count down to ptr1, which is the start of x.
If we write a value as we loop, array x will be set.

Unfortunately, it could happen that x and y are in different
segments on a DOS machine. Therefore the array will be set, as
before, but the loop won't terminate properly because ptr1 and ptr2
don't compare as equal, despite pointing to the same physical
location. This only happens because we've managed to defeat C's
pointer management system. It can't happen if we do things properly,
as in example 1.

It's worse than that, and doesn't require segmented memory. There
is no guarantee, even given a stack machine (which we are not) that
x is assigned space above (or below) y. It is likely (but again not
guaranteed) that one of those two cases will apply.

On the DS9000 the direction is the opposite of whatever you test,
and all i/o is memory mapped. There is no memory access violation
for this run. The act of pointing to an i/o location causes a
default set of 1's to be written for efficiency reasons. A 1 bit
launches a missile. For safety reasons the designers have required
confirmation with a matching 1 bit in the 127 adjacent locations.
Now, if you guess wrong, all missiles are launched.
 
P

pete

Gordon said:
If two pointers *that you could create without invoking undefined
behavior* point to the same location, they will compare equal
regardless of whether or not the bit patterns are the same.

That means that if you are working with a x86 machine in real mode,
with 16-bit segment and 16-bit offset, and you're allowing objects
larger than 64k, that you (the implementor) have to do somewhat
complicated and slow code to do pointer math, and you probably have
to normalize two pointers as part of comparing them for equality.

Probably?
Are you aware that you're giving off topic advice
while admitting that you don't know what you're talking about?
 
G

Gordon Burditt

If two pointers point to the same location,
Probably?
There are circumstances in which the compiler could know it didn't
have to normalize one or both pointers, such as if one was just
set to a known value. Or perhaps no comparison would be needed
at all as the result is already known. Pointer normalization isn't
the only possible approach, either. You could convert one segment
register to match the other one (computing 32-bit offsets temporarily)
or subtract them (32-bits with a special carry/borrow propagation).

Are you aware that you're giving off topic advice
while admitting that you don't know what you're talking about?

Why is talking about the requirements of ANSI C as applied to a
specific platform off-topic?

Gordon L. Burditt
 
P

pete

Gordon said:
There are circumstances in which the compiler could know it didn't
have to normalize one or both pointers, such as if one was just
set to a known value. Or perhaps no comparison would be needed
at all as the result is already known. Pointer normalization isn't
the only possible approach, either. You could convert one segment
register to match the other one (computing 32-bit offsets temporarily)
or subtract them (32-bits with a special carry/borrow propagation).


Why is talking about the requirements of ANSI C as applied to a
specific platform off-topic?

Because having to normalize pointers for comparison
is not part of ANSI C.
 
G

Gordon Burditt

If two pointers point to the same location,
Because having to normalize pointers for comparison
is not part of ANSI C.

It is if that's how the implementation has to do pointer comparisons
in order to satisfy the requirements of ANSI C. Now, if you can't
GET two pointers that point to the same place but have unequal bit
patterns without invoking undefined behavior, it's not an issue.

This might happen if pointer math always does the normalization.
It might also happen if pointer math operates on only the offsets,
and objects can be no bigger than 64k. But if you're trying to
support large objects, things get messier. There's a tradeoff in
how you do pointer math, how you do pointer comparisons, and object
size restrictions. Pointer comparisons are generally done less
frequently than pointer math.

Gordon L. Burditt
 
L

Lawrence Kirby

If two pointers refer to the same location in memory, they contain the
same address, though they might contain two different representations
of the same address.

However they only have to compare equal if they were created using valid C
contructs. It may be that in strictly conforming programs it is only
possible on an implementation to construct pointers to a particular
object in one form. If it was possible to construct alternative forms of
pointer to the same object using extensions they would not have to compare
equal for implementation conformance.
If "far pointers" don't work this way, they're not really pointers.

Since C has no concept of far pointers this is an implementation detail.
Clearly using extensions such as a "far" keyword in the source code are
not valid in standard C. However "normal" C pointers can typically be
implemented as "far pointers" on compilers that support them using
appropriate compile options (commonly referred to as the memory model). In
that case if the compiler claims conformance normal pointers (implemented
as far pointers) must behave correctly in well-defined code. However I'm
not sure to what degree that the compilers that supported these memory
models actually claimed conformance. If they didn't then they could
implement pointers however they like and may not stick to standard C
semantics where that would prove awkward.

Lawrence
 
J

Joe Wright

CBFalconer said:
Malcolm said:
I'm reading Malcolm as being wrong.
The restriction that pointers must be calculated within the
object, has nothing to do with comparing pointers for equality.

Example restored.

/* OK */
int x[256];

int *ptr1 = x;
int *ptr2 = x + 128;

while(ptr2 != ptr1)
ptr2--;

/* silly game, may work as expected may go horribly wrong */
int x[128];
int y[128];

int *ptr1 = x;
int *ptr2 = y;

while(ptr2 != ptr1)
ptr2--;

These could easily compile to exactly the same machine code.
What the hacker who wrote the second example is relying on is that
array y is probably next to array x in memory. As he decrements,
ptr2 will eventually count down to ptr1, which is the start of x.
If we write a value as we loop, array x will be set.

Unfortunately, it could happen that x and y are in different
segments on a DOS machine. Therefore the array will be set, as
before, but the loop won't terminate properly because ptr1 and ptr2
don't compare as equal, despite pointing to the same physical
location. This only happens because we've managed to defeat C's
pointer management system. It can't happen if we do things properly,
as in example 1.


It's worse than that, and doesn't require segmented memory. There
is no guarantee, even given a stack machine (which we are not) that
x is assigned space above (or below) y. It is likely (but again not
guaranteed) that one of those two cases will apply.

On the DS9000 the direction is the opposite of whatever you test,
and all i/o is memory mapped. There is no memory access violation
for this run. The act of pointing to an i/o location causes a
default set of 1's to be written for efficiency reasons. A 1 bit
launches a missile. For safety reasons the designers have required
confirmation with a matching 1 bit in the 127 adjacent locations.
Now, if you guess wrong, all missiles are launched.
Sounds like the Safety mechanism still needs work. The Security side is
rock solid. There is no way to find out where the launching missles are
coming from or where they are going. :)
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
474,169
Messages
2,570,915
Members
47,456
Latest member
JavierWalp

Latest Threads

Top