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