comp.lang.ada
 help / color / mirror / Atom feed
* Executing machine code?
@ 1999-05-27  0:00 Ikram
  1999-05-27  0:00 ` David Brown
  1999-05-27  0:00 ` Samuel Mize
  0 siblings, 2 replies; 4+ messages in thread
From: Ikram @ 1999-05-27  0:00 UTC (permalink / raw)


I occasionally need to write programs that generate and execute
machine code (as in e.g. genetic programming systems).  in C, the
method I've been using is to store the machine instructions in an
array of bytes, and then cast the array into a function, e.g.:

  char code[MAX]; /* storage area for function's code. */
  code[0] = 0x55; /* code making up the function's preamble. */
  code[1] = ...
  ...
  code[x] = ... /* code making up the function's body. */
  code[x+1] = ...
  ...
  code[MAX-1] = 0xC3; /* return instruction. */
  
  /* now cast array pointer into a function pointer.  assume this 
     function takes one int argument and returns an int result, 
     using C parameter passing conventions. */
  f = (int (*)(int))code; 
  result = f(4); /* call the function. */

I'm trying to find out whether it is similarly possible to switch
between array and function representations in Ada (not necessarily in
a platform- or compiler-independent way).  or perhaps someone would
like to suggest an alternative means of executing machine code
generated on-the-fly from within Ada programs?  suggestions or
pointers to information would be welcome.

thanks,
Ikram
-- 
I. M. Ikram   <URL:http://www.cs.und.ac.za/~ikram/>   ikram@cs.und.ac.za




^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: Executing machine code?
  1999-05-27  0:00 Executing machine code? Ikram
@ 1999-05-27  0:00 ` David Brown
  1999-05-27  0:00 ` Samuel Mize
  1 sibling, 0 replies; 4+ messages in thread
From: David Brown @ 1999-05-27  0:00 UTC (permalink / raw)


>>>>> On 27 May 1999 16:50:10 +0200, Ikram <ikram@cs.und.ac.za> said:

> I occasionally need to write programs that generate and execute
> machine code (as in e.g. genetic programming systems).  in C, the
> method I've been using is to store the machine instructions in an
> array of bytes, and then cast the array into a function, e.g.:

>   char code[MAX]; /* storage area for function's code. */
>   code[0] = 0x55; /* code making up the function's preamble. */
>   code[1] = ...
>   ...
>   code[x] = ... /* code making up the function's body. */
>   code[x+1] = ...
>   ...
>   code[MAX-1] = 0xC3; /* return instruction. */
  
>   /* now cast array pointer into a function pointer.  assume this 
>      function takes one int argument and returns an int result, 
>      using C parameter passing conventions. */
>   f = (int (*)(int))code; 
>   result = f(4); /* call the function. */

Calling the code isn't very hard (see below).  With modern
architectures, it is often necessary to flush the data cache and/or
invalidate the instruction cache.  How this is done is very system
specific, and will most likely be provided as a service of your
operating system.

> I'm trying to find out whether it is similarly possible to switch
> between array and function representations in Ada (not necessarily in
> a platform- or compiler-independent way).  or perhaps someone would
> like to suggest an alternative means of executing machine code
> generated on-the-fly from within Ada programs?  suggestions or
> pointers to information would be welcome.

This conversion is making a few assumption about how the compiler
represents procedure (or function) access types, and system address.
I suggest finding out from your vendor how these are implemented.

----------------------------------------------------------------------
--
-- Casting example to a special procedure pointer.
--

with Ada.Unchecked_Conversion;
with System;

procedure Call is

   type Grunt_Call is access procedure (Arg : Integer);

   type Byte is mod 2**8;
   for Byte'Size use 8;

   type Byte_Array is array (Positive range <>) of Byte;
   pragma Pack (Byte_Array);

   Sample_Code : Byte_Array (1 .. 4);

   function "+" is
      new Ada.Unchecked_Conversion (System.Address, Grunt_Call);

   Perform_Grunt : Grunt_Call := "+"(Sample_Code(Sample_Code'First)'Address);

begin
   -- This is an x86 return instruction.
   Sample_Code (1) := 16#C3#;

   -- Processors with separate instruction and data caches may have to
   -- perform a system specific operation to make these caches coherent.

   -- Now we can execute.
   Perform_Grunt.all (10);
end Call;




^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: Executing machine code?
  1999-05-27  0:00 Executing machine code? Ikram
  1999-05-27  0:00 ` David Brown
@ 1999-05-27  0:00 ` Samuel Mize
  1999-05-28  0:00   ` Robert Dewar
  1 sibling, 1 reply; 4+ messages in thread
From: Samuel Mize @ 1999-05-27  0:00 UTC (permalink / raw)


Ikram <ikram@cs.und.ac.za> wrote:
> I occasionally need to write programs that generate and execute
> machine code (as in e.g. genetic programming systems).  in C, the
> method I've been using is to store the machine instructions in an
> array of bytes, and then cast the array into a function, e.g.:

My word.  I doubt you'll find a large body of people with experience
in this area.  :-)

> I'm trying to find out whether it is similarly possible to switch
> between array and function representations in Ada (not necessarily in
> a platform- or compiler-independent way).

I think you can accomplish what you want, at least with some compilers.
You'll need a compiler that supports the syntax for machine-language
instructions.  Write a routine that determines the address of the
first byte in your array of bytes, and then does a machine-language
subroutine jump to that address.

I specify "first byte in the array" because some compilers, at least
some older Ada 83 compilers, may return the address of a dope vector
if you just use 'address.

You may need to decide where to put the array in memory, and use a
representation clause to put it there.

Best of luck, and let us know how it works out!

Sam Mize

-- 
Samuel Mize -- smize@imagin.net (home email) -- Team Ada
Fight Spam: see http://www.cauce.org/ \\\ Smert Spamonam




^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: Executing machine code?
  1999-05-27  0:00 ` Samuel Mize
@ 1999-05-28  0:00   ` Robert Dewar
  0 siblings, 0 replies; 4+ messages in thread
From: Robert Dewar @ 1999-05-28  0:00 UTC (permalink / raw)


In article <7ijqgs$26o@news2.newsguy.com>,
  Samuel Mize <smize@imagin.net> wrote:

> My word.  I doubt you'll find a large body of people with
> experience in this area.  :-)

Actually a lot of GNAT and GNU C users do this without realizing
it because the implementation of trampolines does exactly this
(create code in the stack on the fly and then execute it).

Investigating the gcc implementation of trampolines is a good
idea here, it will show you EXACTLY what needs to be done for
handling the caches correctly.

(the last time I did this kind of thing explicitly was in
implementing complex events for the Alsys x86 CIFO
implementation for NASA. I actually generated the appropriate
boolean predicate code on the fly as a dynamic function :-)


Sent via Deja.com http://www.deja.com/
Share what you know. Learn what you don't.




^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~1999-05-28  0:00 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
1999-05-27  0:00 Executing machine code? Ikram
1999-05-27  0:00 ` David Brown
1999-05-27  0:00 ` Samuel Mize
1999-05-28  0:00   ` Robert Dewar

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox