开发者

Where is function pointer stored?

In an embedded environment, for example, I declared a look开发者_如何转开发-up table in following way:

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

May I know this function pointer is pointing to RAM address or ROM address?


That depends on your compiler and target environment, but most likely it points to ROM—executable code is almost always placed in read-only memory when available. You have to take special steps (like using a custom linker script or allocating dynamic memory and asking the operating system to mark it as writable and executable) to get executable code in non-read-only memory.


The linker should be able to generate a map-file where the location of each variable/constant defined at file-scope is shown. Example:

main.c:

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

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

Generated map-file: (notice how the constant constant is placed in the same memory segment as the read-only code (TEXT), while the variable variable is placed in the DATA section)

# 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


Its address will be entirely dependent on the location of the function pointed to; the linker will tell you that. Most often application code ie either all in RAM or all in ROM, though for some targets, it may be split for performance reasons if RAM execution is faster as it typically is on processors faster than around 100MHz.

If you need to determine this at runtime (if for example it may be either, and is dynamic), you can simply compare the address with the start and end of the relevant memory sections. These addresses may be emitted as symbols by the linker given an appropriate linker script, or they may be defined constants in a target header file or BSP for example.

All that said, I can think of few reasons you should need to know at run-time (unless you are considering self modifying code!).


This is dependent on architecture.

However, if you have some idea of the address ranges for ROM and RAM, you can check the function pointer to the address.

Or, as Mehrdad says, just try writing to the address, it should be easy to figure out from there.


It all depends on which compiler/processor you use. If I put your definition in Keil Uvision for 8051, surely would point to ROM because of the "CONST" definer although I could modify with XRAM or CODE. But for ARM depends on address and not definer. Keil Uvision Example:

// 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
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜