Оптимизация пролога/эпилога функций
Ранние Си-компиляторы использовали для адресации локальных переменных базовый указатель стека – регистр BP (EBP в 32-разрядном режиме), помещая в начало каждой функции специальный код, называемый прологом. Пролог сохранял текущее содержимое регистра BP (EBP) в стеке и копировал в него указатель вершины стека, хранимый в регистре SP (ESP). Затем, уменьшением значения регистра SP (ESP), выделялась память локальным переменным функции (стек, как известно, растет снизу вверх).
По завершению функции код эпилога вновь "опускал" регистр-указатель вершины стека, освобождая память, занятую локальными переменными, и восстанавливал значение базового указателя стека – регистра BP (EBP).
Ну, резервирование/освобождение памяти – это понятно, но вот регистр BP (EBP) зачем? А вот зачем: он хранит указатель кадра стека – региона памяти, отведенного под локальные переменные.
Все три рассматриваемых компилятора адресуют локальные переменные иначе – непосредственно через ESP. Это значительно усложняет реализацию компилятора, т.к. указатель вершины стека меняется в ходе выполнения программы и адресация выходит "плавающей", зато такая техника высвобождает один регистр для регистровых переменных и избавляется от двух операций обращения к памяти (сохранения/восстановления EBP), что заметно повышает производительность.
__встраиваемые функции
__отложенное выталалкивание аргументов из стека