Environment: linux, gcc + nasm.
I have an asm file containing a global data label, eg (NASM syntax):
section .data
global my_data
.....
my_data: times 8 dd 0
So, the label "my_data" identifies a 32 byte (8 * 4) memory area.
I have a C file where I want to use this data, so I did:
.....
extern unsigned int *my_data;
.....
and thought I could legally do (in C)
my_data[0] = 33;
my_data[5] = 44;
etc.
But this results in a segfault.
Instead, if I put this in the C file:
extern unsigned int my_data[8];
everything works fine.
After a few tests, it turns out that, if my_data is declared as a
pointer, it is actually a nil pointer, so --> segfault.
But, shouldn't it point to the actual 32-byte memory area of the asm
file?
Another question that seems to be related: if I have in the asm file
global int_var
int_var: dd 5
in the C file I have to declare it as
extern int int_var;
and not as
extern int *int_var; /* segfaults when used */
In both cases (and in the previous one also), the compiler never
complains.
So, do I have to deduce that an external data label (that, after all,
_is_ a pointer, since it represents a memory address) can never be
treated like a pointer?
Maybe this is a newbie question, but, since this is the first time I
try to link together asm and C files, I never had this issue before.
Thanks
|
|
0
|
|
|
|
Reply
|
sunglo
|
2/17/2004 10:49:38 PM |
|
On Tue, 17 Feb 2004 22:49:38 +0000 (UTC), sunglo@katamail.com (subnet)
wrote in comp.lang.asm.x86:
> Environment: linux, gcc + nasm.
>
> I have an asm file containing a global data label, eg (NASM syntax):
>
> section .data
> global my_data
> ....
> my_data: times 8 dd 0
>
>
> So, the label "my_data" identifies a 32 byte (8 * 4) memory area.
Yes, my_data is an ARRAY of 32 8-bit character types, or 16 16-bit
short int types, or 8 32-bit int or long int types. It is an ARRAY.
> I have a C file where I want to use this data, so I did:
>
> ....
> extern unsigned int *my_data;
But my_data is not a pointer to int. It is an ARRAY. An array is not
a pointer, a pointer is not an array. In many circumstances in C,
when you use the name of an array in an expression it gets converted
to a pointer, but an ARRAY IS NOT A POINTER.
> ....
>
> and thought I could legally do (in C)
>
> my_data[0] = 33;
> my_data[5] = 44;
> etc.
>
> But this results in a segfault.
> Instead, if I put this in the C file:
>
> extern unsigned int my_data[8];
>
> everything works fine.
> After a few tests, it turns out that, if my_data is declared as a
> pointer, it is actually a nil pointer, so --> segfault.
> But, shouldn't it point to the actual 32-byte memory area of the asm
> file?
No, because an array is not a pointer, it does not point to anything.
> Another question that seems to be related: if I have in the asm file
>
> global int_var
> int_var: dd 5
>
> in the C file I have to declare it as
>
> extern int int_var;
>
> and not as
>
> extern int *int_var; /* segfaults when used */
>
> In both cases (and in the previous one also), the compiler never
> complains.
>
> So, do I have to deduce that an external data label (that, after all,
> _is_ a pointer, since it represents a memory address) can never be
> treated like a pointer?
An external data label is NOT a pointer, it is an address. If you put
the address of something in a variable type designed to store
addresses, it becomes a pointer.
> Maybe this is a newbie question, but, since this is the first time I
> try to link together asm and C files, I never had this issue before.
>
> Thanks
Your problem is not about linking assembly language with C, it is a
misunderstanding of C pointers and arrays. See the FAQ for
comp.lang.c, especially section 6, which is all about pointers and
arrays.
http://www.eskimo.com/~scs/C-faq/s6.html
The very first question will show you that you can have the same
misunderstanding, and write the same incorrect code, entirely in C
without needing assembly language at all.
--
Jack Klein
Home: http://JK-Technology.Com
FAQs for
comp.lang.c http://www.eskimo.com/~scs/C-faq/top.html
comp.lang.c++ http://www.parashift.com/c++-faq-lite/
alt.comp.lang.learn.c-c++
http://www.contrib.andrew.cmu.edu/~ajo/docs/FAQ-acllc.html
|
|
0
|
|
|
|
Reply
|
Jack
|
2/18/2004 2:09:10 AM
|
|
> Environment: linux, gcc + nasm.
>
> I have an asm file containing a global data label, eg (NASM syntax):
>
> section .data
> global my_data
> ....
> my_data: times 8 dd 0
>
> I have a C file where I want to use this data, so I did:
>
> extern unsigned int *my_data;
This is indeed wrong.
> and thought I could legally do (in C)
>
> my_data[0] = 33;
> my_data[5] = 44;
> etc.
>
> But this results in a segfault.
Lots of things are legal in C :-)
> Instead, if I put this in the C file:
>
> extern unsigned int my_data[8];
>
> everything works fine.
> After a few tests, it turns out that, if my_data is declared as a
> pointer, it is actually a nil pointer, so --> segfault.
> But, shouldn't it point to the actual 32-byte memory area of the asm
> file?
my_data is a symbol, which has an associated address in the data
section. At that address, you will find the 8 zeros. When you write
extern unsigned int my_data[8], you tell the compiler that there is
already a symbol my_data addressing 8 ints defined elsewhere, and you
are going to use that symbol. This means the C compiler will not
generate a new symbol, and reserve no space. If you write extern
unsigned int *my_data, you tell the compiler that there is a symbol
my_data elsewhere, which addresses an int * that has been defined. The
names of variables in C are themselves pointers, and the values of those
pointers are what you get with the & operator.
> Another question that seems to be related: if I have in the asm file
>
> global int_var
> int_var: dd 5
>
> in the C file I have to declare it as
>
> extern int int_var;
>
> and not as
>
> extern int *int_var; /* segfaults when used */
You have to declare it as extern int, because it is an external integer.
You have, in your assembly file, created an integer and called it
int_var. extern int int_var tells the compiler that you want to use an
int int_var, but it has been created somewhere else, so the compiler
need not bother to create it again. If you put extern int *int_var
instead, the int *int_var will contain 5 as specified in your assembly,
and if you dereference 5 you are likely to segfault. This is equivalent
to doing *(int *)5.
> In both cases (and in the previous one also), the compiler never
> complains.
The compiler has nothing to complain about. You have just told it that
there is no need to generate space and a symbol for int_var, so it
doesn't, and it's perfectly happy with that.
> So, do I have to deduce that an external data label (that, after all,
> _is_ a pointer, since it represents a memory address) can never be
> treated like a pointer?
If you like to call a variable in an external assembly file a pointer,
you should also call the variables in your C file pointers. The names
all have associated addresses, but in assembly the address is more
clearly used as a value than in C, where you must use the & operator to
get it. The value of the int int_var in C is the value of [int_var] in
assembly. That this is an int is something you have to make sure of
yourself in assembly though.
> Maybe this is a newbie question, but, since this is the first time I
> try to link together asm and C files, I never had this issue before.
This is a newbie question, but one that is quite understandable. It is
just a matter of seeing how the pieces come together and what a C
program actually represents, and this can be hard even for a good
programmer. Remember that it is by asking questions that you get answers.
--
Remove the furry animal from my address to send email:
bjarni.ferret@update.ferret.uu.se
|
|
0
|
|
|
|
Reply
|
Bjarni
|
2/18/2004 3:31:49 AM
|
|
Ok, thanks Jack and Bjarni, very clear now.
The FAQ are very good and comprehensive, I read them all.
But, while the case in section 6.1 of the FAQ is very obvious and
easily understood, since arrays are not pointers (yes I know that),
and I could never did that mistake in straight C, I never used them in
asm, so I didn't notice the difference.
What got me wrong is maybe code like the following
in C
----------------------------
void my_function(char *str)
{ .. do something with str .. }
----------------------------
and in asm
----------------------------
msg: db "Hello", 0
......
extern my_function
....
push msg
call my_function
-----------------------------
This code actually works, but not because "msg" is a pointer to char
(as I erroneously thought), but (if I understood correctly) because
it's an array of chars and, in function formal arguments, arrays can
be substituted by pointers.
To summarize (assuming that both ints and pointers are 4 bytes wide):
if I do (in asm)
-----------------------
global var
var: dd 0
-----------------------
in C I can do:
extern int var
and treat var like an int,
or
extern int *var
and treat var like a pointer (and it will be an invalid nil pointer at
the beginning, since it contains 0).
Similarly, if the label identifies some larger area (say, 32 bytes):
var: times 8 dd 0
I can say
extern int var[8];
extern short int var[16];
extern char var[32];
and go as usual with arrays, or
extern <some data type> *var;
But in the latter case I'm really working only with the first 4 bytes
of the area identified by var, and, for the same reason as before,
this will be a nil pointer, and chances are this is probably not what
I intended anyway, or, even worse, I can do
extern <some data type> *var[8];
and I'll end up with an array of 8 nil pointers (like before, probably
wrong).
I think this is correct now, because it makes sense.
Thanks again.
|
|
0
|
|
|
|
Reply
|
sunglo
|
2/19/2004 9:26:24 AM
|
|
> Ok, thanks Jack and Bjarni, very clear now.
Ah! A job well done. Time to sleep now.
[...]
> var: times 8 dd 0
>
> I can say
>
> extern int var[8];
> extern short int var[16];
> extern char var[32];
>
> and go as usual with arrays, or
>
> extern <some data type> *var;
[...]
> I think this is correct now, because it makes sense.
It does seem to make a whole lot of sense.
--
Remove the furry animal from my address to send email:
bjarni.ferret@update.ferret.uu.se
|
|
0
|
|
|
|
Reply
|
Bjarni
|
2/21/2004 7:12:03 PM
|
|
Bjarni Juliusson <bjarni.ferret@update.ferret.uu.se> writes:
> > Ok, thanks Jack and Bjarni, very clear now.
>
> Ah! A job well done. Time to sleep now.
>
> [...]
> > var: times 8 dd 0
> > I can say
> > extern int var[8];
> > extern short int var[16];
> > extern char var[32];
> > and go as usual with arrays, or
Yup, yup, yup,
> > extern <some data type> *var;
> [...]
Nooooooo!
> > I think this is correct now, because it makes sense.
> It does seem to make a whole lot of sense.
The latter doesn't. A pointer is (typically) a 32-bit area of
storage that contains the either the machine address of data
or NULL. An array is a contiguous block of memory that contains
the data itself. Do not confuse the two.
Read K&R again.
Phil
--
1st bug in MS win2k source code found after 20 minutes: scanline.cpp
2nd and 3rd bug found after 10 more minutes: gethost.c
Both non-exploitable. (The 2nd/3rd ones might be, depending on the CRTL)
|
|
0
|
|
|
|
Reply
|
Phil
|
2/22/2004 7:50:17 AM
|
|
>>>var: times 8 dd 0
>>>I can say
>>>extern int var[8];
>>>extern short int var[16];
>>>extern char var[32];
>>>and go as usual with arrays, or
>
> Yup, yup, yup,
>
>>>extern <some data type> *var;
>
> Nooooooo!
>
>>I think this is correct now, because it makes sense.
>
>> It does seem to make a whole lot of sense.
>
> The latter doesn't. A pointer is (typically) a 32-bit area of
> storage that contains the either the machine address of data
> or NULL. An array is a contiguous block of memory that contains
> the data itself. Do not confuse the two.
That post also contained:
--begin
But in the latter case I'm really working only with the first 4 bytes
of the area identified by var, and, for the same reason as before,
this will be a nil pointer, and chances are this is probably not what
I intended anyway, or, even worse, I can do
extern <some data type> *var[8];
and I'll end up with an array of 8 nil pointers (like before, probably
wrong).
--end
The point being that the OP has understood how the symbols and the
linking work; data types and the use of data are a different matter. You
may have been confused into thinking I passed a misunderstanding because
I cut out some stuff from that post I didn't think was necessary to repeat.
--
Remove the furry animal from my address to send email:
bjarni.ferret@update.ferret.uu.se
|
|
0
|
|
|
|
Reply
|
Bjarni
|
2/22/2004 6:03:17 PM
|
|
|
6 Replies
251 Views
(page loaded in 0.115 seconds)
Similiar Articles: External variables - comp.lang.asm.x86Environment: linux, gcc + nasm. I have an asm file containing a global data label, eg (NASM syntax): section .data global my_data ..... my_data: tim... Passing stem variables to an external subroutine - comp.lang.rexx ...Is there any way in Classic Rexx (Quercus Personal Rexx) to pass a stem variable to an external Rexx subroutine and have the subroutine assign its own... accessing a javascript variable using IHTMLDocument - comp.lang ...External variables - comp.lang.asm.x86 accessing a javascript variable using IHTMLDocument - comp.lang ... masm within VisualC++ question (accessing external global ... Finding environment variables usage - comp.unix.programmer ...E.g. under C can declare the external variable extern char **environ; which is an array of char pointers, each pointing to string a with one of the environment ... How to declare variable - comp.soft-sys.sasFinding environment variables usage - comp.unix.programmer ... E.g. under C can declare the external variable extern char **environ; which is an array of char pointers ... Microblaze and external block memory - comp.arch.fpgaExternal variables - comp.lang.asm.x86 So, do I have to deduce that an external data label (that, after all, _is_ a ... An array is a contiguous block of memory that ... Stem variables - comp.lang.rexxHere is a way of passing a stem to an external routine vie an ISPF variable. This is OK for smaller stems but there is probably a limit on the size of an ISPF variables ... Query with NULL - comp.databases.oracle.server> > Plus the fact that the job checking whether an external variable is null > really belongs to the programming interface and not the database. > > --http://mgogala ... Uninitialized variables, why do they equal their name? - comp.lang ...Passing stem variables to an external subroutine - comp.lang.rexx ... Stem variables - comp.lang.rexx Stem variables - comp.lang.rexx Uninitialized variables, why do they ... Are newbie questions OK in here? - comp.lang.asm.x86External variables - comp.lang.asm.x86 Are newbie questions OK in here? - comp.lang.asm.x86 External variables - comp.lang.asm.x86 Maybe this is a newbie question, but ... External variable - Wikipedia, the free encyclopediaIn the C programming language, an external variable is a variable defined outside any function block. On the other hand, a local (automatic) variable is a variable ... Apache ODE -- External VariablesExternal variables are declared in the <variables> section of the <scope> element, just like normal variables. However, unlike regular variables, external variables ... 7/17/2012 9:48:24 PM
|