6

我意识到 far 是特定于编译器的,但我的期望是 far 说明符的放置对那些真正理解指针的人来说应该是有意义的。

所以,我有两个应用程序共享处理器的整个内存空间。

应用 A 需要调用应用 B 中存在的函数 foo。

我知道函数 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 的调用不需要取消引用,您的经验是什么?
  • 这看起来还有什么不正确的,或者我可以尝试完成这个吗?

  • 有一个更好的方法吗?

编辑:

这是在使用 Code Warrior 的嵌入式设备(飞思卡尔 S12XEQ 设备)上。这是一个具有 24 位内存空间的 16 位设备,所以是的,它是分段/存储的。

-亚当

4

5 回答 5

10

__far在创建使用分段内存的二进制文件时,至少在 MS 世界中使用了该关键字。您需要了解 8086 内存系统才能理解这一点。8086将内存分成段,每段64K长,所以段中的每个地址需要16位。地址有两种形式:近处和远处。近地址为 16 位,是当前段的偏移量,根据指令为 CS、DS、ES、SS 之一,远地址为 32 位,由段和偏移量组成。在 8086 中,绝对地址是 16 * 段 + 偏移量,可寻址范围为 1Mb。

如果您没有使用分段内存系统,并且看起来您没有使用,那么所有地址都具有相同的位数,因此不需要区分近/远,这意味着编译器可能会忽略关键字。

于 2008-11-20T17:06:39.093 回答
8

__far 在 typedef 中的正确位置吗?

[编辑,回应 ChrisN 的评论——谢谢]

这是一个依赖于编译器的功能,因为它不是 ANSI C 的一部分。根据编译器手册 <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

这看起来还有什么不正确的,或者我可以尝试完成这个吗?

你做得完全正确。

于 2008-11-20T18:27:54.123 回答
1

这是一段代码,适用于我正在从事的项目。它是 Paradigm C++,所以它使用了 Borland 的某个版本。它使用的 CPU 是 8086 克隆,因此分段的 20 位内存。

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

我毫无怨言地将 softHandler 初始化为 0。

然后,

softHandler = softSerial0SR;

在设置代码中。

要调用它,只需像普通函数一样调用 softHandler 即可。

请注意,此代码是根据我拥有的实际代码为您稍微调整的。

于 2008-11-20T18:22:57.067 回答
0

这两个程序都是由相同的编译器/选项构建的,所以它们使用相同的 OBI?

于 2008-11-21T17:57:49.257 回答
0

同意代码看起来不错 - 在这种情况下,我会反汇编生成的代码,并确定它是否正确。最多应该只有 10 条指令——然后你就会确定它是否有效。

于 2008-11-30T16:11:13.480 回答