Problem with array objects

P

Paul

Leigh Johnston said:
As usual you start mixing terminology to try and hide the fact that you
have been proven wrong; you are the one trying to equate C++ pointers with
array objects (in your C++ code and assembly output that you have
conveniently snipped from your subsequent reply).

What you call an "assembly code pointer" is actually just an integer
constant which is added to the stack frame pointer in order to obtain a
value off the stack. This same mechanism is used to obtain the value of
any type of object not just arrays. Basically you don't know what you are
talking about.

Thats what a pointer is in assembly is just a varaible that stores an offset
value.
 
T

Thomas David Rivers

Paul said:
So - do we agree that an array is a contigous set of like-typed
elements,
where the elements are accessed via the []-operator?
Yes I aggree with that.

So - next let's examine a rather simple declaration of an array in C/C++.

int arr[5];

What does this define.

This defines a contiguous set of 5 `int' elements. The name of that set
is 'arr'.

What is the type of 'arr'? It is an array of 5 'int' elements.

What is 'arr'?

'arr' represents, at execution time, a set of 5 contigous 'int'
elements. The name 'arr'
is used to refer to the runtime location of that set of elements. We
can colloquially
use the term, the "address" of the set of 5 contiguous 'int' elements
when we talk
about the runtime location of the set of 5 contiguous 'int' elements.

That is, the name 'arr' refers to the runtime location (or "address") of
the set
of 5 contiguous 'int' elements.

Does that sound right so far?

- Dave Rivers -
 
I

Ian Collins

From the link you have posted you should refer to chapter 5.5 Pointer Data
types.
http://www.oopweb.com/Assembly/Documents/ArtOfAssembly/Volume/Chapter_5/CH05-1.html#HEADING1-197

"A pointer is simply a memory location whose value is the address (or index
if you prefer) of some other memory location. Pointers are very easy to
declare and use in an assembly language program. You don't even have to
worry about array indices or anything like that. In fact the only
complication you're going to run into is that the 80x86 supports two kinds
of pointers: near pointers and far pointers.

A near pointer is a 16 bit value that provides an offset into a segment. It
could be any segment but you will generally use the data segment (dseg in
SHELL.ASM). If you have a word variable p that contains 1000h then p
"points" at memory location 1000h in dseg. To access the word that p points
at you could use code like the following: "

The pointer _arr$ happens to be an offset into the text segment, but this
does not change the fact that it is a pointer.
It's value is -20 , that is a memory index or an offset.

Man you really don't have a clue, do you? I'll ask again, How much x86
assembly programming have you actually done?
 
P

Paul

Thomas David Rivers said:
Paul said:
So - do we agree that an array is a contigous set of like-typed
elements,
where the elements are accessed via the []-operator?
Yes I aggree with that.

So - next let's examine a rather simple declaration of an array in C/C++.

int arr[5];

No do a dynamic array like so:
int* arr = new int[5];

Then there is no confusion about array objects, an array is simply the
region of memory storing the integer objects and nothing more.

Having read ahead you seem to be slowly introducing this "arr" object into
the equation without first aggreeing on a definition of what exactly "arr"
is. And that is what was the original argument.

In the above example of a dynamic array there is no confusion that "arr" is
a pointer.
 
P

Paul

Ian Collins said:
Man you really don't have a clue, do you? I'll ask again, How much x86
assembly programming have you actually done?

--
It doesn't matter how much I claim to have done or how much you claim to
have done. The fact of the matter is, apparently I know what a pointer is
and you don't.

A variable whose value is an address(or an offset) to another memory
location is a pointer in assembly language.
 
P

Paul

A. Bolmarcich said:
A. Bolmarcich said:
[snip]
When you dereference a pointer to int you access the pointed to integer
object like so :
int x=5;
int* px = &x;
std::cout<< *px;
//this will output 5 because dereferencing px accesses the object it
points
to.


With an array the situation is not the same becasue an array cannot be
accessed, as a whole. The only way we can point to an array is to point
to
one of its elements.
int arr[3] = {1,2,3};
int* parr = arr;
int (*pparr)[3] = &arr;

std::cout<< *parr;
//outputs 1 because it points to the first element of the array.
std::cout<<*pparr;
//outputs a memory address because it points to an array-type object.

The situation with the unary * and unary & operators is the same for
an array and for a non-array. The C++ standard does not specify
different behaviors depending on whether the operand of the unary *
and unary & operators is an array or non-array.

Here is the paragraph from the C++ standard about the unary *
operator.

The unary * operator performs indirection: the expression to which
it is applied shall be a pointer to an object type, or a pointer to
a function type and the result is an lvalue referring to the object
or function to which the expression points. If the type of the
expression is "pointer to T", the type of the result is "T".
[Note: a pointer to an incomplete type (other than cv void ) can be
dereferenced. The lvalue thus obtained can be used in limited ways
(to initialize a reference, for example); this lvalue must not be
converted to an rvalue, see 4.1. ]

The C++ standard does not specify different behaviors for an array
and a non-array with the unary * operator.

Here is the paragraph from the C++ standard about the unary &
operator.

The result of the unary & operator is a pointer to its operand.
The operand shall be an lvalue or a qualified-id. In the first
case, if the type of the expression is "T", the type of the result
is "pointer to T". In particular, the address of an object of type
"cv T" is "pointer to cv T", with the same cv-qualifiers. For a
qualified-id, if the member is a static member of type "T", the
type of the result is plain "pointer to T". If the member is
a nonstatic member of class C of type T, the type of the result is
"pointer to member of class C of type T." [Example:

struct A { int i; };
struct B : A { };
... &B::i ... // has type int A::*

--end example] [Note: a pointer to member formed from a mutable
nonstatic data member (7.1.1) does not reflect the mutable
specifier associated with the nonstatic data member. ]

The C++ standard does not specify different behaviors for an array
and a non-array with the unary & operator.

A difference with array and non-array results is that
array-to-pointer conversion is applied to an array result.

In your example, the statement

int* parr = arr;

implicitly applies array-to-pointer conversion to the array result of
the expression arr. The result of that conversion is a pointer to
the first element of arr, not a pointer to arr. Because parr is a
pointer to int, the result of dereferencing it is an int.

In your example, the statement

int (*pparr)[3] = &arr;

initializes pparr with a pointer to arr, not a pointer to an element
of arr. Because pparr is a pointer to an array of int, the result of
dereferencing it is an array of int. Array-to-pointer conversion is
implicitly applied to that result and the result of the conversion
is a pointer to int that points to the first element of arr.

An array identifier such as 'arr' is an array-type object. A pointer to
this
object points to a single object, not to an array of thi sobject type.

The result of using the identifier 'arr' in an expression is an
array. An array is a single object that contains sub-objects. The
expression &arr points to the object that is the array named arr.

Given the declaration

int arr[4];

a C++ implementaion creates an array object to represent the array,
but it does not also create an object that stores a pointer to the
array object, unless one is explicitly present, say due to the
declaration

int (*pparr)[4] = &arr;

Due to that statement a C++ implementation creates a pointer to
array object that is initialized to point to the array. The
pointer points directly to the array object.

The pointer pparr above points to a single object not an array of
objects.
Consider this:

int (*p)[3]=0;
std::cout<<*p<<std::endl;
std::cout<< typeid(*p).name()<<std::endl;
std::cout<< sizeof(*p);

Does the above pointer point to a valid object?
Or is it completely UB because its dereferencing a null pointer?

Having the value of a pointer be the null pointer is valid. The
effect of dereferencing the null pointer is undefined.

A few followups ago I posted the code generated by a GNU C++ compiler
to show how an array object and a pointer to an array object were
implemented. I don't know of any compiler that adds an object that
stores a pointer to the array for each array. I don't know of
anything in the C++ standard that requires an object that stores
a pointer to an array for each array. If you do, please provide
details.
An array object must store a pointer otherwise how does it know, where
in
memory, the array is?
The post you have replied to up till here was not a post by me.
I believe the following is addressed toward sme.

The post that I replied to, and that is quoted above in the lines
starting with ">>>", was posted by you. If the newsreader you use
has a function to go back to the post that a reply is to, use that
function to go back 3 replys to get to the post in which the lines
above starting with ">>>" were originally written. Otherwise, open
http://groups.google.com/group/comp.lang.c++/msg/c53faaea6144e685?hl=en

Ok sorry I lost track of these threads a little bit there.
SO what exactly is your arguemnt about arrays again?
 
I

Ian Collins

It doesn't matter how much I claim to have done or how much you claim to
have done. The fact of the matter is, apparently I know what a pointer is
and you don't.

I'll take that as "none".
A variable whose value is an address(or an offset) to another memory
location is a pointer in assembly language.

The *number* -20 isn't a variable any more than arr in "#define arr 20"
is.

_arr$ = -20 ; size = 20

is the MASM equivalent of

#define arr = -20 // is arr a pointer?

It is declared in the text segment, it is not an offset into the text
segment.

Get a clue, please.
 
P

Paul

Ian Collins said:
I'll take that as "none".


The *number* -20 isn't a variable any more than arr in "#define arr 20"
is.
Correct -20 is not a variable , it is the value of the variable.
_arr$ = -20 ; size = 20

is the MASM equivalent of

#define arr = -20 // is arr a pointer?

It is declared in the text segment, it is not an offset into the text
segment.
_arr$ is a variable that stores the value -20.
-20 is a value that represents an offset memory address. This is pointer
variable that holds an offset which points to another memory location.
 
I

Ian Collins

Correct -20 is not a variable , it is the value of the variable.

It is the value of a constant. By your definition, if I write

#define arr -20

arr is a variable.
_arr$ is a variable that stores the value -20.

No, for the last time it is a constant. Please study a topic before
posting about it. From the link I posted earlier:

"A manifest constant is a symbol name that represents some fixed
quantity during the assembly process. That is it is a symbolic name that
represents some value. Equates are the mechanism MASM uses to declare
symbolic constants."

This is now way off topic. I suggest you find an assembly programming
group and see how far you get there.
 
P

Paul

Ian Collins said:
It is the value of a constant. By your definition, if I write

#define arr -20

arr is a variable.


No, for the last time it is a constant. Please study a topic before
posting about it. From the link I posted earlier:

"A manifest constant is a symbol name that represents some fixed quantity
during the assembly process. That is it is a symbolic name that represents
some value. Equates are the mechanism MASM uses to declare symbolic
constants."

This is now way off topic. I suggest you find an assembly programming
group and see how far you get there.
Its you that brought it up. And now you seem to be ruinning away from the
argument because you are maybe starting to realise that _arr$ is a pointer.


Look at the following code:

int main(){
int arr[3]={0};
int* px= arr;
px[1] = 7;
}

; Listing generated by Microsoft (R) Optimizing Compiler Version
14.00.50727.762

TITLE C:\cpp\public.cpp
.686P
.XMM
include listing.inc
.model flat

INCLUDELIB LIBCMT
INCLUDELIB OLDNAMES

PUBLIC _main
; Function compile flags: /Odtp
_TEXT SEGMENT
_px$ = -16 ; size = 4
_arr$ = -12 ; size = 12
_main PROC
; File c:\cpp\public.cpp
; Line 5
push ebp
mov ebp, esp
sub esp, 16 ; 00000010H
; Line 6
mov DWORD PTR _arr$[ebp], 0
xor eax, eax
mov DWORD PTR _arr$[ebp+4], eax
mov DWORD PTR _arr$[ebp+8], eax
; Line 7
lea ecx, DWORD PTR _arr$[ebp]
mov DWORD PTR _px$[ebp], ecx
; Line 8
mov edx, DWORD PTR _px$[ebp]
mov DWORD PTR [edx+4], 7
; Line 9
xor eax, eax
mov esp, ebp
pop ebp
ret 0
_main ENDP
_TEXT ENDS
END

Line 5-6 Creates a stack frame similar to below. It preserves ebp on the
stack, then assgins the esp value to ebp and then decrements esp by 16
bytes.
Line 6-7 Initialises the 3 integer objects , of the array, to 0.
Line 7-8 Stores the address of the first element at the location _px$ points
to.
Line 8-9 Moves the literal value of 7 into the 2nd element of the array.


00001C [-------------]
000018 [--orig ebp---]<- orig esp
000014 [------0------] <-ebp
000010 [------7------]
00000C [------0------]
000008 [---00000C---] <- esp
000004 [-------------]
000000 [-------------]

After that ebp is popped and esp is back to its original value.
Face the facts about what a pointer is in assembly programming.
If you still do not accept these facts then I urge you to refer to the link
I posted about pointer data types by Randy Hyde.
 
P

Paul

Paul said:
Thats should be:

00001C [-------------]<- original esp
000018 [--orig ebp---]<- ebp
000014 [------0------] 000010 [------7------]
00000C [------0------]
000008 [---00000C---] <- esp
000004 [-------------]
000000 [-------------]
I had ebp pointing to the wrong location.
 
I

Ian Collins

Its you that brought it up.

Did I? It was you who claimed a constant was a pointer.
And now you seem to be ruinning away from the
argument because you are maybe starting to realise that _arr$ is a pointer.

No I'm not because it isn't.
Look at the following code:

int main(){
int arr[3]={0};
int* px= arr;
px[1] = 7;
}

Let's see the output from a less verbose compiler:

.file "x.cc"
.text
..globl main
.type main, @function
main:
..LFB0:
pushl %ebp
..LCFI0:
movl %esp, %ebp
..LCFI1:
subl $16, %esp
..LCFI2:
movl $0, -16(%ebp)
movl $0, -12(%ebp)
movl $0, -8(%ebp)
leal -16(%ebp), %eax
movl %eax, -4(%ebp)
movl -4(%ebp), %eax
addl $4, %eax
movl $7, (%eax)
movl $0, %eax
leave
..LCFI3:
ret
..LFE0:
.size main, .-main

Much more concise, don't you agree? I guess by your reasoning, -16,
-12, -8 and -4 are pointers? The compiler could have used symbolic
constants like VCC, but is chooses not to.

How about another that uses symbolic constants for the array initialiser?

/ FILE x.cc

/ 1 !int main(){

push %rbp
..CG4:
movq %rsp,%rbp
..CG5:
subq $16,%rsp

/ 2 ! int arr[3]={0};

movq .LI1(%rip),%rcx
movl .LI1+8(%rip),%eax
movq %rcx,-16(%rbp) / sym=__1fEmain1ADarr_
movl %eax,-8(%rbp) / sym=__1fEmain1ADarr_

/ 3 ! int* px= arr;
/ 4 ! px[1] = 7;

movl $7,-12(%rbp) / sym=__1fEmain1ADarr_

/ 5 !}

xorl %eax,%eax
leave
ret

..CG6:
.size main, . - main
..CG7:

..CG8:
.section .data,"aw"
Ddata.data: / Offset 0

.align 8
..LI1: / Offset 0
.type .LI1, @object
.size .LI1, 12

.zero 12
.section .bss,"aw"

Just because one implementation uses symbolic constants for offsets,
they don't morph into pointers.
 
P

Paul

Ian Collins said:
Did I? It was you who claimed a constant was a pointer.
No I claimed that _arr$ was a pointer, you are arguing that is it s not a
poiter and it is just a constant.
So what do you think a pointer is in assembly?
No I'm not because it isn't.
_arr$ IS a pointer, its value is an offset to anothe rmemory location.
Look at the following code:

int main(){
int arr[3]={0};
int* px= arr;
px[1] = 7;
}

Let's see the output from a less verbose compiler:
There is nothing wrong with the code I posted, it was very simple. The code
you have posted below does away with the varaible altogether so how can you
argue about whether or not its a pointer if it doesn't even exist?
.file "x.cc"
.text
.globl main
.type main, @function
main:
.LFB0:
pushl %ebp
.LCFI0:
movl %esp, %ebp
.LCFI1:
subl $16, %esp
.LCFI2:
movl $0, -16(%ebp)
movl $0, -12(%ebp)
movl $0, -8(%ebp)
leal -16(%ebp), %eax
movl %eax, -4(%ebp)
movl -4(%ebp), %eax
addl $4, %eax
movl $7, (%eax)
movl $0, %eax
leave
.LCFI3:
ret
.LFE0:
.size main, .-main

Much more concise, don't you agree? I guess by your
reasoning, -16, -12, -8 and -4 are pointers? The compiler could have used
symbolic constants like VCC, but is chooses not to.

No its not concise, my listing was well commented and initially started by
telling you the source of the code. Where does your code come from?
So it does away with all variables and replaces them with literals, does
this mean that _arr$ in my code is not a pointer, NO.


How about another that uses symbolic constants for the array initialiser?

Now you are just spamming shite.
/ FILE x.cc

/ 1 !int main(){

push %rbp
.CG4: movq %rsp,%rbp
.CG5: subq $16,%rsp
/ 2 ! int arr[3]={0};

movq .LI1(%rip),%rcx movl .LI1+8(%rip),%eax movq
%rcx,-16(%rbp) / sym=__1fEmain1ADarr_
movl %eax,-8(%rbp) / sym=__1fEmain1ADarr_

/ 3 ! int* px= arr;
/ 4 ! px[1] = 7;

movl $7,-12(%rbp) / sym=__1fEmain1ADarr_

/ 5 !}

xorl %eax,%eax leave ret
.CG6:
.size main, . - main
.CG7:

.CG8:
.section .data,"aw"
Ddata.data: / Offset 0

.align 8
.LI1: / Offset 0
.type .LI1, @object
.size .LI1, 12

.zero 12
.section .bss,"aw"

Just because one implementation uses symbolic constants for offsets, they
don't morph into pointers.
You don't know what a pointer is.
 
I

Ian Collins

Ian Collins said:
Look at the following code:

int main(){
int arr[3]={0};
int* px= arr;
px[1] = 7;
}

Let's see the output from a less verbose compiler:
There is nothing wrong with the code I posted, it was very simple. The code
you have posted below does away with the varaible altogether so how can you
argue about whether or not its a pointer if it doesn't even exist?

It's you code compiled with gcc.
No its not concise, my listing was well commented and initially started by
telling you the source of the code. Where does your code come from?

It's you code compiled with gcc.
So it does away with all variables and replaces them with literals, does
this mean that _arr$ in my code is not a pointer, NO.

Well yes and no, because it never was. As everyone one who has ever
worked with this assembler (no you, obviously) knows, it is a symbolic
constant.
Now you are just spamming shite.

Well maybe, it is your code after all!

Your code, compiled with Sun CC:
/ FILE x.cc

/ 1 !int main(){

push %rbp
.CG4: movq %rsp,%rbp
.CG5: subq $16,%rsp
/ 2 ! int arr[3]={0};

movq .LI1(%rip),%rcx movl .LI1+8(%rip),%eax movq
%rcx,-16(%rbp) / sym=__1fEmain1ADarr_
movl %eax,-8(%rbp) / sym=__1fEmain1ADarr_

/ 3 ! int* px= arr;
/ 4 ! px[1] = 7;

movl $7,-12(%rbp) / sym=__1fEmain1ADarr_

/ 5 !}

xorl %eax,%eax leave ret
.CG6:
.size main, . - main
.CG7:

.CG8:
.section .data,"aw"
Ddata.data: / Offset 0

.align 8
.LI1: / Offset 0
.type .LI1, @object
.size .LI1, 12

.zero 12
.section .bss,"aw"

Just because one implementation uses symbolic constants for offsets, they
don't morph into pointers.
You don't know what a pointer is.

Oh no! The past 30 years have been a delusion!

But I know a fool when I see one.
 
P

Paul

Leigh Johnston said:
Ian Collins said:
On 05/27/11 11:15 AM, Paul wrote:
On 05/27/11 08:10 AM, Paul wrote:

Man you really don't have a clue, do you? I'll ask again, How much
x86
assembly programming have you actually done?

It doesn't matter how much I claim to have done or how much you
claim to
have done. The fact of the matter is, apparently I know what a
pointer
is
and you don't.

I'll take that as "none".

A variable whose value is an address(or an offset) to another memory
location is a pointer in assembly language.

The *number* -20 isn't a variable any more than arr in "#define arr
20"
is.
Correct -20 is not a variable , it is the value of the variable.

It is the value of a constant. By your definition, if I write

#define arr -20

arr is a variable.

_arr$ = -20 ; size = 20

is the MASM equivalent of

#define arr = -20 // is arr a pointer?

It is declared in the text segment, it is not an offset into the text
segment.

_arr$ is a variable that stores the value -20.

No, for the last time it is a constant. Please study a topic before
posting about it. From the link I posted earlier:

"A manifest constant is a symbol name that represents some fixed
quantity during the assembly process. That is it is a symbolic name
that represents some value. Equates are the mechanism MASM uses to
declare symbolic constants."

This is now way off topic. I suggest you find an assembly programming
group and see how far you get there.
Its you that brought it up. And now you seem to be ruinning away from
the argument because you are maybe starting to realise that _arr$ is a
pointer.


Look at the following code:

int main(){
int arr[3]={0};
int* px= arr;
px[1] = 7;
}

; Listing generated by Microsoft (R) Optimizing Compiler Version
14.00.50727.762

TITLE C:\cpp\public.cpp
.686P
.XMM
include listing.inc
.model flat

INCLUDELIB LIBCMT
INCLUDELIB OLDNAMES

PUBLIC _main
; Function compile flags: /Odtp
_TEXT SEGMENT
_px$ = -16 ; size = 4
_arr$ = -12 ; size = 12
_main PROC
; File c:\cpp\public.cpp
; Line 5
push ebp
mov ebp, esp
sub esp, 16 ; 00000010H
; Line 6
mov DWORD PTR _arr$[ebp], 0
xor eax, eax
mov DWORD PTR _arr$[ebp+4], eax
mov DWORD PTR _arr$[ebp+8], eax
; Line 7
lea ecx, DWORD PTR _arr$[ebp]
mov DWORD PTR _px$[ebp], ecx
; Line 8
mov edx, DWORD PTR _px$[ebp]
mov DWORD PTR [edx+4], 7
; Line 9
xor eax, eax
mov esp, ebp
pop ebp
ret 0
_main ENDP
_TEXT ENDS
END

Line 5-6 Creates a stack frame similar to below. It preserves ebp on the
stack, then assgins the esp value to ebp and then decrements esp by 16
bytes.
Line 6-7 Initialises the 3 integer objects , of the array, to 0.
Line 7-8 Stores the address of the first element at the location _px$
points to.
Line 8-9 Moves the literal value of 7 into the 2nd element of the array.


00001C [-------------]
000018 [--orig ebp---]<- orig esp
000014 [------0------] <-ebp
000010 [------7------]
00000C [------0------]
000008 [---00000C---] <- esp
000004 [-------------]
000000 [-------------]

After that ebp is popped and esp is back to its original value.
Face the facts about what a pointer is in assembly programming.
If you still do not accept these facts then I urge you to refer to the
link I posted about pointer data types by Randy Hyde.

Now you are arguing with yourself: you have just shown that there is no
special hidden object which containing the address of the array object;
the only thing that contains the address of the array object above is the
pointer 'px'.
No there is a pointer named _arr$, which happens to be in the text segment,
it is not on the stack.
Just the same as the pointer _px$ is not on the stack.
Look at the value of _px$, it is -16, this doesn't mean it's not a pointer.
Its just a pointer that stores an offset, or an index into the stack.
For:

lea ecx, DWORD PTR _arr$[ebp]

what will actually be emitted is:

lea ecx, DWORD PTR [ebp-12]

as '_arr$' is a constant; not a variable or a "pointer".

_arr$ holds an offset which is added to ebp to create the real address.
_arr$ is a constant only because it is stored in the read only text segment.
This does not mean it is not a pointer , it stores an offset that points to
the begining of the array.
A pointer does not need to store a real address a pointer can also store an
offset, as in this case.


Given my stack frame illustration _arr$ points to here:

00001C [-------------]
000018 [--orig ebp---] <- ebp
000014 [------0------]
000010 [------7------]
00000C [------0------] <- _arr$
000008 [---00000C---] <- esp
000004 [-------------]
000000 [-------------]

-12 is an offset into the stack frame, which is the location where the array
begins.
 
T

Thomas David Rivers

Paul said:
Paul said:
So - do we agree that an array is a contigous set of like-typed
elements,
where the elements are accessed via the []-operator?

Yes I aggree with that.

So - next let's examine a rather simple declaration of an array in
C/C++.

int arr[5];


No do a dynamic array like so:
int* arr = new int[5];

Then there is no confusion about array objects, an array is simply the
region of memory storing the integer objects and nothing more.

Having read ahead you seem to be slowly introducing this "arr" object
into the equation without first aggreeing on a definition of what
exactly "arr" is. And that is what was the original argument.

In the above example of a dynamic array there is no confusion that
"arr" is a pointer.

You are correct - what you have declared there is a pointer to an integer,
(the `int *arr' portion), and that pointer is initialized with some
dynamically
allocated space (the `new' portion.) The dynamically allocated space is a
contiguous set of 5 'int' elements (the `int[5]' portion.) The pointer's
name is 'arr'.

That's all well and good, but it is very different from what I was
talking about.

What I'd like to focus on is this simple declaration:

int arr[5];

Can we agree that the declaration of

int arr[5];

represents, at runtime, a set of 5 contiguous 'int' elements. The
name of the set of 5 contiguous elements it 'arr'. The name 'arr'
refers to the runtime location of the set of 5 contiguous elements.

If we can, I'd like to restrict the conversation to just that for the
moment... we can get to the other stuff soon enough... but, one
thing at a time.

Does that sound like a good starting place?

- Dave Rivers -
 
P

Paul

Thomas David Rivers said:
Paul said:
Paul wrote:



So - do we agree that an array is a contigous set of like-typed
elements,
where the elements are accessed via the []-operator?

Yes I aggree with that.


So - next let's examine a rather simple declaration of an array in
C/C++.

int arr[5];


No do a dynamic array like so:
int* arr = new int[5];

Then there is no confusion about array objects, an array is simply the
region of memory storing the integer objects and nothing more.

Having read ahead you seem to be slowly introducing this "arr" object
into the equation without first aggreeing on a definition of what exactly
"arr" is. And that is what was the original argument.

In the above example of a dynamic array there is no confusion that "arr"
is a pointer.

You are correct - what you have declared there is a pointer to an integer,
(the `int *arr' portion), and that pointer is initialized with some
dynamically
allocated space (the `new' portion.) The dynamically allocated space is
a
contiguous set of 5 'int' elements (the `int[5]' portion.) The pointer's
name is 'arr'.

That's all well and good, but it is very different from what I was talking
about.

What I'd like to focus on is this simple declaration:

int arr[5];

Can we agree that the declaration of

int arr[5];

represents, at runtime, a set of 5 contiguous 'int' elements. The
name of the set of 5 contiguous elements it 'arr'. The name 'arr'
refers to the runtime location of the set of 5 contiguous elements.

If we can, I'd like to restrict the conversation to just that for the
moment... we can get to the other stuff soon enough... but, one
thing at a time.
Yes I agree with this, but before we can proceed any further we need to
agree on what exactly "arr" is.
You are calling it a name that refers to the contiguous sequence of elements
here.
I would like to establish just what exactly it is because it seems to store
a memory address as can be show with:
int arr[5];
int* p = arr;

So lets try to agree about what exactly arr is.
As you know I have been calling it an array type object.
 
P

Paul

Leigh Johnston said:
Man you really don't have a clue, do you? I'll ask again, How much
x86
assembly programming have you actually done?

It doesn't matter how much I claim to have done or how much you
claim to
have done. The fact of the matter is, apparently I know what a
pointer
is
and you don't.

I'll take that as "none".

A variable whose value is an address(or an offset) to another
memory
location is a pointer in assembly language.

The *number* -20 isn't a variable any more than arr in "#define
arr 20"
is.
Correct -20 is not a variable , it is the value of the variable.

It is the value of a constant. By your definition, if I write

#define arr -20

arr is a variable.

_arr$ = -20 ; size = 20

is the MASM equivalent of

#define arr = -20 // is arr a pointer?

It is declared in the text segment, it is not an offset into the
text
segment.

_arr$ is a variable that stores the value -20.

No, for the last time it is a constant. Please study a topic before
posting about it. From the link I posted earlier:

"A manifest constant is a symbol name that represents some fixed
quantity during the assembly process. That is it is a symbolic name
that represents some value. Equates are the mechanism MASM uses to
declare symbolic constants."

This is now way off topic. I suggest you find an assembly programming
group and see how far you get there.

Its you that brought it up. And now you seem to be ruinning away from
the argument because you are maybe starting to realise that _arr$ is a
pointer.


Look at the following code:

int main(){
int arr[3]={0};
int* px= arr;
px[1] = 7;
}

; Listing generated by Microsoft (R) Optimizing Compiler Version
14.00.50727.762

TITLE C:\cpp\public.cpp
.686P
.XMM
include listing.inc
.model flat

INCLUDELIB LIBCMT
INCLUDELIB OLDNAMES

PUBLIC _main
; Function compile flags: /Odtp
_TEXT SEGMENT
_px$ = -16 ; size = 4
_arr$ = -12 ; size = 12
_main PROC
; File c:\cpp\public.cpp
; Line 5
push ebp
mov ebp, esp
sub esp, 16 ; 00000010H
; Line 6
mov DWORD PTR _arr$[ebp], 0
xor eax, eax
mov DWORD PTR _arr$[ebp+4], eax
mov DWORD PTR _arr$[ebp+8], eax
; Line 7
lea ecx, DWORD PTR _arr$[ebp]
mov DWORD PTR _px$[ebp], ecx
; Line 8
mov edx, DWORD PTR _px$[ebp]
mov DWORD PTR [edx+4], 7
; Line 9
xor eax, eax
mov esp, ebp
pop ebp
ret 0
_main ENDP
_TEXT ENDS
END

Line 5-6 Creates a stack frame similar to below. It preserves ebp on
the
stack, then assgins the esp value to ebp and then decrements esp by 16
bytes.
Line 6-7 Initialises the 3 integer objects , of the array, to 0.
Line 7-8 Stores the address of the first element at the location _px$
points to.
Line 8-9 Moves the literal value of 7 into the 2nd element of the
array.


00001C [-------------]
000018 [--orig ebp---]<- orig esp
000014 [------0------] <-ebp
000010 [------7------]
00000C [------0------]
000008 [---00000C---] <- esp
000004 [-------------]
000000 [-------------]

After that ebp is popped and esp is back to its original value.
Face the facts about what a pointer is in assembly programming.
If you still do not accept these facts then I urge you to refer to the
link I posted about pointer data types by Randy Hyde.

Now you are arguing with yourself: you have just shown that there is
no special hidden object which containing the address of the array
object; the only thing that contains the address of the array object
above is the pointer 'px'.
No there is a pointer named _arr$, which happens to be in the text
segment, it is not on the stack.

No, '_arr$' is not a pointer; '_arr$' is a constant used when emitting
machine code in the text segment. If does not exist as a separate entity
in the text segment. lrn2asm.
Just the same as the pointer _px$ is not on the stack.
Look at the value of _px$, it is -16, this doesn't mean it's not a
pointer. Its just a pointer that stores an offset, or an index into the
stack.

The value of the pointer 'px' is stored on the stack at a location stack
frame pointer + '_px$' (a constant whose value is -16); we have already
told you this.
For:

lea ecx, DWORD PTR _arr$[ebp]

what will actually be emitted is:

lea ecx, DWORD PTR [ebp-12]

as '_arr$' is a constant; not a variable or a "pointer".

_arr$ holds an offset which is added to ebp to create the real address.

Correct we have already told you this.
_arr$ is a constant only because it is stored in the read only text
segment. This does not mean it is not a pointer , it stores an offset
that points to the begining of the array.

As I have already said '_arr$' does not exist as a distinct separate
entity in the text segment; it used when emitting machine code in the text
segment.
A pointer does not need to store a real address a pointer can also store
an offset, as in this case.

It is not a pointer; it is a constant used when emitting machine code.

Oh you want to go to machine code level now?
There is no pointers in machine code at all, your argument is nonsense.
Given my stack frame illustration _arr$ points to here:

00001C [-------------]
000018 [--orig ebp---] <- ebp
000014 [------0------]
000010 [------7------]
00000C [------0------] <- _arr$
000008 [---00000C---] <- esp
000004 [-------------]
000000 [-------------]

-12 is an offset into the stack frame, which is the location where the
array begins.

Finally. Yes -12 is an offset into the stack frame; we have been trying
to tell you this for the past couple of days; -12 is not a pointer or a
variable it is a constant offset. A realistic and correct stack frame
illustration is:

123000 [-------------]
122FFC [--orig ebp---] <- ebp
123FF8 [------0------]
123FF4 [------7------]
123FF0 [------0------] <- ebp + _arr$
123FEC [---123FEC---] <- esp
123FE8 [-------------]
123FE4 [-------------]

Notice how I have replaced your deliberately misleading value of 12
(00000C) with a more realistic value that shows that the contents of the
pointer 'px' is unrelated to the number 12; its value is ebp + _arr$ as
encoded into the emitted machine code in the text segment.
There was no deliberate attempt to mislead, It was pure coincidence that the
address turned out to be 12. You interpretation is wrong , the value of
memory location 123FEC should be 123FF0.
 
P

Paul

Leigh Johnston said:
Leigh Johnston said:
On 27/05/2011 14:34, Paul wrote:


Man you really don't have a clue, do you? I'll ask again, How
much
x86
assembly programming have you actually done?

It doesn't matter how much I claim to have done or how much you
claim to
have done. The fact of the matter is, apparently I know what a
pointer
is
and you don't.

I'll take that as "none".

A variable whose value is an address(or an offset) to another
memory
location is a pointer in assembly language.

The *number* -20 isn't a variable any more than arr in "#define
arr 20"
is.
Correct -20 is not a variable , it is the value of the variable.

It is the value of a constant. By your definition, if I write

#define arr -20

arr is a variable.

_arr$ = -20 ; size = 20

is the MASM equivalent of

#define arr = -20 // is arr a pointer?

It is declared in the text segment, it is not an offset into the
text
segment.

_arr$ is a variable that stores the value -20.

No, for the last time it is a constant. Please study a topic before
posting about it. From the link I posted earlier:

"A manifest constant is a symbol name that represents some fixed
quantity during the assembly process. That is it is a symbolic name
that represents some value. Equates are the mechanism MASM uses to
declare symbolic constants."

This is now way off topic. I suggest you find an assembly
programming
group and see how far you get there.

Its you that brought it up. And now you seem to be ruinning away from
the argument because you are maybe starting to realise that _arr$ is
a
pointer.


Look at the following code:

int main(){
int arr[3]={0};
int* px= arr;
px[1] = 7;
}

; Listing generated by Microsoft (R) Optimizing Compiler Version
14.00.50727.762

TITLE C:\cpp\public.cpp
.686P
.XMM
include listing.inc
.model flat

INCLUDELIB LIBCMT
INCLUDELIB OLDNAMES

PUBLIC _main
; Function compile flags: /Odtp
_TEXT SEGMENT
_px$ = -16 ; size = 4
_arr$ = -12 ; size = 12
_main PROC
; File c:\cpp\public.cpp
; Line 5
push ebp
mov ebp, esp
sub esp, 16 ; 00000010H
; Line 6
mov DWORD PTR _arr$[ebp], 0
xor eax, eax
mov DWORD PTR _arr$[ebp+4], eax
mov DWORD PTR _arr$[ebp+8], eax
; Line 7
lea ecx, DWORD PTR _arr$[ebp]
mov DWORD PTR _px$[ebp], ecx
; Line 8
mov edx, DWORD PTR _px$[ebp]
mov DWORD PTR [edx+4], 7
; Line 9
xor eax, eax
mov esp, ebp
pop ebp
ret 0
_main ENDP
_TEXT ENDS
END

Line 5-6 Creates a stack frame similar to below. It preserves ebp
on the
stack, then assgins the esp value to ebp and then decrements esp by
16
bytes.
Line 6-7 Initialises the 3 integer objects , of the array, to 0.
Line 7-8 Stores the address of the first element at the location _px$
points to.
Line 8-9 Moves the literal value of 7 into the 2nd element of the
array.


00001C [-------------]
000018 [--orig ebp---]<- orig esp
000014 [------0------] <-ebp
000010 [------7------]
00000C [------0------]
000008 [---00000C---] <- esp
000004 [-------------]
000000 [-------------]

After that ebp is popped and esp is back to its original value.
Face the facts about what a pointer is in assembly programming.
If you still do not accept these facts then I urge you to refer to
the
link I posted about pointer data types by Randy Hyde.

Now you are arguing with yourself: you have just shown that there is
no special hidden object which containing the address of the array
object; the only thing that contains the address of the array object
above is the pointer 'px'.

No there is a pointer named _arr$, which happens to be in the text
segment, it is not on the stack.

No, '_arr$' is not a pointer; '_arr$' is a constant used when emitting
machine code in the text segment. If does not exist as a separate
entity in the text segment. lrn2asm.

Just the same as the pointer _px$ is not on the stack.
Look at the value of _px$, it is -16, this doesn't mean it's not a
pointer. Its just a pointer that stores an offset, or an index into the
stack.

The value of the pointer 'px' is stored on the stack at a location
stack frame pointer + '_px$' (a constant whose value is -16); we have
already told you this.


For:

lea ecx, DWORD PTR _arr$[ebp]

what will actually be emitted is:

lea ecx, DWORD PTR [ebp-12]

as '_arr$' is a constant; not a variable or a "pointer".

_arr$ holds an offset which is added to ebp to create the real address.

Correct we have already told you this.

_arr$ is a constant only because it is stored in the read only text
segment. This does not mean it is not a pointer , it stores an offset
that points to the begining of the array.

As I have already said '_arr$' does not exist as a distinct separate
entity in the text segment; it used when emitting machine code in the
text segment.

A pointer does not need to store a real address a pointer can also
store
an offset, as in this case.

It is not a pointer; it is a constant used when emitting machine code.

Oh you want to go to machine code level now?
There is no pointers in machine code at all, your argument is nonsense.
Given my stack frame illustration _arr$ points to here:

00001C [-------------]
000018 [--orig ebp---] <- ebp
000014 [------0------]
000010 [------7------]
00000C [------0------] <- _arr$
000008 [---00000C---] <- esp
000004 [-------------]
000000 [-------------]

-12 is an offset into the stack frame, which is the location where the
array begins.

Finally. Yes -12 is an offset into the stack frame; we have been
trying to tell you this for the past couple of days; -12 is not a
pointer or a variable it is a constant offset. A realistic and correct
stack frame illustration is:

123000 [-------------]
122FFC [--orig ebp---] <- ebp
123FF8 [------0------]
123FF4 [------7------]
123FF0 [------0------] <- ebp + _arr$
123FEC [---123FEC---] <- esp
123FE8 [-------------]
123FE4 [-------------]

Notice how I have replaced your deliberately misleading value of 12
(00000C) with a more realistic value that shows that the contents of
the pointer 'px' is unrelated to the number 12; its value is ebp +
_arr$ as encoded into the emitted machine code in the text segment.
There was no deliberate attempt to mislead, It was pure coincidence that
the address turned out to be 12. You interpretation is wrong , the value
of memory location 123FEC should be 123FF0.

Typical troll: deliberately ignoring my correction. On the small chance
that you didn't use your newsreader properly yes I did put the wrong value
in the illustration but that doesn't change the fact that what I said (and
my "interpretation") is correct: '_arr$' is not a pointer it is a constant
used when emitting machine code in the text segment.
So a simple task like changing the ficticional addresses is obviously too
complicated for you.

You don't even have a clue about machine code, this code is translated into
object code.
Machine code is post linking where all addresses and instructions are
reduced to binary.
 

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

Forum statistics

Threads
474,142
Messages
2,570,820
Members
47,367
Latest member
mahdiharooniir

Latest Threads

Top