Forth http://fforum.winglion.ru/ |
|
Еще один способ работы с параметрами на стеке http://fforum.winglion.ru/viewtopic.php?f=2&t=3141 |
Страница 1 из 5 |
Автор: | chess [ Вс сен 17, 2017 22:10 ] |
Заголовок сообщения: | Еще один способ работы с параметрами на стеке |
Код: \ | inp n | par | исходный стек \ | out | free (К-n) | inp n | par | промежуточный стек - par - незатрагиваемые пар-ры \ | out | par | конечный стек : stack ( n -- ) CREATE HERE , CELLS ALLOT ; 256 stack locst \ переложить со стека параметров на стек : >cs ( x -- | cs: -- x) locst CELL OVER +! @ ! ; \ скопировать со стека на стек параметров : cs@ ( cs: x -- x | -- x) locst @ @ ; \ убрать верхний со стека : cs-drop ( cs: x --) locst DUP DUP @ = INVERT IF CELL NEGATE SWAP +! THEN ; \ переложить со стека на стек параметров : cs> ( cs: x -- | -- x) cs@ cs-drop ; : bs ( N -- ) >R DEPTH CELLS >R S0 @ >cs S0 @ R> - R> CELLS + DUP >cs 15 CELLS - SP! SP@ S0 ! ; : p ( n -- An ) CELLS NEGATE cs@ + ; : es DEPTH CELLS >R cs@ 15 CELLS - R@ - cs@ R@ - R@ MOVE cs> cs> S0 ! R> - SP! ; : 1> 1 p @ ; : >1 1 p ! ; : 2> 2 p @ ; : >2 2 p ! ; : 3> 3 p @ ; : >3 3 p ! ; : 4> 4 p @ ; : >4 4 p ! ; : 5> 5 p @ ; : >5 5 p ! ; : 6> 6 p @ ; : >6 6 p ! ; : 7> 7 p @ ; : >7 7 p ! ; : 8> 8 p @ ; : >8 8 p ! ; : 9> 9 p @ ; : >9 9 p ! ; : a> 10 p @ ; : >a 10 p ! ; : b> 11 p @ ; : >b 11 p ! ; : c> 12 p @ ; : >c 12 p ! ; : d> 13 p @ ; : >d 13 p ! ; : e> 14 p @ ; : >e 14 p ! ; : f> 15 p @ ; : >f 15 p ! ; : Pr1 3 bs 1> 2> * 1> 3> * 2> 3> * 3 bs 1> 2> + 1> 3> + es 10 2 bs 2> 1> + es 11 es ; 1 2 3 4 Pr1 LOG Код: Ok ( 1 14 28 11 )
|
Автор: | chess [ Вс дек 03, 2017 21:59 ] |
Заголовок сообщения: | Re: Еще один способ работы с параметрами на стеке |
Тот же пример. Обозначенная выше модель работы с параметрами на стеке с локальным именованием этих параметров. Именование сквозное, т.е. имена не могут быть одинаковыми на разных уровнях вложенности. Имена разных уровней вложенности не могут использоваться совместно. Код: : Pr2 3 bs a^ b^ c^ x^ \ создание лок. переменных на данном уровне вложенности a b * a c * b c * 3 bs d^ e^ f^ d e + d f + es 10 2 bs g^ h^ g h + es 11 es ; 1 2 3 4 Pr2 log Код: Ok ( 1 14 28 11 )
|
Автор: | chess [ Ср дек 13, 2017 22:10 ] |
Заголовок сообщения: | Re: Еще один способ работы с параметрами на стеке |
Оптимизированный вариант кода. Код: : bs ( N -- ) 1+ CELLS SP@ + DUP >cs 60 - SP! ; : p ( n -- An ) CELLS NEGATE cs@ + ; : es SP@ DUP 60 + TUCK cs> OVER - MOVE SP! ; PS. Для создания локальных переменных используется только область памяти, выделенная для стека параметров, путем перемещения указателя стека на фиксированное значение в сторону увеличения глубины стека. После использования таких переменных указатель стека устанавливается в сторону уменьшения глубины стека, с учетом стекового эффекта. Получается экономно в сравнении с вариантами размещения лок. переменных на стеке возвратов(СПФ) или в хипе. При этом сохраняется возможность использования таких лок. переменных в многопоточных приложениях. |
Автор: | chess [ Чт дек 28, 2017 22:33 ] |
Заголовок сообщения: | Re: Еще один способ работы с параметрами на стеке |
Дальнейшее совершенствование механизма. Вспомогательный стек ( операции >cs , cs> , cs@ ) заменяем стеком возвратов ( операции >R , R> , R@ ) Код: : bs ( N -- ) 1+ CELLS SP@ + DUP R> SWAP >R >R 60 - SP! ; M: p ( n -- An ) CELLS NEGATE R> R@ SWAP >R + ; \ макрос : es SP@ DUP 60 + TUCK R> R> SWAP >R OVER - MOVE SP! ; PS. В стеке возвратов сохраняется только один адрес, указывающий на начало области локальных переменных для каждого уровня вложенности. На практике достаточно будет одного уровня вложенности внутри слова. Т.е. адрес на стеке возвратов будет только один. |
Автор: | Victor__v [ Пт дек 29, 2017 12:41 ] |
Заголовок сообщения: | Re: Еще один способ работы с параметрами на стеке |
То есть, Создаём область в стеке данных подальше от верхушки стека? Ежели так, то какая защита от затирания быть должна? |
Автор: | chess [ Сб дек 30, 2017 01:57 ] |
Заголовок сообщения: | Re: Еще один способ работы с параметрами на стеке |
Мне проще написать на форте, чем объяснить на русском языке, так как язык сильно неоднозначен и неточен одновременно. Над данными стека создаем область( у меня размером 15 ячеек, в которые входят нужные верхние ячейки стека ). Над этой областью размещаем указатель вершины стека(заводим пустой стек). На этом стеке оперируем используя локальные переменные - содержимое тех самых 15 ячеек. Затем параметры вычисленные на новом стеке переносим обратно в начало области в 15 ячеек. Код: Иллюстрация применения механизма лок. переменных на примере конкатенации двух строк в динамической памяти перенос выходных параметров с промежуточного стека на конечный стек u ----------------------->---------------------- <-- конечный промежуточный указатель вершины стека a ----------------------->-------------------- |<-- начальный промежуточный указатель вершины стека -- ^ | | .. | | | -- | | | -- u | | | -- a 15 CELLS ( область лок. переменных ) | | u2 | входные | |<-- начальный указатель вершины стека a2 | пар-ры | | u1 | | --> u <-- конечный указатель вершины стека a1 v адрес начала области лок. переменных ----> a адрес начала области лок. переменных переносится на стек возвратов, при переносе выходных параметров с промежуточного стека на конечный стек адрес начала области лок. переменных снимается со стека возвратов на форте в режиме интерпретации ( a1 u1 a2 u2 -- a u ) S" 123 " S" abc" 4 bs 2> 4> + >6 6> ALLOCATE THROW >5 1> 5> 2> MOVE 3> 5> 2> + 4> MOVE 5> 6> es TYPE CR на форте сначала в режиме компиляции : s+ \ a1 u1 a2 u2 -- a u 4 bs 2> 4> + >6 6> ALLOCATE THROW >5 1> 5> 2> MOVE 3> 5> 2> + 4> MOVE 5> 6> es ; S" 456 " S" def" s+ TYPE CR на форте в стенографическом стиле : ss+ \ a1 u1 a2 u2 -- a u 4 /[24+:66h:5152V352+4V56] ; S" 789 " S" ghi" ss+ TYPE CR ps. При такой реализации используются аппаратные возможности процессора с минимумом ограничений на использование лок. переменных, в том числе при организации многопоточных вычислений (многозадачности внутри форта). |
Автор: | Victor__v [ Сб дек 30, 2017 10:16 ] |
Заголовок сообщения: | Re: Еще один способ работы с параметрами на стеке |
А, понял. Резервируем пространство в стеке данных с захватом нужных элементов стека. Смещаем указатель вниз. Помещаем прежний указатель стека данных в стек возвратов. Хм, хорошо. Как развитие идеи можно немного переписать. Сделать так, чтобы при упоминании bs, es ( ест-но чуть переписанный ) укладывался в стек возвратов так сказать на откат. В итоге снимем с себя необходимость контроля за парностью структур. Однако ж, будут проблемы в режиме интерпретации (слететь может при ретрансляции источника). Однозначно возьму и переработаю в своём форте Ещё врем. связывание с именами сделаю, дабы цифирями не напрягаться. |
Автор: | chess [ Сб дек 30, 2017 17:18 ] |
Заголовок сообщения: | Re: Еще один способ работы с параметрами на стеке |
Сравним варианты реализации предложенного механизма с уже существующим. Код: \ существующий в SPF вариант : s+ { a1 u1 a2 u2 \ a u } u1 u2 + TO u u ALLOCATE THROW TO a a1 a u1 MOVE a2 a u1 + u2 MOVE a u ; \ стенографический стиль записи ( с фиксированным именованием лок. переменных) : s1+ 4 /[24+h:5152V352+4V524+] ; \ традиционный стиль записи ( с произвольным именованием лок. переменных) : s2+ 4 /[ a1^ u1^ a2^ u2^ a^ u^ u1 u2 + iv u u ALLOCATE THROW iv a a1 a u1 MOVE a2 a u1 + u2 MOVE a u /] ; \ тестовые процедуры для оценки быстродействия : tst-s+ S" 12 " S" ab " s+ ; : tst-s1+ S" 12 " S" ab " s1+ ; : tst-s2+ S" 12 " S" ab " s2+ ; STARTLOG SEE s+ SEE s1+ SEE s2+ METER tst-s+ METER tst-s1+ METER tst-s2+ LOG Код: CODE s+ 5D9273 8945FC MOV FC [EBP] , EAX 5D9276 B810000000 MOV EAX , # 10 5D927B 8D6DFC LEA EBP , FC [EBP] 5D927E E8659EF7FF CALL 5530E8 ( DRMOVE ) 5D9283 8945FC MOV FC [EBP] , EAX 5D9286 B802000000 MOV EAX , # 2 5D928B 8D6DFC LEA EBP , FC [EBP] 5D928E E8919FF7FF CALL 553224 ( (RALLOT) ) 5D9293 6818000000 PUSH , # 18 5D9298 686C325500 PUSH , # 55326C 5D929D 8945FC MOV FC [EBP] , EAX 5D92A0 8B442418 MOV EAX , 18 [ESP] 5D92A4 03442410 ADD EAX , 10 [ESP] 5D92A8 89442408 MOV 8 [ESP] , EAX 5D92AC 8B442408 MOV EAX , 8 [ESP] 5D92B0 8D6DFC LEA EBP , FC [EBP] 5D92B3 E8E4BCF7FF CALL 554F9C ( ALLOCATE ) 5D92B8 E8F7BDF7FF CALL 5550B4 ( THROW ) 5D92BD 8944240C MOV C [ESP] , EAX 5D92C1 8B44241C MOV EAX , 1C [ESP] 5D92C5 8945FC MOV FC [EBP] , EAX 5D92C8 8B44240C MOV EAX , C [ESP] 5D92CC 8945F8 MOV F8 [EBP] , EAX 5D92CF 8B442418 MOV EAX , 18 [ESP] 5D92D3 8D6DF8 LEA EBP , F8 [EBP] 5D92D6 E8A9AAF7FF CALL 553D84 ( MOVE ) 5D92DB 8945FC MOV FC [EBP] , EAX 5D92DE 8B442414 MOV EAX , 14 [ESP] 5D92E2 8945F8 MOV F8 [EBP] , EAX 5D92E5 8B44240C MOV EAX , C [ESP] 5D92E9 03442418 ADD EAX , 18 [ESP] 5D92ED 8945F4 MOV F4 [EBP] , EAX 5D92F0 8B442410 MOV EAX , 10 [ESP] 5D92F4 8D6DF4 LEA EBP , F4 [EBP] 5D92F7 E888AAF7FF CALL 553D84 ( MOVE ) 5D92FC 8945FC MOV FC [EBP] , EAX 5D92FF 8B44240C MOV EAX , C [ESP] 5D9303 8945F8 MOV F8 [EBP] , EAX 5D9306 8B442408 MOV EAX , 8 [ESP] 5D930A 8D6DF8 LEA EBP , F8 [EBP] 5D930D C3 RET NEAR END-CODE ( 155 bytes, 41 instructions ) CODE s1+ 5D931F 8945FC MOV FC [EBP] , EAX 5D9322 B804000000 MOV EAX , # 4 5D9327 8D6DFC LEA EBP , FC [EBP] 5D932A E8BCB4FFFF CALL 5D47EB ( bs ) 5D932F E863B6FFFF CALL 5D4997 ( 2> ) 5D9334 E846B7FFFF CALL 5D4A7F ( 4> ) 5D9339 034500 ADD EAX , 0 [EBP] 5D933C 8D6D04 LEA EBP , 4 [EBP] 5D933F E873BEFFFF CALL 5D51B7 ( hAlloc ) 5D9344 E8CEB7FFFF CALL 5D4B17 ( >5 ) 5D9349 E8D5B5FFFF CALL 5D4923 ( 1> ) 5D934E E8A0B7FFFF CALL 5D4AF3 ( 5> ) 5D9353 E83FB6FFFF CALL 5D4997 ( 2> ) 5D9358 E827AAF7FF CALL 553D84 ( MOVE ) 5D935D E8A9B6FFFF CALL 5D4A0B ( 3> ) 5D9362 E88CB7FFFF CALL 5D4AF3 ( 5> ) 5D9367 E82BB6FFFF CALL 5D4997 ( 2> ) 5D936C 034500 ADD EAX , 0 [EBP] 5D936F 8D6D04 LEA EBP , 4 [EBP] 5D9372 E808B7FFFF CALL 5D4A7F ( 4> ) 5D9377 E808AAF7FF CALL 553D84 ( MOVE ) 5D937C E872B7FFFF CALL 5D4AF3 ( 5> ) 5D9381 E811B6FFFF CALL 5D4997 ( 2> ) 5D9386 E8F4B6FFFF CALL 5D4A7F ( 4> ) 5D938B 034500 ADD EAX , 0 [EBP] 5D938E 8D6D04 LEA EBP , 4 [EBP] 5D9391 E825B5FFFF CALL 5D48BB ( es ) 5D9396 C3 RET NEAR END-CODE ( 120 bytes, 28 instructions ) CODE s2+ 5D93A7 8945FC MOV FC [EBP] , EAX 5D93AA B804000000 MOV EAX , # 4 5D93AF 8D6DFC LEA EBP , FC [EBP] 5D93B2 E834B4FFFF CALL 5D47EB ( bs ) 5D93B7 E8C9A0FDFF CALL 5B3485 ( lcode+40E ) 5D93BC E81CA1FDFF CALL 5B34DD ( lcode+466 ) 5D93C1 034500 ADD EAX , 0 [EBP] 5D93C4 8D6D04 LEA EBP , 4 [EBP] 5D93C7 E87CA1FDFF CALL 5B3548 ( lcode+4D1 ) 5D93CC E864A1FDFF CALL 5B3535 ( lcode+4BE ) 5D93D1 E8C6BBF7FF CALL 554F9C ( ALLOCATE ) 5D93D6 E8D9BCF7FF CALL 5550B4 ( THROW ) 5D93DB E83CA1FDFF CALL 5B351C ( lcode+4A5 ) 5D93E0 E874A0FDFF CALL 5B3459 ( lcode+3E2 ) 5D93E5 E81FA1FDFF CALL 5B3509 ( lcode+492 ) 5D93EA E896A0FDFF CALL 5B3485 ( lcode+40E ) 5D93EF E890A9F7FF CALL 553D84 ( MOVE ) 5D93F4 E8B8A0FDFF CALL 5B34B1 ( lcode+43A ) 5D93F9 E80BA1FDFF CALL 5B3509 ( lcode+492 ) 5D93FE E882A0FDFF CALL 5B3485 ( lcode+40E ) 5D9403 034500 ADD EAX , 0 [EBP] 5D9406 8D6D04 LEA EBP , 4 [EBP] 5D9409 E8CFA0FDFF CALL 5B34DD ( lcode+466 ) 5D940E E871A9F7FF CALL 553D84 ( MOVE ) 5D9413 E8F1A0FDFF CALL 5B3509 ( lcode+492 ) 5D9418 E818A1FDFF CALL 5B3535 ( lcode+4BE ) 5D941D E899B4FFFF CALL 5D48BB ( es ) 5D9422 C3 RET NEAR END-CODE ( 124 bytes, 28 instructions ) 834 tics 219 nsec 816 tics 214 nsec 831 tics 218 nsec Ok PS. По объему в памяти варианты предложенного механизма лучше, по времени исполнения примерно одинаковы. |
Автор: | Victor__v [ Пт янв 05, 2018 18:54 ] |
Заголовок сообщения: | Re: Еще один способ работы с параметрами на стеке |
Вот, как и говорил вариант для моего форта. Всё работоспособно. Разумеется, кое-что можно переписать получше. А ещё лучше на асме Кстати, насчёт Интела есть такие команды как ENTER и LEAVE Файл: ds-local-BASE.F Код: \ базовые слова \ для лок.переменных \ на стеке данных \ ~er 03.01.2018 : (local) SP@ R@ 9 CELLS - \ sp - NEGATE CELL / N>R R@ 1+ RPICK \ sp CELL+ SP! NR> DROP RDROP ; : local: \ n -- R: -- sp '(local) 1- >R SP@ R> CELLS + ['] (local) R> 3 N>R RDROP 2 RPICK 9 CELLS - SP! ; Файл: ds-local2.F Код: \ локальные переменные на стеке данных \ с поддержкой возможности наименования \ ~er 05.01.2018 \ В тек. словарь компилируются 2 слова \ Во временный идут все остальные \ Действие файла на стеки: \ Voc: a b -- a b tmp REQUIRE local: DS-LOCAL-BASE.F CURRENT KEEP TEMP-WORDLIST ALSO CONTEXT ! DEFINITIONS \ для поддержки корректной работы \ при использовании стека возвратов \ в связке с лок. переменными 0 VALUE dLocalR-correct \ для сброса лок.переменных CREATE dLocalLFA-link 4 CELLS ALLOT 0 VALUE dLocalLFAvocHere : (local@) 1 dLocalR-correct + LIT, POSTPONE RPICK LIT, POSTPONE - POSTPONE @ ; : (local!) 1 dLocalR-correct + LIT, POSTPONE RPICK LIT, POSTPONE - POSTPONE ! ; \ создать слова во врем. словаре \ слово -- дать значение переменной \ слово! -- присвоить значение переменной : create-local-data \ n a u -- n TRUE STATE KEEP! \ только компиляция 2>R 2R@ SHEADER DUP CELLS LIT, ['] (local@) COMPILE, RET, IMMEDIATE 2R> MOVE->R RF^ 2DUP + '!' SWAP C! 1+ SHEADER DUP CELLS LIT, ['] (local!) COMPILE, RET, IMMEDIATE ; : new-d-local dLocalLFA-link [ CURRENT @ LIT, ] L>LLFA 4 CELLS MOVE dLocalLFAvocHere [ CURRENT @ LIT, ] L>hereFA @ ! [ CURRENT @ LIT, ] CURRENT KEEP! 0 BEGIN PARSE-NAME 2DUP S" }" COMPARE WHILE create-local-data 1+ REPEAT DROP 2DROP ; : local{ \ n -- in: name1 name2 ... namen } new-d-local POSTPONE local: ; IMMEDIATE HERE TO dLocalLFAvocHere CURRENT @ L>LLFA dLocalLFA-link 4 CELLS MOVE \EOF Пример: : Disk^2 3 local{ a b c D } \ в D мусор b b * 4 a c * * - D! D ; Как-то так. |
Автор: | chess [ Пн янв 29, 2018 22:28 ] |
Заголовок сообщения: | Re: Еще один способ работы с параметрами на стеке |
Вариант с использованием стека в USER памяти ( стек возвратов при этом не используется ) Код: USER dps 0 dps ! ps.USER-CREATE ads 60 USER-ALLOT : bs ( N -- ) 1+ CELLS SP@ + DUP 4 dps +! ads dps @ + ! 60 - SP! ; : prm ( n -- An ) CELLS NEGATE ads dps @ + @ + ; : es SP@ DUP 60 + TUCK ads dps @ + @ -4 dps +! OVER - MOVE SP! ; быстродействие тут даже чуть выше, чем в варианте реализации из SPF, позволяет использовать локальные переменные при распараллеливании приложений для многоядерных процессоров. |
Автор: | Victor__v [ Вт янв 30, 2018 12:13 ] |
Заголовок сообщения: | Re: Еще один способ работы с параметрами на стеке |
Цитата: Вариант с использованием стека в USER памяти ( стек возвратов при этом не используется ) Ну, так не интересно. К тому же этот вариант тяжелей использовать. А если памяти не хватит? Тут либо стек, который по умолчанию безконечный, или хип. |
Автор: | chess [ Вт янв 30, 2018 21:47 ] |
Заголовок сообщения: | Re: Еще один способ работы с параметрами на стеке |
Зато не требуется переопределение ниже указанных слов для возможности использовать локальные переменные внутри цикла DO LOOP и независимо от изменения содержимого стека возвратов словами >R R> , ну и других слов создаваемых самостоятельно, использующих стек возвратов DO ?DO LOOP +LOOP >R R> RDROP 2>R 2R> Ну памяти-то в ПК предостаточно (например, кэш 3 уровня у меня для каждого из 8-ми поддерживаемых аппаратно потоков, аж 8 Мб). |
Автор: | Victor__v [ Ср янв 31, 2018 09:06 ] |
Заголовок сообщения: | Re: Еще один способ работы с параметрами на стеке |
chess писал(а): Зато не требуется переопределение ниже указанных слов для возможности использовать локальные переменные внутри цикла DO LOOP и независимо от изменения содержимого стека возвратов словами >R R> , ну и других слов создаваемых самостоятельно, использующих стек возвратов DO ?DO LOOP +LOOP >R R> RDROP 2>R 2R> Ну памяти-то в ПК предостаточно (например, кэш 3 уровня у меня для каждого из 8-ми поддерживаемых аппаратно потоков, аж 8 Мб). Я смягчил это в своём форте введением механизма предкомпиляции. К тому же в этом (доопределении) нет ничего сложного. А вот использование юзер-области для ЛОКАЛЬНЫХ служебных слов т.е. работающих не повсеместно в форте, не есть хорошо (личное мнение) |
Автор: | mOleg [ Ср янв 31, 2018 11:23 ] |
Заголовок сообщения: | Re: Еще один способ работы с параметрами на стеке |
Victor__v писал(а): А вот использование юзер-области для ЛОКАЛЬНЫХ служебных слов т.е. работающих не повсеместно в форте, не есть хорошо (личное мнение) А обосновать можете? Обычно, как раз наоборот считается. |
Автор: | _KROL [ Ср янв 31, 2018 11:53 ] |
Заголовок сообщения: | Re: Еще один способ работы с параметрами на стеке |
Victor__v писал(а): А вот использование юзер-области для ЛОКАЛЬНЫХ служебных слов т.е. работающих не повсеместно в форте, не есть хорошо (личное мнение) Хм, но это же область пользователя, да и слова пользовательские, или я что-то недопонимаю?Хоть несколько стеков объявлю, главное не то, что они в USER-области, а чтобы нормально взаимодействовали между собой (не перекрывая друг друга). |
Страница 1 из 5 | Часовой пояс: UTC + 3 часа [ Летнее время ] |
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group http://www.phpbb.com/ |