* A copy question....
@ 2001-10-15 10:40 Zebylon
2001-10-15 11:21 ` Dale Stanbrough
` (3 more replies)
0 siblings, 4 replies; 14+ messages in thread
From: Zebylon @ 2001-10-15 10:40 UTC (permalink / raw)
If you have an system.address variable, an data length variable and an array
of Unsigned_32. How can you move the data ranging between the address and
the address+data_length into the array?
I.G.
Address : System.address := 0x0200_0000;
Data_Length : Natural := 200; --bytes
Array : array range (integer 0..375) of Unsigned_32;
Is there some smart way of placing the data in the array...?
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: A copy question....
2001-10-15 10:40 A copy question Zebylon
@ 2001-10-15 11:21 ` Dale Stanbrough
2001-10-15 11:30 ` Dale Stanbrough
2001-10-15 13:38 ` Ted Dennison
2001-10-15 13:30 ` Mark Doherty
` (2 subsequent siblings)
3 siblings, 2 replies; 14+ messages in thread
From: Dale Stanbrough @ 2001-10-15 11:21 UTC (permalink / raw)
In article <9qedad$i1p$1@newstoo.ericsson.se>,
"Zebylon" <sebastian.madunic@esavionics.se> wrote:
> If you have an system.address variable, an data length variable and an array
> of Unsigned_32. How can you move the data ranging between the address and
> the address+data_length into the array?
>
> I.G.
>
> Address : System.address := 0x0200_0000;
> Data_Length : Natural := 200; --bytes
> Array : array range (integer 0..375) of Unsigned_32;
>
> Is there some smart way of placing the data in the array...?
Convert the address to an access type using an instantiation of the
generic
System.Address_To_Access_Conversions.To_Pointer
and then dereference the pointer generated by the function...
function Address_To_Int_Pointer is new
To_Pointer (Int_Pointer);
...
for i in Array'range loop
Array (i) := Address_To_Int_Pointer (Address).all;
Address := Address + Unsigned_32'Size/8;
-- i think there is a constant somewhere i should use instead of 8
end loop;
note that the "+" operator is from System.Storage_Elements
Alternatively you could dive into either the OS API, which could well
have a block move instruction (realloc?), or call any relavent assembler
instruction.
Dale
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: A copy question....
2001-10-15 11:21 ` Dale Stanbrough
@ 2001-10-15 11:30 ` Dale Stanbrough
2001-10-15 11:59 ` Petter Fryklund
2001-10-15 13:38 ` Ted Dennison
1 sibling, 1 reply; 14+ messages in thread
From: Dale Stanbrough @ 2001-10-15 11:30 UTC (permalink / raw)
Dale Stanbrough wrote:
> Convert the address to an access type using an instantiation of the
> generic
>
> System.Address_To_Access_Conversions.To_Pointer
>
> and then dereference the pointer generated by the function...
>
> function Address_To_Int_Pointer is new
> To_Pointer (Int_Pointer);
>
> ...
> for i in Array'range loop
> Array (i) := Address_To_Int_Pointer (Address).all;
> Address := Address + Unsigned_32'Size/8;
> -- i think there is a constant somewhere i should use instead of 8
> end loop;
Silly me. I didn't check the code. System.Address_To_Access_Conversion
is a generic package, not a package with a generic function.
You'll need to instantiate it as...
package To_Int_Pointers is
new System.Address_To_Access_Conversion (Int_Pointer);
and then you'll call the To_Pointer function in this package.
Dale
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: A copy question....
2001-10-15 11:30 ` Dale Stanbrough
@ 2001-10-15 11:59 ` Petter Fryklund
2001-10-15 21:04 ` Dale Stanbrough
0 siblings, 1 reply; 14+ messages in thread
From: Petter Fryklund @ 2001-10-15 11:59 UTC (permalink / raw)
Wouldn't it be more efficient to let Int_Pointer point to an Array of
Unsigned_32 and instead of looping just assign the value by means of:
Array (0 .. 199) := Address_To_Int_Pointer (Address).all (0 .. 199);
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: A copy question....
2001-10-15 11:59 ` Petter Fryklund
@ 2001-10-15 21:04 ` Dale Stanbrough
2001-10-16 2:34 ` Jeffrey Carter
0 siblings, 1 reply; 14+ messages in thread
From: Dale Stanbrough @ 2001-10-15 21:04 UTC (permalink / raw)
Petter Fryklund wrote:
> Wouldn't it be more efficient to let Int_Pointer point to an Array of
> Unsigned_32 and instead of looping just assign the value by means of:
>
> Array (0 .. 199) := Address_To_Int_Pointer (Address).all (0 .. 199);
I hadn't thought of that! Certainly better notationally - probably
more efficient at the computer level as well.
Dale
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: A copy question....
2001-10-15 21:04 ` Dale Stanbrough
@ 2001-10-16 2:34 ` Jeffrey Carter
2001-10-16 11:15 ` Dale Stanbrough
0 siblings, 1 reply; 14+ messages in thread
From: Jeffrey Carter @ 2001-10-16 2:34 UTC (permalink / raw)
Dale Stanbrough wrote:
>
> > Array (0 .. 199) := Address_To_Int_Pointer (Address).all (0 .. 199);
>
> I hadn't thought of that! Certainly better notationally - probably
> more efficient at the computer level as well.
The .all is not required. Note also that using
Address_To_Access_Conversions on an unconstrained array type is unlikely
to give the desired results. The compiler has no way to determine the
designated object's bounds. A constrained subtype is usually OK, but I
think using an address clause to locate an object of the desired type
and bounds is usually best.
--
Jeff Carter
"We call your door-opening request a silly thing."
Monty Python & the Holy Grail
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: A copy question....
2001-10-15 11:21 ` Dale Stanbrough
2001-10-15 11:30 ` Dale Stanbrough
@ 2001-10-15 13:38 ` Ted Dennison
1 sibling, 0 replies; 14+ messages in thread
From: Ted Dennison @ 2001-10-15 13:38 UTC (permalink / raw)
In article <dale-238AFE.21195615102001@mec2.bigpond.net.au>, Dale Stanbrough
says...
>
>In article <9qedad$i1p$1@newstoo.ericsson.se>,
> "Zebylon" <sebastian.madunic@esavionics.se> wrote:
>
>> If you have an system.address variable, an data length variable and an array
>> of Unsigned_32. How can you move the data ranging between the address and
>> the address+data_length into the array?
..
>Convert the address to an access type using an instantiation of the
>generic
But a *really* smart Ada developer will never get him/herself into this
situation in the first place. Instead, you pick better types, that don't need to
be converted. In *rare* circumstances something like this may be unaviodable.
---
T.E.D. homepage - http://www.telepath.com/dennison/Ted/TED.html
No trees were killed in the sending of this message.
However a large number of electrons were terribly inconvenienced.
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: A copy question....
2001-10-15 10:40 A copy question Zebylon
2001-10-15 11:21 ` Dale Stanbrough
@ 2001-10-15 13:30 ` Mark Doherty
2001-10-15 17:00 ` tmoran
2001-10-16 23:00 ` David Botton
3 siblings, 0 replies; 14+ messages in thread
From: Mark Doherty @ 2001-10-15 13:30 UTC (permalink / raw)
> If you have an system.address variable, an data length variable and an array
> of Unsigned_32. How can you move the data ranging between the address and
> the address+data_length into the array?
Take a look at:
for ... use (at) clause (ada83/95 syntax dependant),
pragma volatile and
pragma import.
in the lrm.
p.s. be careful with the sizes as you are impling 375*4 bytes of array
and 200 bytes of address space!
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: A copy question....
2001-10-15 10:40 A copy question Zebylon
2001-10-15 11:21 ` Dale Stanbrough
2001-10-15 13:30 ` Mark Doherty
@ 2001-10-15 17:00 ` tmoran
2001-10-16 10:09 ` Mark Doherty
2001-10-16 23:00 ` David Botton
3 siblings, 1 reply; 14+ messages in thread
From: tmoran @ 2001-10-15 17:00 UTC (permalink / raw)
with System,
System.Storage_Elements,
Interfaces;
procedure Test is
Address : System.Address
:= System.Storage_Elements.To_Address(16#0200_0000#);
Data_Length: Natural := 200; --bytes
type Dword_Arrays is array (Integer range <>) of Interfaces.Unsigned_32;
Source : Dword_Arrays(0 .. 49); -- 50*32=200*8
for Source'Address use Address;
Target : Dword_Arrays(0 .. 375);
begin
Target(Source'range) := Source;
end Test;
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: A copy question....
2001-10-15 17:00 ` tmoran
@ 2001-10-16 10:09 ` Mark Doherty
2001-10-17 0:18 ` tmoran
0 siblings, 1 reply; 14+ messages in thread
From: Mark Doherty @ 2001-10-16 10:09 UTC (permalink / raw)
tmoran@acm.org wrote in message news:<mCEy7.18793$gT6.11921721@news1.rdc1.sfba.home.com>...
> with System,
> System.Storage_Elements,
> Interfaces;
> procedure Test is
> Address : System.Address
> := System.Storage_Elements.To_Address(16#0200_0000#);
> Data_Length: Natural := 200; --bytes
> type Dword_Arrays is array (Integer range <>) of Interfaces.Unsigned_32;
> Source : Dword_Arrays(0 .. 49); -- 50*32=200*8
> for Source'Address use Address;
> Target : Dword_Arrays(0 .. 375);
> begin
> Target(Source'range) := Source;
> end Test;
The use of
> for Source'Address use Address;
is not portable.
Rational would initialise Source to 0's (unless the Pragma Import is used).
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: A copy question....
2001-10-16 10:09 ` Mark Doherty
@ 2001-10-17 0:18 ` tmoran
2001-10-17 1:14 ` David Botton
0 siblings, 1 reply; 14+ messages in thread
From: tmoran @ 2001-10-17 0:18 UTC (permalink / raw)
> The use of
> > for Source'Address use Address;
> is not portable.
>
> Rational would initialise Source to 0's (unless the Pragma Import is used).
It's not a portability problem, it's an error in the code I posted. :(
Most compilers of my acquaintance only initialize things with
initializers, and don't initialize simple arrays of integers. But that
just demonstrates the disadvantages of not using a diversity of compilers.
Yes indeed there should be a Pragma Import.
As I read the LRM, the array Source ought to be declared aliased, also.
Speaking of portability,
> function To_Pointer_To_The_Array is
> new Ada.Unchecked_Conversion (System.Address, Pointer_To_The_Array);
is not portable, while
package System.Address_To_Access_Conversions
is specifically designed to do what you want.
> Put_Line (Copied_Array (N)'Img);
The 'Img attribute is a "vendor special", 'Image would be portable.
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: A copy question....
2001-10-17 0:18 ` tmoran
@ 2001-10-17 1:14 ` David Botton
0 siblings, 0 replies; 14+ messages in thread
From: David Botton @ 2001-10-17 1:14 UTC (permalink / raw)
I was showing my "favorite" method. The use of the 'Img was part of the test
driver. It is a convenience that I am surprised has not been adopted by
other vendors.
I admit that since most of my Ada programming is with GNAT, I get lazy about
portability to other compilers.
Here is a more universal version:
with Ada.Text_IO; use Ada.Text_IO;
with System.Address_To_Access_Conversions;
with System;
with Interfaces;
procedure Block is
type My_Array is array (Integer range <>) of Interfaces.Unsigned_32;
Stuff_In_Memory : My_Array (1 .. 200) := (others => 999);
Address : System.Address := Stuff_In_Memory (1)'Address;
Data_Length : Natural := Stuff_In_Memory'Length;
-- Assuming of Unsigned_32s
type The_Array is new My_Array (1 .. Data_Length);
pragma Pack (The_Array);
package Array_Copier is
new System.Address_To_Access_Conversions (The_Array);
Copied_Array : The_Array := Array_Copier.To_Pointer (Address).all;
begin
for N in Copied_Array'Range loop
Put_Line (Interfaces.Unsigned_32'Image (Copied_Array (N)));
end loop;
end Block;
<tmoran@acm.org> wrote in message
news:t74z7.24114$gT6.15011939@news1.rdc1.sfba.home.com...
> Speaking of portability,
> > function To_Pointer_To_The_Array is
> > new Ada.Unchecked_Conversion (System.Address, Pointer_To_The_Array);
> is not portable, while
> package System.Address_To_Access_Conversions
> is specifically designed to do what you want.
> > Put_Line (Copied_Array (N)'Img);
> The 'Img attribute is a "vendor special", 'Image would be portable.
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: A copy question....
2001-10-15 10:40 A copy question Zebylon
` (2 preceding siblings ...)
2001-10-15 17:00 ` tmoran
@ 2001-10-16 23:00 ` David Botton
3 siblings, 0 replies; 14+ messages in thread
From: David Botton @ 2001-10-16 23:00 UTC (permalink / raw)
----- Original Message -----
From: "Zebylon" <sebastian.madunic@esavionics.se>
> Is there some smart way of placing the data in the array...?
This is my favorite method and if you don't need a copy, but just an easy
way to access the memory, you can just use the returned Pointer_To_The_Array
directly instead of copying it.
I think the compiler will likely figure out the best way to make the block
copy on the platform :-)
with GNAT.IO; use GNAT.IO;
with Ada.Unchecked_Conversion;
with System;
with Interfaces;
procedure Block is
type My_Array is array (Integer range <>) of Interfaces.Unsigned_32;
Stuff_In_Memory : My_Array (1 .. 200) := (others => 999);
Address : System.Address := Stuff_In_Memory (1)'Address;
Data_Length : Natural := Stuff_In_Memory'Length;
type The_Array is new My_Array (1 .. Data_Length);
type Pointer_To_The_Array is access all The_Array;
function To_Pointer_To_The_Array is
new Ada.Unchecked_Conversion (System.Address, Pointer_To_The_Array);
Copied_Array : The_Array := To_Pointer_To_The_Array (Address).all;
begin
for N in Copied_Array'Range loop
Put_Line (Copied_Array (N)'Img);
end loop;
end Block;
^ permalink raw reply [flat|nested] 14+ messages in thread
end of thread, other threads:[~2001-10-17 1:14 UTC | newest]
Thread overview: 14+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2001-10-15 10:40 A copy question Zebylon
2001-10-15 11:21 ` Dale Stanbrough
2001-10-15 11:30 ` Dale Stanbrough
2001-10-15 11:59 ` Petter Fryklund
2001-10-15 21:04 ` Dale Stanbrough
2001-10-16 2:34 ` Jeffrey Carter
2001-10-16 11:15 ` Dale Stanbrough
2001-10-15 13:38 ` Ted Dennison
2001-10-15 13:30 ` Mark Doherty
2001-10-15 17:00 ` tmoran
2001-10-16 10:09 ` Mark Doherty
2001-10-17 0:18 ` tmoran
2001-10-17 1:14 ` David Botton
2001-10-16 23:00 ` David Botton
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox