函数指针存储在哪里?

时间:2011-06-07 03:44:20

标签: c embedded function-pointers

例如,在嵌入式环境中,我以下列方式声明了一个查找表:

const Operation Vehicle_OpNotification[] =
{
  { OP_SET            , &Vehicle_Notification_Set},
  { OP_GET            , &Vehicle_Notification_Get}
};

我是否知道此函数指针指向RAM地址或ROM地址?

5 个答案:

答案 0 :(得分:1)

这取决于您的编译器和目标环境,但很可能它指向ROM可执行代码几乎总是在可用时放在只读内存中。您必须采取特殊步骤(例如使用自定义链接描述文件或分配动态内存并要求操作系统将其标记为可写和可执行)以在非只读内存中获取可执行代码。

答案 1 :(得分:1)

链接器应该能够生成一个map文件,其中显示了在文件范围定义的每个变量/常量的位置。例如:

main.c中:

static const int constant = 42;
static int volatile variable = 43;

int main (int argc, const char * argv[]) {
    variable = constant;
    return 0;
}

生成的map-file :(注意常量constant如何放在与只读代码(TEXT)相同的内存段中,而变量variable放在DATA部分)

# Sections:
# Address   Size        Segment Section
0x00001F6C  0x0000008F  __TEXT  __text
0x00001FFC  0x00000004  __TEXT  __literal4
0x00002000  0x00000018  __DATA  __data
0x00002018  0x0000001C  __DATA  __dyld
0x00003000  0x00000008  __IMPORT    __pointers
0x00003040  0x00000005  __IMPORT    __jump_table
# Symbols:
# Address   Size        File  Name
0x00001F6C  0x00000040  [  1] start
0x00001FAC  0x00000014  [  1] dyld_stub_binding_helper
0x00001FC0  0x0000000E  [  1] __dyld_func_lookup
0x00001FCE  0x0000002D  [  2] _main
0x00001FFC  0x00000004  [  2] _constant
0x00002000  0x00000004  [  1] ___progname
0x00002004  0x00000004  [  1] _environ
0x00002008  0x00000004  [  1] _NXArgv
0x0000200C  0x00000008  [  1] _NXArgc
0x00002014  0x00000004  [  2] _variable
0x00002018  0x0000001C  [  1] __dyld@0
0x00003000  0x00000004  [  2] _variable$non_lazy_ptr
0x00003004  0x00000004  [  2] _constant$non_lazy_ptr
0x00003040  0x00000005  [  0] _exit$stub

答案 2 :(得分:1)

它的地址完全取决于指向的函数的位置;链接器会告诉你。大多数情况下应用程序代码,即全部在RAM中或全部在ROM中,但对于某些目标,如果RAM执行速度更快,则可能会因为性能原因而拆分,因为处理器通常比100MHz左右更快。

如果需要在运行时确定(例如,它可能是动态的),则可以简单地将地址与相关内存部分的开头和结尾进行比较。在给定适当的链接描述文件的情况下,这些地址可以由链接器作为符号发出,或者它们可以在目标头文件或BSP中定义为常量。例如。

所有这一切,我可以想到在运行时你应该知道的几个原因(除非你考虑自我修改代码!)。

答案 3 :(得分:0)

这取决于架构。

但是,如果您对ROM和RAM的地址范围有所了解,可以检查指向该地址的函数指针。

或者,正如Mehrdad所说,只要尝试写入地址,就应该很容易从中找出答案。

答案 4 :(得分:0)

这完全取决于您使用的编译器/处理器。如果我把你的定义放在Keil Uvision中用于8051,肯定会指向ROM因为“CONST”定义器虽然我可以用XRAM或CODE修改。但是ARM依赖于地址而不是定义。 Keil Uvision示例:

// For 8051 Keil 
const char code romdata[2] = {0,1}; //<< this point to ROM/FLASH
const char xram ramdata[2] = {0,1}; // this point to external RAM 
const char romdata[2] = {0,1}; // this point to ROM/FLASH