comp.lang.ada
 help / color / mirror / Atom feed
From: David Brown <davidb-cla@davidb.org>
Subject: Re: Executing machine code?
Date: 1999/05/27
Date: 1999-05-27T00:00:00+00:00	[thread overview]
Message-ID: <osu2sycw85.fsf@opus.davidb.org> (raw)
In-Reply-To: 86u2sya7od.fsf@finch.cs.und.ac.za

>>>>> 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;




      parent reply	other threads:[~1999-05-27  0:00 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
1999-05-27  0:00 Executing machine code? Ikram
1999-05-27  0:00 ` Samuel Mize
1999-05-28  0:00   ` Robert Dewar
1999-05-27  0:00 ` David Brown [this message]
replies disabled

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