разборка класса с ++ - PullRequest
1 голос
/ 22 июня 2011

У меня есть следующий код:

class Base {
public:
int x,y;
Base() { x=10; y=20; }
virtual void myfunction() { }
};

int main() {
Base *b = new Base();
return 0;
}

Разборка дает мне что-то вроде:

push 0Ch                ; size of Base
call j_<some giberrish> ; IDA gives the comment "operator new(uint)"
add esp, 4              ; function epilogue
mov [ebp+var_E0], eax

Через несколько строк у вас вызывается конструктор.

mov ecx, [ebp+var_E0]
call j_Base__Base
mov [ebp+var_F4], eax
  • Сначала я думал, что var_E0 будет содержать указатель на экземпляр, но теперь я почти уверен, что var_F4 делает то, что содержит возвращаемое значение конструктора.
  • В таком случае, что вообще содержит var_E0?Почему он перемещен в ecx до вызова конструктора?

Ответы [ 3 ]

2 голосов
/ 22 июня 2011

Visual C ++ использует внутреннее соглашение, в котором конструкторы возвращают указатель на экземпляр объекта (по стандарту C ++ конструкторы не имеют возвращаемого значения). Так что в вашем случае var_E0 и var_F4 содержат указатель экземпляра.

Проверьте мою статью для получения более подробной информации о том, как Visual C ++ реализует C ++.

2 голосов
/ 22 июня 2011

Это некоторая внутренняя переменная для временного сгенерированного компилятором.

Когда вы пишете new Base, компилятор генерирует вызов глобального operator new функция, затем вызывает конструктор возвращаемого адрес. Видимо, ваш компилятор сохраняет адрес, возвращенный из operator new в памяти, а не в реестре.

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

Это почти наверняка отладочная сборка, на которую вы смотрите, и отладочные сборки очень консервативны в том, что они делают.Создание объекта - это двухэтапный процесс: выделение памяти, а затем создание объекта.Ваш компилятор помещает указатель выделенной памяти во временную переменную.Если вы создаете оптимизированную версию, эта временная переменная не будет сохранена, поскольку это приводит к ненужным накладным расходам (запись / чтение ОЗУ).

...