【问题标题】:Is it possible to map an address to the result of a function?是否可以将地址映射到函数的结果?
【发布时间】:2010-06-20 15:11:01
【问题描述】:

我正在用 C/C++ 为 Mac OS 编写一个 NES 模拟器(我已经编写了一个,所以我知道基础知识)。由于许多硬件寄存器映射到内存位置,我想知道是否有一些系统调用可以用来将地址映射到函数的结果:当它被访问时,函数会被调用。 (我很确定我不能,但是,嘿,值得一问。)

这是我想做的:

int getStatusRegisterValue()
{
    return 0xCAFEBABE;
}

// obviously, more parameters than just this would be involved I suppose
int* statusRegister = syscall_to_map_function_to_address(getStatusRegisterValue);

// from here on, doing (*statusRegister) should call getStatusRegisterValue and
// return its value
*statusRegister == 0xCAFEBABE;

这个项目将是我在 LLVM 上的尝试,我的目标是将 ROM 重新编译为 LLVM 字节码。这就是为什么如果简单的内存访问可以触发该功能会很方便(就像在真正的NES硬件上一样)。解决我的问题的另外两个明显的可能性是缓存寄存器值并将它们存储在实际内存中,或者从重新编译的代码中调用一个函数来将内存位置映射到它们真正的位置。

谢谢!

【问题讨论】:

  • 没有 C/C++ 这样的东西。
  • @wowus:“C/C++”听起来是总结“C++ 与 C 交互”的好方法。我还应该补充一点,该语言会涉及到 Objective-C 和一些汇编语言。
  • 你能展示一些示例代码吗?还是用例?我无法完全想象这一点。
  • @wowus:我已经编辑了我的问题。

标签: c++ c macos pointers map


【解决方案1】:

也许您可以尝试安装 SEGV 处理程序并在那里检查故障地址。由于我不使用 Mac OS,因此无法为您提供更多帮助。

【讨论】:

  • 可能是个好主意。但是,它需要与其他好的地址连续,所以可能不会这样做。
  • 你的意思是NES寄存器和真实内存在同一页?或者你会使用普通的旧变量来模拟一些寄存器?如果您不介意同一页面上其他所有内容的性能不佳,这应该可以。
  • 您似乎会对 $2000 - $5FFF 范围内的任何访问产生错误。当然,这对于扩展 ROM 访问来说会很慢,但一开始并不快。
  • 不,你是对的。 IO 寄存器页不断地镜像自己,所以除了寄存器之外,它们里面没有好的地址。我不会这样做,因为它比我想要的要贵得多,但你仍然会得到很好的答案。
【解决方案2】:

这听起来就像普通的函数指针:

typedef int(*function_type)(void);

function_type = &getStatusRegisterValue; // store
int i = function_type(); // call

不同的语法,相同的想法?

【讨论】:

  • 不完全是:NES 有几个内存位置可以访问硬件寄存器而不是实际的 RAM 地址,我正在尝试模仿这种行为。我不会自己调用函数(因此这不是语法问题):这个项目是使用 LLVM 的借口,所以我会尝试将 ROM 重新编译为 LLVM 字节码。如果我可以让我的程序的地址空间表现得像 NES 的地址空间,我认为我担心的事情会更少。当然,还有明显的替代方案,例如使用函数将位置映射到他们真正需要做的任何事情。
【解决方案3】:

这不能用 C(或 C++,但为了简单起见,我们还是坚持使用 C)。

您可以通过运算符重载和具有显式寻址的函子“模拟”(ha)这种效果,但这不是真实的。要正常执行此操作,必须对目标函数做出太多假设。

1) 你假设它总是返回相同的值。

其实就是这样。尽管如此,这是一个很大的假设!

【讨论】:

  • 实际上,我不想假设它总是返回相同的值。那将是愚蠢的:我不需要在每次访问内存位置时计算函数的结果,如果我可以将它放在那里并让它代替的话。示例中的相等性只是它所做的一个示例。除此之外,显然,为了简洁起见,它假设了各种各样的东西,但我可以想象一个更灵活的设计。
【解决方案4】:

在 C++ 中,您可以为用户定义的类重载 *-> 运算符。这会让你实现你想要的吗?

【讨论】:

  • 这是个好主意,但执行引擎需要的功能比 C++ 低得多。我将尝试将 ROM 重新编译为 LLVM 字节码,这就是为什么如果唯一的内存访问可以执行该函数会更简单。
【解决方案5】:

除非您使用内存断点(如果在系统上可用的话,这实际上只是为了调试)。

这也与编程语言无关,您的问题通常是针对现代计算机平台的。

【讨论】:

  • 我指定编程语言只是因为如果有解决方案,发布它的人就会知道使用哪种语言。
猜你喜欢
  • 1970-01-01
  • 2018-01-09
  • 2023-03-25
  • 2013-06-13
  • 1970-01-01
  • 2011-11-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多