0

我正在阅读比特币 trezor MCU 的代码,发现:

(*(void (**)())(FLASH_APP_START + 4))();

通过分解一些东西,我试图分析这条线的含义:

(   *(void (**)())(FLASH_APP_START + 4)    )      ();

我可以看到这是一个没有参数的函数调用,因为()最后是

*(void (**)())(FLASH_APP_START + 4)

指着。

我知道这FLASH_APP_START + 4会解决一些问题,所以我只需要弄清楚这是什么:

*(void (**)())

它正在解决任何void (**)()指向的问题。但什么是void (**)()?也许它看起来像是一个函数的转换。但我不确定。你能给我举个例子来说明这个呼召是什么吗?你为什么需要那个?

4

2 回答 2

2

其含义(void (**)())是:将指针转换为指向返回void的函数的指针。因此,当您取消引用它 ( *(void(**)())) 时,它的类型是指向返回 void 的函数的指针,您可以调用它。(FLASH_APP_START+4)是指向函数指针表的指针。如果类型FLASH_APP_STARTchar*,则将调用列表中的第二个函数,假设为 32 位指针。如果类型FLASH_APP_STARTvoid*,则将调用表中的第 5 个函数。

fun2例如,此代码将在具有 32 位指针的机器上调用。

#include <stdio.h>

void fun1() { printf("fun1\n"); }
void fun2() { printf("fun2\n"); }

int main(void) {
  static void (*table[])() = { fun1, fun2 };

  int const FLASH_APP_START = (int)&table;
  (*(void (**)())(FLASH_APP_START + 4))();
}

如果您需要解码 C 类型的帮助,cdecl.org是您的朋友。

于 2016-02-10T03:16:04.783 回答
0

首先,void (**)()是一个指向函数指针的指针,没有参数和 void 返回类型。

其次,意味着在第一步中将(void (**)())(FLASH_APP_START + 4)地址值转换为指针。应该是一个固定值。它可能是 NAND 闪存的起始地址,在嵌入式系统中总是用作向量表。FLASH_APP_START + 4FLASH_APP_START

第三,*(void (**)())(FLASH_APP_START + 4)取消引用第二步中得到的指针。我们现在得到了一个函数指针。

最后,(*(void (**)())(FLASH_APP_START + 4))()调用我们在第三步得到的函数。

总结:地址处存储了一个函数入口地址FLASH_APP_START + 4。我们得到函数入口地址。将其转换为函数指针,然后调用它。

于 2016-02-10T03:26:08.383 回答