Изучение листинга ассемблирования, генерируемого компилятором C++ - часть 1 - Конструкторы и исключения
ОГЛАВЛЕНИЕ
Конструкторы
Рассматривается ассемблерный код для секции, где вызывается оператор new.
; 23 : SmartString* arr = new SmartString[2];
push 12 ; 0000000cH
call ??2@YAPAXI@Z ; оператор new
test eax, eax
pop ecx
je SHORT $L980
push 2
pop ecx
push OFFSET FLAT:??0SmartString@@QAE@XZ
; SmartString::SmartString
push ecx
lea esi, DWORD PTR [eax+4]
push 4
push esi
mov DWORD PTR [eax], ecx
call ??_H@YGXPAXIHP6EPAX0@Z@Z
jmp SHORT $L981
$L980:
xor esi, esi
$L981:
Функция ??_H@YGXPAXIHP6EPAX0@Z@Z - "итератор конструктора вектора", подобный итератору деструктора вектора.
Его перевод на псевдокод C++ выглядит так
unsigned char* allocated =
new unsigned char[12]; //Выделить 12 байтов, 4 байта для размера
if (allocated != NULL)
{
//Поместить размер в первые четыре байта
//Фактический массив начинается в выделенном + 4
*(int*)allocated = 4;
vector_constructor_iterator(allocated + 4,
4, 2, &SmartString::SmartString);
}
Итератор конструктора вектора работает так же, как итератор деструктора вектора. Он вызывает конструктор для всех элементов в массиве.
Исключения
Во всех примерах была отключена обработка исключений перед компиляцией приложения. Активация обработки исключений заставляет компилятор генерировать много лишнего кода.
Заключение
Были изучены некоторые аспекты внутренних механизмов компилятора C++ с помощью листинга ассемблирования. Изучение листинга ассемблирования дает четкое представление о том, что компилятор делает внутри с кодом C++. Это помогает писать более качественный и эффективный код C++.