[comp.lang.ada] Memory Access Question

tony@ucf-cs.ucf.edu (07/27/89)

Does anyone have a code fragment that demonstrates how to access memory?
I am looking for a program that tests memory.  Instruction and data space
are seperate on my machine and I am trying to test RAM from 0 to n.  I have
looked at the "access" data type and can't figure out how to initialize it
to 0 let alone increment the pointer by 1.  The representation
specification doesn't seem to provide the answer either.  Any and all help
is greatly appreciated.

Tony Becker			Phone: 407-356-9334
University of Central Florida	csnet: tony@ucf-cs.ucf.edu
Orlando, FL  32816		uucp:  {ihnp4!decvax,peora}!ucf-cs!tony

hammondr@sunroof.crd.ge.com (richard a hammond) (07/27/89)

In article <18800002@ucf-cs.ucf.edu> tony@ucf-cs.ucf.edu writes:
>
>Does anyone have a code fragment that demonstrates how to access memory?
>I am looking for a program that tests memory.  Instruction and data space
>are seperate on my machine and I am trying to test RAM from 0 to n.  I have
>looked at the "access" data type and can't figure out how to initialize it
>to 0 let alone increment the pointer by 1.  The representation
>specification doesn't seem to provide the answer either.  Any and all help
>is greatly appreciated.
>Tony Becker			Phone: 407-356-9334
>University of Central Florida	csnet: tony@ucf-cs.ucf.edu
>Orlando, FL  32816		uucp:  {ihnp4!decvax,peora}!ucf-cs!tony

Argh!!! No matter what you come up with in Ada, I can't believe that it
would be portable across all machines - so why try to write it in Ada?

Why not make it explicit to the next person porting the code that this
code is going to break all the access controls and possibly muck up
all memory (or do you just want to see if you can read it?) and write
it in assembler?

Besides, the several lines of assembly required to do this are as readable
for most competent programmers as the dozens of lines of Ada.

If you're doing a lot of other work, just write a trivial assembly
language routine that takes two unsigned integers and stuffs the
second argument's lower n (n = 8, 16, 32, 64, ...) bits into the
physical/logical address implied by treating the first argument as
an address.  And another assembly routine to read the contents.

Ada was designed to write portable, safe software.  Reading/writing
all locations in memory is possibly portable, but certainly not safe.
Use the tool suited to the job, assembly language.

Rich Hammond

trent@unix.SRI.COM (Ray Trent) (07/28/89)

In the above article, hammondr@sunroof.crd.ge.com (richard a hammond) writes:
>In article <18800002@ucf-cs.ucf.edu> tony@ucf-cs.ucf.edu writes:
>>I am looking for a program that tests memory.  Instruction and data space
>>are seperate on my machine and I am trying to test RAM from 0 to n.  I have
>[various other grumbling]
>Ada was designed to write portable, safe software.  Reading/writing
>all locations in memory is possibly portable, but certainly not safe.
>Use the tool suited to the job, assembly language.

Why not just say: No, you can't do it in Ada (easily), nor should you
want to. This is not convincing if a client wants *all* of the code
delivered to be written in Ada (many of them are absolutely stupid
about this). Or perhaps you could just say: check if your
implementation uses integers as pointers and use unchecked conversion
to do pointer arithmetic. 

The answer to the question is: it's implementation dependent whether
you can even do what you want in Ada...if access types are implemented
as integers, you have a pretty good chance of being able to do what
you want via unchecked conversion. If that's unacceptable, then you're
out of luck, use another language.
-- 
"When you're down, it's a long way up
 When you're up, it's a long way down
 It's all the same thing
 And it's no new tale to tell"                      ../ray\..

murphy@mips.COM (Mike Murphy) (07/28/89)

Others have commented that you should write in assembler to 
do low-level memory accesses, but keep in mind that you don't
really need to leave Ada to use assembly language:  just use
machine-code insertions!   It's for this kind of application
that Ada provides machine_code.  Now if your compiler does not 
support machine code then you're out of luck, but a number of 
good Ada compilers do.
-- 
-- Mike Murphy
-- UUCP: sun!decwrl!mips!murphy
-- AT&T: (408) 991-0438

brians@hpcljms.HP.COM (Brian Sullivan) (07/29/89)

  It is possible to use UNCHECKED_CONVERSION to provide access
memory locations.  The following Ada package will allows you
to read and write to memory locations.

  The file depends on the existence of a predefined integer type
that is the same size as SYSTEM.ADDRESS, and the SYSTEM.ADDRESS
is of the same size as a pointer or access object.

------------------------------------------------------------------------
with SYSTEM;
package MEMORY is

   --
   -- The predefined integer type used for the type ADDR_INT
   -- must be the same size in bits as the type SYSTEM.ADDRESS
   -- because unchecked conversion is used to convert ADDR_INT
   -- into SYSTEM.ADDRESS
   --
   -- Also the size of an access type must be the same as the
   -- size of SYSTEM.ADDRESS
   --
   -- These two requirements are automatically check in the
   -- elaboration code for the body of this package.
   --

   type ADDR_INT is new INTEGER;      

   type DATUM is range 0 .. (2**SYSTEM.STORAGE_UNIT)-1;

   function  READ ( FROM : ADDR_INT ) return DATUM;
   
   procedure WRITE( TO : ADDR_INT; VALUE : DATUM);
   
   function  CONVERT_TO_ADDR_INT( LOC : SYSTEM.ADDRESS) return ADDR_INT; 
   
private

   pragma INLINE(READ);
   pragma INLINE(WRITE);
   pragma INLINE(CONVERT_TO_ADDR_INT);

   for DATUM'SIZE use SYSTEM.STORAGE_UNIT;
   
end MEMORY;   

with UNCHECKED_CONVERSION;
package body MEMORY is

   type DATUM_PTR is access DATUM;
   
   function CONVERT_TO_DATUM_PTR is 
      new UNCHECKED_CONVERSION( SOURCE => ADDR_INT,
                                TARGET => DATUM_PTR);
   pragma INLINE(CONVERT_TO_DATUM_PTR);

   function LOCAL_CONVERT_TO_ADDR_INT is 
      new UNCHECKED_CONVERSION( SOURCE => SYSTEM.ADDRESS,
                                TARGET => ADDR_INT);
   pragma INLINE(LOCAL_CONVERT_TO_ADDR_INT);

   function  READ ( FROM : ADDR_INT ) return DATUM is
   begin
      return CONVERT_TO_DATUM_PTR(FROM).all;
   end;
   
   procedure WRITE( TO : ADDR_INT; VALUE : DATUM) is
   begin
      CONVERT_TO_DATUM_PTR(TO).all := VALUE;
   end;
   
   function  CONVERT_TO_ADDR_INT( LOC : SYSTEM.ADDRESS) return ADDR_INT is
   begin
      return LOCAL_CONVERT_TO_ADDR_INT(LOC);
   end;
   
begin
   if ADDR_INT'SIZE /= SYSTEM.ADDRESS'SIZE then
      raise PROGRAM_ERROR;
   end if;    
   if DATUM_PTR'SIZE /= SYSTEM.ADDRESS'SIZE then
      raise PROGRAM_ERROR;
   end if;    
end MEMORY;   
   
   
 

walsh@stdc01.UUCP (Mike Walsh) (08/02/89)

>>Others have commented that you should write in assembler to 
>>do low-level memory accesses, but keep in mind that you don't
>>really need to leave Ada to use assembly language:  just use
>>machine-code insertions!   It's for this kind of application
>>that Ada provides machine_code.  Now if your compiler does not 
>>support machine code then you're out of luck, but a number of 
>>good Ada compilers do.
>>-- 
>>-- Mike Murphy
>>-- UUCP: sun!decwrl!mips!murphy
>>-- AT&T: (408) 991-0438

 In my experience, writing machine code insertions is not as trivial as
 this posting makes it out to be.  The project I worked on was and ARMY
 contract and they wanted everything done in Ada.  We were using the
 Softech Ada86 Compiler and an Intel 80186.  Softech provided the Machine
 Code Package, but it was incomplete or erroneous.  Plus anyone writing
 machine code insertions had better be better than just average assembly
 language programmer.  IMHO it is better to write the routine in Assembly,
 and pass an Address to the routine from the Ada caller, or just invoke
 an Assembly Language routine from Ada, since if the code needs to be 
 protable, it is likely that the architecture of the machine that the
 porting is being done on is different from the original machine.  Since
 the architecture is most likely different, the memory scheme is probably
 different.  I also feel that a good Assembly Language Routine that is
 well documented is much more maintainable than a peice of code written
 in machine code insertions.  BTW, machine code insertions are machine
 dependent anyway.


...Mike

Mike Walsh, Electrical Engineer
Star Technologies 
Graphicon Products Division
P.O. Box 13951
Reserach Triangle Park, NC 27709
(919) 361-3800

walsh@stdc01.UUCP   {...!uunet!mcnc!rti!stdc01!walsh}

murphy@mips.COM (Mike Murphy) (08/03/89)

In article <513@stdc01.UUCP> walsh@stdc01.UUCP (Mike Walsh) writes:
> In my experience, writing machine code insertions is not as trivial as
> this posting makes it out to be.  The project I worked on was and ARMY
> contract and they wanted everything done in Ada.  We were using the
> Softech Ada86 Compiler and an Intel 80186.  Softech provided the Machine
> Code Package, but it was incomplete or erroneous.  Plus anyone writing
> machine code insertions had better be better than just average assembly
> language programmer.  IMHO it is better to write the routine in Assembly,
> and pass an Address to the routine from the Ada caller, or just invoke
> an Assembly Language routine from Ada....

It sounds to me like your problem was not with machine code but that your 
compiler provided a weak implementation of machine code.  Machine code
lets you access the full range of assembly language, plus (at least in 
Verdix-based implementations) allows you to access Ada objects from 
within machine code.  So anything you can do in pure assembly language 
you can also do in machine code, plus you have added functionality.
The ability to access Ada objects (parameters and global variables)
is a definite advantage of machine code (admittedly this functionality 
does not have to be supported and is not in all implementations of 
machine code).  Plus you can enhance performance by inlining machine code 
procedures, unlike assembly language routines that are linked in.

> ....  I also feel that a good Assembly Language Routine that is
> well documented is much more maintainable than a peice of code written
> in machine code insertions. 

Why?  What's the difference between the two?

-- 
-- Mike Murphy
-- UUCP: sun!decwrl!mips!murphy
-- AT&T: (408) 991-0438