Адрес функции не фактический адрес кода - PullRequest
21 голосов
/ 21 марта 2010

Отлаживая некоторый код в Visual Studio 2008 (C ++), я заметил, что адрес в моей переменной указателя функции не является фактическим адресом самой функции. Это внешняя функция "C".

int main() {
   void (*printaddr)(const char *) = &print; // debug shows printaddr == 0x013C1429

}

Address: 0x013C4F10
void print() {
  ...
}

Разборка адреса взятия функции:

   void (*printaddr)(const char *) = &print;
013C7465 C7 45 BC 29 14 3C 01 mov         dword ptr [printaddr],offset print (13C1429h) 

РЕДАКТИРОВАТЬ: Я просмотрел код по адресу 013C4F10, и компилятор, очевидно, вставляет команду "jmp" по этому адресу.

013C4F10 E9 C7 3F 00 00   jmp         print (013C1429h) 

На самом деле в .exe есть целая таблица переходов для каждого метода.

Может кто-нибудь объяснить, почему он это делает? Это отладочная «фича»?

Ответы [ 3 ]

19 голосов
/ 21 марта 2010

Это вызвано «Инкрементным связыванием». Если вы отключите это в настройках компилятора / компоновщика, скачки исчезнут.

http://msdn.microsoft.com/en-us/library/4khtbfyf(VS.80).aspx

6 голосов
/ 21 марта 2010

Я собираюсь рискнуть предположить здесь, но это возможно, чтобы включить Редактировать и продолжить .

Скажем, вам нужно перекомпилировать эту функцию, вам нужно только изменитьтаблица косвенности, не все звонящие.Это значительно сократит объем работы, выполняемой при редактировании и продолжении.

2 голосов
/ 21 марта 2010

Компилятор вставляет команду "jmp" по этому адресу в реальный метод.

013C4F10 E9 C7 3F 00 00   jmp         print (013C1429h)

На самом деле есть целая таблица переходов для каждого метода в .exe.

Это функция отладки. Когда я переключаюсь в режим разблокировки, таблица переходов исчезает, и адрес действительно является фактическим адресом функции.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...