Берем до невозможности простую функцию типа:
- Код: Выделить всё
Function F1(A:Integer):Integer; Register;
begin
A:=A+4;
Result:=A;
end;
проводим тестирования в Delphi2009 и FPC 2.4.2.
асм код для FPC 2.4.2. выводим при помощи ключей(параметров) компилятора:
- Код: Выделить всё
-Amasm -al –s
Видим такой результат:
- Код: Выделить всё
; Temps allocated between ebp-8 and ebp-8
@@f3:
@@l9:
; [65] begin
push ebp
mov ebp,esp
sub esp,8
; Var A located at ebp-4
; Var $result located at ebp-8
mov dword ptr [ebp-4],eax
@@l10:
; [66] A:=A+4;
mov eax,dword ptr [ebp-4]
add eax,4
mov dword ptr [ebp-4],eax
@@l11:
; [67] Result:=A;
mov dword ptr [ebp-8],eax
@@l12:
; [68] end;
mov eax,dword ptr [ebp-8]
leave
ret
В Delphi 2009 видим это:
- Код: Выделить всё
Unit1.pas.77: A:=A+4;
00464238 83C004 add eax,$04
Unit1.pas.79: end;
0046423B C3 ret
Про оптимизацию, я молчу, к FPC так как он бесплатный претензий нету, но вот, какого он сделал вот это:
- Код: Выделить всё
; Var A located at ebp-4
; Var $result located at ebp-8
mov dword ptr [ebp-4],eax
Он сознательно сделал копию передаваемых параметров на стеке, Я ему по-человечески сказал, что нужно расположить данные в Регистрах (Register;) Так зачем он сделал копию. И потом работает именно с памятью а не с регистром, как Delphi?? Когда данных тьма, ясно что они все не влезут в 3 регистра и следующие размещаем в стеке, но тут…
Получается, что FPC, скажем если используем рекурсию (будет нам каждый вызов, делать подобные вещи)… Что за фишка, зачем,?....
Потом, вспомнил как советовал, Сергей Горелкин: включить оптимизацию: O2
Получим следующий код:
- Код: Выделить всё
_CODE SEGMENT PARA PUBLIC USE32 'CODE'
ALIGN 16
UNIT1_F1$LONGINT$$LONGINT:
; Temps allocated between esp+0 and esp+0
; Var A located in register eax
; Var $result located in register eax
; [65] begin
@@f3:
@@l9:
; [66] A:=A+4;
add eax,4
@@l10:
; [68] end;
ret
@@t8:
_CODE ENDS
Эээ, тогда смысл в O1?...
Вопрос:
Если же я пишу функцию полностью на асм (без begin..end;)
То оба ключа –O1 and -O2, выдают код без локальных копий на стеке, тогда получается, что для не asm функции, еще не доделали или в этом заложен смысл…?