2010-07-14 19 views
5

Eso podría ser un problema un poco exótico, pero espero que alguien pueda todavía me ayude un poco;). Me gustaría ejecutar un programa C estándar, , sin embargo, en algún momento durante la ejecución del programa me gustaría que se ejecute un cierto número de instrucciones , que se almacenan en una memoria RAM de libreta local, . La memoria del bloc de notas es accesible para todos los procesos. Vamos a suponer esta memoria local comienza en la dirección 0x80000000 y me gustaría integrar este en el siguiente código C fragementAcceder a la memoria del bloc de notas desde C

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

}

El contador de programa pasaría a través de las siguientes etapas, asumiendo principal se carga en 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); 

¿Alguien una idea de cómo hacer esto? ¿Necesito usar assembler jump o hay algo más elegante?

Muchas gracias, Andi

+2

¿El programa en 0x80000000 se comporta como una función? Es decir. ¿salvará la pila correctamente y ejecutará un salto de regreso a la persona que llama? – bstpierre

Respuesta

0

para saltar a una ubicación fija, se puede declarar un tipo que es un puntero a una función, entonces emitir su dirección a ese tipo y llamarlo como una función.

Si desea que esta área de memoria sea accesible para procesos que no sean su programa, deberá usar las primitivas de memoria compartida de su sistema operativo (Windows/Linux/OS X) para asignar un fragmento de memoria a la dirección elegida .

Suena como una idea loca, pero podría hacerse funcionar. ¡Buena suerte!

+0

Bueno, hay procesadores integrados que vienen con memoria de memoria virtual, por lo que debería ser factible. Desafortunadamente, no he visto ningún ejemplo que demuestre el uso de tales memorias locales. Gracias por su aporte, lo echaré un vistazo. – Rob

6

Suponiendo que las instrucciones que se comportan como una función normal, que puede hacer:

#include <stdio.h> 

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

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

Obviamente, usted tiene que estar utilizando un sistema operativo de modo real, o saltar a través de aros cualquiera que sea su combinación OS/procesador requiere tener acceso directo a ese espacio de direcciones.

(En algunas arquitecturas "se comportan como una función normal" es tan simple como un "salto $ ra" al final si no se toca registros de abonado llamado salvado. Por ejemplo MIPS.)

+0

Eso parece aterrador, pero lo intentaré. ¡Gracias por eso! – Rob

+0

-1 No hay nada que garantice que las instrucciones ubicadas en la dirección se comporten como una función. El OP quiere ejecutar una cantidad fija de instrucciones ubicadas allí. –

+1

@Jens Gusted: así la calificación en mi respuesta ... – bstpierre

0

Bueno un par de pistas.

  1. Debe asegurarse de que la memoria en el "bloc de notas" es direccionable y ejecutable.
  2. Asegúrese de que la secuencia de instrucciones en la posición de memoria termina con una instrucción ret
  3. call el código en lugar de saltar a ella.
1

Ni la dirección de fundición a un puntero de función ni ensamblador se normaliza, de modo que nada de eso sería portátil ;-)

correlación de la dirección fija como Carl menciona que es posible con POSIX, pero luego otra vez a ejecutarlo, no hay una manera simple.

Lo que ninguno de los post anteriores responde, es cómo saltar atrás después de exactamente tres instrucciones ...

La única forma en que puedo pensar sería copiar las instrucciones en algún lugar y colocar un salto incondicional inmediatamente después. Luego use una instrucción de ensamblador en línea para saltar a esa ubicación.

Cuestiones relacionadas