Генерация высококачественного кода для программ, написанных на СИ | страница 12
>mov CX,10000
>mov i,CX
>sub AX,AX
>mov DI,offset a
>push DS
>pop ES
>cld
>rep stosw
"Минимизация заголовков вызова функций" может существенно уменьшить время выполнения в структурированной программе. При вызове функции параметры передаются вызываемой подпрограмме в стеке, находящемся в оперативной памяти. Набор инструкций некоторых процессоров содержит инструкции, которые поддерживают потребности Си и других структурированных языков высокого уровня в установке адресации фрейма стека перед выполнением кода функции и восстановлении стекового фрейма перед завершением.
Начиная с процессора Intel 80186, семейство микропроцессоров 80x86 предоставляет инструкции ENTER и LEAVE для обработки вызовов функций. Полезность инструкции ENTER снижается, так как ее выполнение занимает гораздо больше временных циклов процессора, чем выполнение последовательности команд, осуществляющих засылку в стек базового указателя и вычитание необходимого количества байт для фрейма из указателя стека.
Альтернативой использованию стека для передачи параметров функции является задание корректно определенного протокола для передачи стольких параметров, сколько возможно, в регистрах. Если доступно достаточное количество регистров чтобы передать все параметры функции, и вызываемая функция не использует локальные переменные, то отпадает необходимость генерации кода для пролога и эпилога функции (они обычно нужны для установки адресации фрейма стека). Компилятор WATCOM C 6.0 использует этот подход (см. рис. 5). Существенное приращение скорости получается потому, что не только удаляются инструкции, но и потому, что параметры уже регистровые и могут обрабатываться более эффективно.
--------------------------------------------------------------¬
¦РИСУНОК 5: Строение заголовка вызова функции ¦
+-------------------------------------------------------------+
¦Исходный текст на Си MICROSOFT WATCOM ¦
¦(x)-врем. циклы C 5.0 C 6.0 ¦
+-------------------------------------------------------------+
¦/*Тест вызова funcall funcall ¦
¦ функции */ push bp push DX ¦
¦int funcall() mov BP,SP xor DX,DX ¦
¦{ sub SP,2 L4 mov AX,DX <-¬ ¦
¦ int i; push SI call dummy ¦ ¦