首页 文章

使用far函数指针

提问于
浏览
6

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

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

App 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的嵌入式设备(Freescale S12XEQ设备) . 它是一个具有24位存储空间的16位器件,所以是的,它是分段/存储的 .

-亚当

5 回答

  • 10

    __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
    

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

    你完全正确地完成了它 .

  • 0

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

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

  • 0

    这是一个代码片段,可以从我正在处理的项目中运行 . 这是Paradigm C,所以它使用了Borland的某些版本 . 它使用的CPU是8086克隆,因此分段的20位内存 .

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

    我将softHandler初始化为0而没有抱怨 .

    然后,

    softHandler = softSerial0SR;
    

    在设置代码中 .

    要调用它,只需像常规函数一样调用softHandler .

    请注意,此代码会根据我的实际代码稍微调整一下 .

  • 1

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

  • 8

    同意代码看起来很好 - 在这种情况下,我会得到一个反汇编生成的代码,并弄清楚它是否正确 . 最多应该只有10条指令 - 然后你会确定它是否有效 .

相关问题