Страница 1 из 1

Соглашение Register в FPC[Решено]

СообщениеДобавлено: 18.03.2011 16:35:18
Maxizar
Опять 25… проводим эксперимент:
Берем до невозможности простую функцию типа:
Код: Выделить всё
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 функции, еще не доделали или в этом заложен смысл…?

Re: Соглашение Register в FPC

СообщениеДобавлено: 18.03.2011 17:30:48
Сквозняк
Что за фишка, зачем,?....
FPC в отличии от дельфи кроссплатформенный и оптимизирован для работы на многих платформах а не на одной конкретной.
Получается, что FPC, скажем если используем рекурсию (будет нам каждый вызов, делать подобные вещи)…
У кого как. Если религиозные убеждения позволяют, то рекурсию можно делать внутри функции :mrgreen: Нужно лишь в начале исходника прописать {$GOTO ON} Кстати,
Remark:When compiling assembler code using the inline assembler readers, any labels used in the assembler code must be declared, and the {$GOTO ON} directive should be used.

Re: Соглашение Register в FPC

СообщениеДобавлено: 18.03.2011 21:36:37
Sergei I. Gorelkin
Соглашение о вызове 'register' на платформе i386 определяет только то, что вызывающая сторона помещает первые три параметра в регистры, а вызываемая берет из этих регистров. Всё. Дальше вызываемая процедура вправе делать все что угодно.
Есть еще такая широко известная в узких кругах программа, как gdb. Так вот эта замечательная программа мало что знает об особенностях fpc, и показывает значения переменных только тогда, когда они находятся в памяти. Ежики плакали, кололись, но ничего лучшего на сегодняшний день не написано.
Ну и если вспомнить описание опций оптимизации: -O1 означает debugger-friendly, "не обижай отладчик" если по-русски. -O2 означает "хрен с ним с отладчиком, давай по полной".

Re: Соглашение Register в FPC

СообщениеДобавлено: 18.03.2011 22:29:02
Maxizar
Sergei I. Gorelkin писал(а):Ну и если вспомнить описание опций оптимизации: -O1 означает debugger-friendly, "не обижай отладчик" если по-русски. -O2 означает "хрен с ним с отладчиком, давай по полной".

Да спасибо. Теперь всегда буду использовать для релиза -O2., для отладки -О1.

Да на счет того что О2, приводит gdb в замешательство, я уже уловил... и если учесть что:
Sergei I. Gorelkin писал(а):Так вот эта замечательная программа мало что знает об особенностях fpc, и показывает значения переменных только тогда, когда они находятся в памяти

Возможно, моя проблема(вопрос) в этом и заключается, что fpc делает эти копии, чтобы можно трассировать по шагам, и видеть значения переменных используя gdb...

Вывод:
Опция none and -O1 специально, генерируют копии, переданных параметров в стеке, для того, чтобы gdb смог их увидеть.
Опция -О2, таких копий не делает, вследствии чего, генерируемый код:
    - Почти похож на код Delphi
    - Но теряется возможность видеть при отладке значение переменных...
    - При этом нужно понимать, что это реально увеличивает работоспособность (производительность) процедуры...
Опция -О3, делает тоже самое что и -О2, но плюс различные фокусы и трюки (наверное)

Теперь, я начал понимать смысл этих оптимизаций, потому что видел различие в asm коде. Раньше это было для меня туманным :D

PS. Еще раз, спасибо, вопрос считаю для себя решенным.

Re: Соглашение Register в FPC[Решено]

СообщениеДобавлено: 16.04.2011 13:17:15
Maxizar
Sergei I. Gorelkin писал(а):Соглашение о вызове 'register' на платформе i386 определяет только то, что вызывающая сторона помещает первые три параметра в регистры, а вызываемая берет из этих регистров. Всё. Дальше вызываемая процедура вправе делать все что угодно.


Тогд можете пояснить мне вот такое поведение: FPC закидывает второй параметр не в регистр EDX, а в стек...
Имеем функцию\процедуру:
Код: Выделить всё
procedure FFT(var D: TCmxArray; const TableExp: TCmxArray);register; assembler;

Где TCmxArray:
Код: Выделить всё
type
  TCmxArray    = array of TComplex;

Сначала думал, что-то сломалось или неправильно делаю внутри функции, но он зараза (FPC) переменную TableExp передал не в регистр EDX а в стек... почему? Спецификатор Const так виляет или что?..
Выход асм кода по ключам: -Amasm -al -s:
Код: Выделить всё
PUBLIC   ITERATIVE_FFT_FFT$TCMXARRAY$TCMXARRAY
ITERATIVE_FFT_FFT$TCMXARRAY$TCMXARRAY:
; Temps allocated between ebp-72 and ebp-72
@@f4:
@@l60:
; [390] end;
      push   ebp
      mov   ebp,esp
      sub   esp,72
; Var D located in register eax
; Var TableExp located at ebp+8


Почему размещено в ebp+8 ?

При этом вызов из другой функции, тобишь смотрим что и куда поместит сам FPC при вызове функции видим такое:
Код: Выделить всё
@@l54:
; [136] FFT(Sampl,TableExp);
      push   dword ptr [U_UNIT1_TABLEEXP]
      mov   eax,offset U_UNIT1_SAMPL
      call   ITERATIVE_FFT_FFT$TCMXARRAY$TCMXARRAY


Видно, что первый параметр закину в EAX а второй push-ем закинул в стек... ЭЭЭ вопрос Почему?... Это принципиально так сделано? мне теперь тоже через стек работать :( я ведь хотел именно через регистры...

Re: Соглашение Register в FPC[Решено 50%]

СообщениеДобавлено: 16.04.2011 14:31:54
Sergei I. Gorelkin
Maxizar писал(а):Почему размещено в ebp+8 ?

в результате выполения "push ebp; mov ebp, esp" по адресу [ebp] получается предыдущее значение ebp, по адресу [ebp+4] находится адрес возврата, по адресу [ebp+8] - последний помещенный в стек аргумент... [ebp+12] будет предпоследний аргумент (если он есть) и т.д.

Maxizar писал(а):Видно, что первый параметр закину в EAX а второй push-ем закинул в стек...

Это он посчитал что динамический массив не влезет в регистр. На самом деле влезет... вопрос больше в целесообразности попыток *настолько* соответствовать Дельфи.

Re: Соглашение Register в FPC[Решено 50%]

СообщениеДобавлено: 16.04.2011 14:50:04
Maxizar
Да на счет смещения я уже разобрался... кстати Вы же вроде мне и помогли в этом, правда в другой ветке :)
Что касается, EDX.. просто я ждал что там будет указатель на дин Массив. но получается, что нет... Просто я думал так будет железно, все три первых параметра в регистры(если они влезут) Тут вроде указатель, но FPC думал что наверное весь массив нуна туда запихать... а это конечно не реально. Но ведь Я же подсказал мол Const, но FPC это не помогло... :evil:


Спасибо.