Mодель использования стека параметров та же что и предыдущая.
Стековый кадр заданного размера является одним из источников
параметров для вычислений и в процессе этих вычислений остается неизменным.
В конце вычислений он модифицируется путем записи в его начальные ячейки
полученных выходных данных и удаления уже ненужных параметров
путем уменьшения глубины стека переустановкой указателя стека.
Но реализация этой модели изменена - оказалось возможным использовать
лишь один указатель для стека, что с одной стороны упростило реализацию
(около 200 строк текста), а с другой стороны повысило эффективность
генерируемого кода.
Представление об эффективности кода можно получить из небольшого количества примеров
в сравнении с кодом с использованием локальных переменных в SPF. Алгоритмы в примерах
абсолютно одинаковы для SPF и предложенного подхода.
Код:
\ конкатенация строк
: S+ { a1 u1 a2 u2 \ a u }
u1 u2 + DUP TO u ALLOCATE THROW TO a a1 a u1 MOVE a2 a u1 + u2 MOVE a u ;
SEE S+
: TST2 S" 123" S" ABС" S+ ;
METER0 TST2
: s+ \ a1 u1 a2 u2 -- a u
\[424+dh162V362+4V:15:2]2 ;
SEE s+
: tst2 S" 123" S" ABС" s+ ;
METER0 tst2
\ функции макс-мин
: MAXMIN { a b c }
a b MAX c MIN DROP ;
SEE MAXMIN
: TST 8 4 9 MAXMIN ;
METER0 TST
: maxmin \[312M3m"1 ;
SEE maxmin
: tst 8 4 9 maxmin ;
METER0 tst
\ сумма попарных произведений 3х параметров
: DCRT3 { a b c }
b c + a * b c * + ;
SEE DCRT3
: TST1 2 3 4 DCRT3 ;
METER0 TST1
: dcrt3 \[323+1*23*+"1 ;
SEE dcrt3
: tst1 2 3 4 dcrt3 ;
METER0 tst1
лог
Код:
CODE S+
5FCC5F 8945FC MOV FC [EBP] , EAX
5FCC62 B810000000 MOV EAX , # 10
5FCC67 8D6DFC LEA EBP , FC [EBP]
5FCC6A E87564F5FF CALL 5530E4 ( DRMOVE )
5FCC6F 8945FC MOV FC [EBP] , EAX
5FCC72 B802000000 MOV EAX , # 2
5FCC77 8D6DFC LEA EBP , FC [EBP]
5FCC7A E8A165F5FF CALL 553220 ( (RALLOT) )
5FCC7F 6818000000 PUSH , # 18
5FCC84 6868325500 PUSH , # 553268
5FCC89 8945FC MOV FC [EBP] , EAX
5FCC8C 8B442418 MOV EAX , 18 [ESP]
5FCC90 03442410 ADD EAX , 10 [ESP]
5FCC94 8945F8 MOV F8 [EBP] , EAX
5FCC97 89442408 MOV 8 [ESP] , EAX
5FCC9B 8B45F8 MOV EAX , F8 [EBP]
5FCC9E 8D6DFC LEA EBP , FC [EBP]
5FCCA1 E8F282F5FF CALL 554F98 ( ALLOCATE )
5FCCA6 E80584F5FF CALL 5550B0 ( THROW )
5FCCAB 8944240C MOV C [ESP] , EAX
5FCCAF 8B44241C MOV EAX , 1C [ESP]
5FCCB3 8945FC MOV FC [EBP] , EAX
5FCCB6 8B44240C MOV EAX , C [ESP]
5FCCBA 8945F8 MOV F8 [EBP] , EAX
5FCCBD 8B442418 MOV EAX , 18 [ESP]
5FCCC1 8D6DF8 LEA EBP , F8 [EBP]
5FCCC4 E8B770F5FF CALL 553D80 ( MOVE )
5FCCC9 8945FC MOV FC [EBP] , EAX
5FCCCC 8B442414 MOV EAX , 14 [ESP]
5FCCD0 8945F8 MOV F8 [EBP] , EAX
5FCCD3 8B44240C MOV EAX , C [ESP]
5FCCD7 03442418 ADD EAX , 18 [ESP]
5FCCDB 8945F4 MOV F4 [EBP] , EAX
5FCCDE 8B442410 MOV EAX , 10 [ESP]
5FCCE2 8D6DF4 LEA EBP , F4 [EBP]
5FCCE5 E89670F5FF CALL 553D80 ( MOVE )
5FCCEA 8945FC MOV FC [EBP] , EAX
5FCCED 8B44240C MOV EAX , C [ESP]
5FCCF1 8945F8 MOV F8 [EBP] , EAX
5FCCF4 8B442408 MOV EAX , 8 [ESP]
5FCCF8 8D6DF8 LEA EBP , F8 [EBP]
5FCCFB C3 RET NEAR
END-CODE
( 157 bytes, 42 instructions )
8394 nsec
CODE s+
5FCD3B 8945FC MOV FC [EBP] , EAX
5FCD3E 8B45FC MOV EAX , FC [EBP]
5FCD41 8D6DFC LEA EBP , FC [EBP]
5FCD44 034508 ADD EAX , 8 [EBP]
5FCD47 8945FC MOV FC [EBP] , EAX
5FCD4A 8D6DFC LEA EBP , FC [EBP]
5FCD4D E83D82FFFF CALL 5F4F8F ( hAlloc )
5FCD52 8945FC MOV FC [EBP] , EAX
5FCD55 8B4510 MOV EAX , 10 [EBP]
5FCD58 8945F8 MOV F8 [EBP] , EAX
5FCD5B 8B45FC MOV EAX , FC [EBP]
5FCD5E 8945F4 MOV F4 [EBP] , EAX
5FCD61 8B450C MOV EAX , C [EBP]
5FCD64 8D6DF4 LEA EBP , F4 [EBP]
5FCD67 E81470F5FF CALL 553D80 ( MOVE )
5FCD6C 8945FC MOV FC [EBP] , EAX
5FCD6F 8B4508 MOV EAX , 8 [EBP]
5FCD72 8945F8 MOV F8 [EBP] , EAX
5FCD75 8B45FC MOV EAX , FC [EBP]
5FCD78 8D6DF8 LEA EBP , F8 [EBP]
5FCD7B 034514 ADD EAX , 14 [EBP]
5FCD7E 8945FC MOV FC [EBP] , EAX
5FCD81 8B450C MOV EAX , C [EBP]
5FCD84 8D6DFC LEA EBP , FC [EBP]
5FCD87 E8F46FF5FF CALL 553D80 ( MOVE )
5FCD8C 894510 MOV 10 [EBP] , EAX
5FCD8F 8B5D00 MOV EBX , 0 [EBP]
5FCD92 895D0C MOV C [EBP] , EBX
5FCD95 8B450C MOV EAX , C [EBP]
5FCD98 8D6D10 LEA EBP , 10 [EBP]
5FCD9B C3 RET NEAR
END-CODE
( 97 bytes, 31 instructions )
5288 nsec
CODE MAXMIN
5FCDDF 8945FC MOV FC [EBP] , EAX
5FCDE2 B80C000000 MOV EAX , # C
5FCDE7 8D6DFC LEA EBP , FC [EBP]
5FCDEA E8F562F5FF CALL 5530E4 ( DRMOVE )
5FCDEF 680C000000 PUSH , # C
5FCDF4 6868325500 PUSH , # 553268
5FCDF9 8945FC MOV FC [EBP] , EAX
5FCDFC 8B442410 MOV EAX , 10 [ESP]
5FCE00 8945F8 MOV F8 [EBP] , EAX
5FCE03 8B44240C MOV EAX , C [ESP]
5FCE07 8D6DF8 LEA EBP , F8 [EBP]
5FCE0A E86155F5FF CALL 552370 ( MAX )
5FCE0F 8945FC MOV FC [EBP] , EAX
5FCE12 8B442408 MOV EAX , 8 [ESP]
5FCE16 8D6DFC LEA EBP , FC [EBP]
5FCE19 E86E55F5FF CALL 55238C ( MIN )
5FCE1E C3 RET NEAR
END-CODE
( 64 bytes, 17 instructions )
130 nsec
CODE maxmin
5FCE63 8945FC MOV FC [EBP] , EAX
5FCE66 8B4500 MOV EAX , 0 [EBP]
5FCE69 8D6DFC LEA EBP , FC [EBP]
5FCE6C 8B5508 MOV EDX , 8 [EBP]
5FCE6F 3BD0 CMP EDX , EAX
5FCE71 0F4FC2 CMOVG EAX , EDX
5FCE74 8B5500 MOV EDX , 0 [EBP]
5FCE77 3BD0 CMP EDX , EAX
5FCE79 0F4CC2 CMOVL EAX , EDX
5FCE7C 8D6D0C LEA EBP , C [EBP]
5FCE7F C3 RET NEAR
END-CODE
( 29 bytes, 11 instructions )
85 nsec
CODE DCRT3
5FCEC7 8945FC MOV FC [EBP] , EAX
5FCECA B80C000000 MOV EAX , # C
5FCECF 8D6DFC LEA EBP , FC [EBP]
5FCED2 E80D62F5FF CALL 5530E4 ( DRMOVE )
5FCED7 680C000000 PUSH , # C
5FCEDC 6868325500 PUSH , # 553268
5FCEE1 8945FC MOV FC [EBP] , EAX
5FCEE4 8B44240C MOV EAX , C [ESP]
5FCEE8 03442408 ADD EAX , 8 [ESP]
5FCEEC 8945F8 MOV F8 [EBP] , EAX
5FCEEF 8B442410 MOV EAX , 10 [ESP]
5FCEF3 F76DF8 IMUL F8 [EBP]
5FCEF6 8945F8 MOV F8 [EBP] , EAX
5FCEF9 8B44240C MOV EAX , C [ESP]
5FCEFD 8945F4 MOV F4 [EBP] , EAX
5FCF00 8B442408 MOV EAX , 8 [ESP]
5FCF04 F76DF4 IMUL F4 [EBP]
5FCF07 0345F8 ADD EAX , F8 [EBP]
5FCF0A 8D6DFC LEA EBP , FC [EBP]
5FCF0D C3 RET NEAR
END-CODE
( 71 bytes, 20 instructions )
700 nsec
CODE dcrt3
5FCF53 8945FC MOV FC [EBP] , EAX
5FCF56 8B45FC MOV EAX , FC [EBP]
5FCF59 8D6DFC LEA EBP , FC [EBP]
5FCF5C 034504 ADD EAX , 4 [EBP]
5FCF5F F76D08 IMUL 8 [EBP]
5FCF62 8945FC MOV FC [EBP] , EAX
5FCF65 8B4500 MOV EAX , 0 [EBP]
5FCF68 8D6DFC LEA EBP , FC [EBP]
5FCF6B F76D08 IMUL 8 [EBP]
5FCF6E 034500 ADD EAX , 0 [EBP]
5FCF71 8D6D10 LEA EBP , 10 [EBP]
5FCF74 C3 RET NEAR
END-CODE
( 34 bytes, 12 instructions )
238 nsec
PS
1. Код попроще и побыстрее.
2. Писать такой код тоже попроще и побыстрее (исчезает основная составляющая
оперативного инструментального контекста)
3. Время поиска имен операторов в предложенной форме записи можно свести
к теоретическому минимуму - к одному обращению к памяти.
Интерпретация(как следствие быстрого поиска имен) может быть предельно ускорена.
Ну и компиляция по той же причине тоже ускоряется.
4. Введение внешнего флага немедленного исполнения(как атрибута имени - в виде, например, суффикса)
исключает понятие слова немедленного исполнения (таким образом исключается еще одна составляющая
оперативного инструментального контекста).
PPS
Некоторое уточнение, источником параметров является не только неизменный исходный стековый кадр,
но и содержимое всех ячеек текущего стека. "Именем" параметра является номер ячейки-контейнера
стека. По "имени" выкладывается на стек содержимое ячейки-контейнера. Начальная ячейка исходного
стекового кадра имеет номер 1.
В записи \[312+22*43*2- фрагмент [3 означает что исходный стековый кадр имеет размер 3 ячейки,
ячейки нумеруются 1 2 3. Фрагмент 12+ означает, что в ячейке 4 будет сумма содержимого 1 и 2 ячейки,
а ячейке 5 будет квадрат содержимого ячейки 2, а фрагмент 43*2- поместит в ячейку 6 результат 43*2-.
Таким образом стек будет содержать 6 ячеек. Имеем таким образом несколько другой порядок
работы с параметрами на стеке, с более "прямым" к ним доступом.