可以使用 C 将函数的存储位置存储到 RAM 中吗?

pup*_*m64 3 c embedded arm game-boy-advance

我一直在玩 C 语言的 Game Boy Advance 编码。为了使中断正常工作,必须将中断处理程序例程的地址手动复制到 RAM 位置 0x03007FFC。我知道如何在 ARM Assembly 中执行此操作,但不知道如何在 C 中执行此操作。我正在尝试这样的操作:

#define REG_INTERRUPT *(vu32*)0x03007FFC
void irqhandler()
{
    while(1){}
}

int main()
{
    REG_INTERRUPT = &irqhandler();

    while(1){}
    return 0;

}
Run Code Online (Sandbox Code Playgroud)

但这不起作用。根据我对 C 函数的理解,C 似乎认为我正在尝试获取返回值的地址irqhandler(因为它是空的,所以没有返回值),这就是错误的来源。我如何告诉 C 我想要函数本身的内存位置?

Lun*_*din 6

  • irqhandler()是错误的,您正在调用该函数而不是获取其地址。您应该写irqhandler或 100% 等效的&irqhandler.
  • 不要使用奇怪的自制类型,比如vu32,没有人知道这意味着什么。使用 stdint.h 中的标准化类型。
  • 您不能将函数指针分配给整数,它们不是兼容的类型。您需要显式转换为整数。

更正的代码:

#include <stdint.h>
#define REG_INTERRUPT (*(volatile uint32_t*)0x03007FFCu)
...
REG_INTERRUPT = (uint32_t)irqhandler;
Run Code Online (Sandbox Code Playgroud)

当然,这是假设底层硬件支持这一点,并且在0x3007FFC需要 32 位整数访问的地址处存在有效的内容。

有关详细信息,请参阅如何从固件访问硬件寄存器?

  • @puppydrum64 然后如前所述,使用“-ffreestand”进行编译,否则它会认为您正在为 PC 编码。 (2认同)