Где хранится указатель на функцию? - PullRequest
2 голосов
/ 07 июня 2011

Например, во встроенной среде я объявил справочную таблицу следующим образом:

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

Могу ли я знать, что указатель этой функции указывает на адрес ОЗУ или ПЗУ?

Ответы [ 5 ]

1 голос
/ 11 июня 2011

Его адрес будет полностью зависеть от расположения указанной функции;компоновщик скажет вам это.Чаще всего код приложения, т. Е. Либо весь в ОЗУ, либо весь в ПЗУ, хотя для некоторых целей он может быть разбит по соображениям производительности, если выполнение ОЗУ происходит быстрее, поскольку обычно оно работает на процессорах с частотой, превышающей 100 МГц.

Если выНеобходимо определить это во время выполнения (если, например, оно может быть и динамическим), вы можете просто сравнить адрес с началом и концом соответствующих разделов памяти.Эти адреса могут выдаваться компоновщиком в виде символов с помощью соответствующего сценария компоновщика, или они могут быть определены как константы в целевом заголовочном файле или BSP, например.

При всем этом я могу придумать несколько причин, по которым вам следуетнеобходимо знать во время выполнения (если вы не рассматриваете самоизменяющийся код!).

1 голос
/ 08 июня 2011

Компоновщик должен иметь возможность генерировать файл карты, где показано местоположение каждой переменной / константы, определенной в области видимости файла.Пример:

main.c:

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

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

Сгенерированный файл карты: (обратите внимание, как константа 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
1 голос
/ 07 июня 2011

Это зависит от вашего компилятора и целевой среды, но, скорее всего, оно указывает на ПЗУ - исполняемый код почти всегда помещается в постоянную память, когда она доступна.Чтобы получить исполняемый код в недоступной только для чтения памяти, необходимо выполнить специальные действия (например, использовать собственный сценарий компоновщика или выделить динамическую память и попросить операционную систему пометить его как доступный для записи и исполняемый).

0 голосов
/ 28 июня 2011

Все зависит от того, какой компилятор / процессор вы используете.Если бы я поместил ваше определение в 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
0 голосов
/ 07 июня 2011

Это зависит от архитектуры.

Однако, если у вас есть представление о диапазонах адресов для ПЗУ и ОЗУ, вы можете проверить указатель функции на адрес.

Или, как говорит Мерадад, просто попробуйте записать адрес., это должно быть легко выяснить оттуда.

...