views:

81

answers:

4

Hi,

That might be a little bit an exotic problem, but I hope somebody can still help me out a bit ;). I would like to execute a standard C program, however, at some point during program execution I would like that a certain number of instructions, which are stored in a local scratch pad RAM, are executed. The scratchpad memory is accessable for all processes. Lets assume this local memory starts at address 0x80000000 and I would integrate this in the following C code fragement

int main {
int a=1;
int b=2;
int c=3;    

c = a + b;

%goto address 0x80000000 and execute three instructions before continuing
%program execution here 

return(0);

}

The program counter would go through the following stages, assuming main is loaded at 0x40000000

0x40000000    a=5; 
0x40000004    b=2; 
0x40000008    c=1;  
0x4000000C    c=a+b;
0x80000000    first instruction in the local scratch pad
0x80000004    second instruction in the local scratch pad
0x80000008    third instruction in the local scratch pad  
0x40000010    return(0);

Anyone an idea how to do this? Do I need to use assembler jump instructions or is there something more elegant.

Many thanks, Andi

A: 

To jump to a fixed location, you can declare a type that's a pointer to a function, then cast your address to that type and call it as a function.

If you want this memory area to be accessible to processes other than your program, you'll have to use your operating system's (Windows/Linux/OS X) shared memory primitives to map a chunk of memory to your chosen address.

Sounds like a crazy idea, but it could be made to work. Good luck!

Carl Smotricz
Well, there are embedded processors that come with scratch pad memory so it should be doable. Unfortunately, I have not seen any example that demonstrate the use of such local memories. Thanks for your input, I will have a look at it.
Rob
+5  A: 

Assuming that the instructions behave like a normal function, you can do:

#include <stdio.h>

void (*scratchpad_func)(void) = (void(*)(void))0x80000000;

int main()
{
    printf("before\n");
    scratchpad_func();
    printf("after\n");
    return 0;
}

Obviously, you'll have to be using a real mode operating system, or jump through whatever hoops your OS/processor combination requires to have direct access to that address space.

(On some architectures "behave like a normal function" is as simple as a "jump $ra" at the end if you don't touch callee-saved registers. E.g. MIPS.)

bstpierre
That looks scary but I will give it a go. Thanks for that!
Rob
-1 There is nothing that guarantees that the instructions located at the address behaves as a function. The OP wants to execute a fixed number of instructions located there.
Jens Gustedt
@Jens Gusted: thus the qualification in my answer...
bstpierre
@Jens Gustedt: well obviously it depends to an extent what the machine architecture is, but there is no general reason why this would not work except that the last instruction has to be a return instruction.
JeremyP
A: 

Well a couple of hints.

  1. You need to ensure that the memory in the "scratch pad" is addressable and executable.
  2. Make sure that the sequence of instructions in the memory location ends with a ret instruction
  3. call the code rather than jumping to it.
torak
A: 

Neither casting the address to a function pointer nor inline assembler is normalized, so nothing of that would be portable ;-)

Mapping the fixed address as Carl mentions is possible with POSIX, but then again to get it executed, there is no simple way.

What none of the previous post answers either, is how to jump back after exactly three instructions...

The only way I can think of would really be to copy just the three instructions somewhere and place an unconditional jump immediately after it. Then use an inline assembler instruction to jump to that location.

Jens Gustedt