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
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.)
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.
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!
Well a couple of hints.
ret
instructioncall
the code rather than jumping to it.User contributions licensed under CC BY-SA 3.0