2008-11-20 16 views
6

Me doy cuenta de que el compilador es específico, pero mi expectativa es que la ubicación del especificador de lejos tenga sentido para aquellos que realmente entienden los punteros.Uso de los punteros de función de lejos

Tengo dos aplicaciones que comparten todo el espacio de memoria del procesador.

la aplicación A tiene que llamar a la función foo que existe en aplicación B.

Sé que la posición de memoria de función foo.

Así que esto debería funcionar, en aplicación R:

typedef int (* __far MYFP)(int input); 

void somefunc(void) 
{ 
    int returnvalue; 
    MYFP foo; 

    foo = (MYFP) 0xFFFFFA; 

    returnvalue = foo(39); 
} 
  • ¿Está el __far en el lugar correcto en el typedef?
  • ¿Debo agregar __far al molde (MYFP)?
  • Alguna información sugiere que la llamada a foo no necesita ser desreferenciada, ¿cuál es su experiencia?
  • ¿Qué más parece incorrecto o podría tratar de lograrlo?

  • ¿Hay una mejor manera de hacerlo?

Editar:

Se trata de un dispositivo embebido (dispositivo de Freescale S12XEQ) utilizando código de Guerrero. Es un dispositivo de 16 bits con un espacio de memoria de 24 bits, así que sí, está segmentado/en bancos.

-Adam

+0

¿Puede dar más información? ¿En qué plataforma estás? Qué compilador estas usando? – grieve

Respuesta

8

¿Está el __far en el lugar correcto en el typedef?

[Editar, en respuesta al comentario de ChrisN - gracias]

Ésta es una característica dependiente del compilador, ya que no es parte de la norma ANSI C. De acuerdo con el manual del compilador < http://www.freescale.com/files/soft_dev_tools/doc/ref_manual/CW_Compiler_HC12_RM.pdf >, capítulo 8 , lo tienes colocado correctamente. En otros compiladores, es posible que deba revertir el pedido. Sin embargo, esto debería ser bastante fácil de entender, ya que exactamente una de las dos opciones se compilará con cualquier compilador determinado.

¿Debo agregar __far al molde (MYFP)?

No, es parte del tipo.

Alguna información sugiere que la llamada a foo no necesita ser desreferenciada, ¿cuál es su experiencia?

punteros de función se pueden dereferenced opcionalmente en C. Las siguientes líneas son válidas tanto hacen exactamente lo mismo:

foo = (MYFP)0xFFFFFA; 
returnvalue = foo(39); // 1 
returnvalue = (*foo)(39); // 2 

¿Qué más acerca de esto parece incorrecta, o puede que tratar de lograr esto?

Lo ha hecho con exactitud.

+1

Buena respuesta, excepto que la documentación del compilador que está utilizando indica que la sintaxis del puntero a la función debe ser typedef int (* __far MYFP) (int). Ver http://www.freescale.com/files/soft_dev_tools/doc/ref_manual/CW_Compiler_HC12_RM.pdf – ChrisN

10

El __far de palabras clave, al menos en el mundo MS, se utilizó al crear binarios que utilizan memoria segmentada. Necesita comprender el sistema de memoria 8086 para entender esto. El 8086 dividió la memoria en segmentos, cada segmento tenía 64K de longitud, por lo que cada dirección en un segmento necesitaba 16bits. Las direcciones vienen en dos formas: cerca y lejos. Una dirección cercana era de 16bits y era una compensación en el segmento actual, uno de CS, DS, ES, SS dependiendo de la instrucción, un lejos era de 32 bits y consistía en un segmento y un desplazamiento. En el 8086, la dirección absoluta era 16 * segmento + desplazamiento, dando un rango direccionable de 1Mb.

Si no está utilizando un sistema de memoria segmentada, y parece que no lo está, todas las direcciones tienen el mismo número de bits por lo que no es necesaria la distinción de cerca/lejos, lo que significa que la palabra clave es probablemente ignorada por el compilador.

+0

Sí, significaba que había 4096 maneras de abordar el mismo byte de memoria. – Skizz

+0

__far existía no solo en la familia x86 con direccionamiento segmentado. M68k, PowerPC y algunos otros también tenían este calificador. Creo que en el incrustado todavía se usa. Para hacer la respuesta a la pregunta original necesitamos más información (como plataforma, compilador, ...) – flolo

+0

Entiendo esto, y sí, mi memoria está segmentada. –

1

Este es un fragmento de código que funciona desde un proyecto en el que estoy trabajando. Es Paradigma C++, por lo que usa alguna versión de Borland. La CPU que utiliza es un clon 8086, por lo que la memoria de 20 bits está segmentada.

void softSerial0SR(unsigned16); 
void (__far *softHandler)(unsigned16); 

Inicializo softHandler a 0 sin reclamo.

Entonces,

softHandler = softSerial0SR; 

en código de configuración.

Para llamarlo, simplemente llame a softHandler como una función normal.

Tenga en cuenta que este código se modifica ligeramente para usted desde el código real que tengo.

0

ambos programas fueron construidos por el mismo compilador/opciones, ¿entonces usan el mismo OBI?

0

Estoy de acuerdo en que el código se ve bien - en este caso, me gustaría obtener un desmontaje del código generado, y averiguar si salió bien. Solo debería haber 10 instrucciones como máximo, y entonces sabrá con certeza si funcionó.