Использование указателей на дальние функции - PullRequest
6 голосов
/ 20 ноября 2008

Я понимаю, что far зависит от компилятора, но я ожидаю, что размещение спецификатора far должно иметь смысл для тех, кто действительно понимает указатели.

Итак, у меня есть два приложения, которые разделяют все пространство памяти процессора.

Приложение A должно вызвать функцию foo, которая существует в приложении B.

Я знаю место в памяти функции foo.

Так что это должно работать, в приложении A:

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

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

   foo = (MYFP) 0xFFFFFA;

   returnvalue = foo(39);
}
  • Находится ли __far в нужном месте в typedef?
  • Нужно ли добавлять __far к исполнению (MYFP)?
  • Некоторая информация предполагает, что вызов foo не нуждается в разыменовании, каков ваш опыт?
  • Что еще по этому поводу выглядит неправильно, или я могу попытаться это сделать?

  • Есть ли лучший способ сделать это?

Edit:

Это на встроенном устройстве (устройстве Freescale S12XEQ), использующем Code Warrior. Это 16-битное устройство с 24-битным пространством памяти, так что да, оно сегментировано / объединено.

-Adam

Ответы [ 5 ]

10 голосов
/ 20 ноября 2008

Ключевое слово __far, по крайней мере, в мире MS, использовалось при создании двоичных файлов, которые использовали сегментированную память. Вы должны понимать систему памяти 8086, чтобы понять это. 8086 разделил память на сегменты, каждый сегмент имел длину 64 КБ, поэтому каждому адресу в сегменте требовалось 16 бит. Адреса приходили в двух формах: ближний и дальний. Ближайший адрес был 16 бит и был смещением в текущий сегмент, один из CS, DS, ES, SS в зависимости от инструкции, дальний был 32 бита и состоял из сегмента и смещения. В 8086 абсолютный адрес был 16 * сегмент + смещение, давая адресуемый диапазон 1 Мб.

Если вы не используете систему с сегментированной памятью, и похоже, что это не так, тогда все адреса имеют одинаковое количество битов, поэтому различие между ближним и дальним расстоянием не требуется, что означает, что ключевое слово, вероятно, игнорируется компилятором. .

8 голосов
/ 20 ноября 2008

Находится ли __far в правильном месте в typedef?

[Изменить, в ответ на комментарий ChrisN - спасибо]

Это функция, зависящая от компилятора, поскольку она не является частью ANSI C. Согласно руководству по компилятору <<a href="http://www.freescale.com/files/soft_dev_tools/doc/ref_manual/CW_Compiler_HC12_RM.pdf" rel="noreferrer">http://www.freescale.com/files/soft_dev_tools/doc/ref_manual/CW_Compiler_HC12_RM.pdf>,, глава 8, она размещена правильно. В других компиляторах вам может понадобиться изменить порядок. Это должно быть довольно легко понять, так как точно один из двух вариантов будет компилироваться с любым данным компилятором.

Нужно ли добавить __far к исполнению (MYFP)?

Нет, это часть типа.

Некоторая информация предполагает, что вызов foo не нуждается в разыменовании, каков ваш опыт?

Функциональные указатели могут быть дополнительно разыменованы в C. Следующие строки являются действительными и выполняют одно и то же:

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

Что еще по этому поводу выглядит неправильно, или я могу попытаться это сделать?

Вы сделали это совершенно правильно.

1 голос
/ 20 ноября 2008

Это фрагмент кода, который работает из проекта, над которым я работаю. Это Paradigm C ++, поэтому он использует некоторую версию Borland. Процессор, который он использует, является клоном 8086, поэтому сегментированная 20-битная память.

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

Я инициализирую softHandler на 0 без жалоб.

Тогда

softHandler = softSerial0SR;

в коде настройки.

Чтобы вызвать его, просто вызовите softHandler как обычную функцию.

Обратите внимание, что этот код немного подправлен для вас по сравнению с тем кодом, который у меня есть.

0 голосов
/ 30 ноября 2008

Согласитесь, что код выглядит нормально - в этом случае я получу дизассемблирование сгенерированного кода и выясню, правильно ли он получился. Должно быть не более 10 инструкций, и тогда вы точно будете знать, сработало ли это.

0 голосов
/ 21 ноября 2008

обе программы были созданы одним и тем же компилятором / опциями, поэтому они используют один и тот же OBI?

...