Forth и другие саморасширяющиеся системы программирования Locations of visitors to this page
Текущее время: Ср авг 10, 2022 08:03

...
Google Search
Forth-FAQ Spy Grafic

Часовой пояс: UTC + 3 часа [ Летнее время ]




Начать новую тему Ответить на тему  [ Сообщений: 49 ]  На страницу Пред.  1, 2, 3, 4
Автор Сообщение
 Заголовок сообщения: Re: Еще один способ работы с параметрами на стеке
СообщениеДобавлено: Сб янв 01, 2022 17:29 
Не в сети
Аватара пользователя

Зарегистрирован: Чт июл 20, 2006 11:31
Сообщения: 2157
Откуда: Екб
Благодарил (а): 0 раз.
Поблагодарили: 41 раз.
Victor__v писал(а):
Как понимаю, Вы закидываете часть переменных выше вершины стека.
Но как происходит контроль измерения глубины?
При изменении этого самого стека?

Ничего никуда не закидывается. В начале манипулятора просто отмечается с каким количеством верхних параметров на стеке будет работать данный манипулятор. Вот на стеке находятся 4 параметра: a b c d. Нам нужно оставить на стеке параметр а, а с параметрами
b c d поработать. Мы пишем определение
Код:
: proba  /[312M3m'1 ;
что эквивалентно
Код:
: proba { b c d } b c MAX d MIN ;

После исполнения слова proba на стеке останется два параметра
Код:
a
и результат от
Код:
b c MAX d MIN

Для управления стеком при компиляции используются стековые эффекты входящих в определение через двоеточие слов.
Это технологический прием. Каждое слово форта имеет стековый эффект - величина на которую слово меняет глубину стека.
Зная исходное состояние стека и стековые эффекты последовательно выполняемых слов, можно вычислять положение ячеек стека
во время компиляции кода определения.
Сложности при компиляции возникают для ветвлений, циклов, слов типа EXECUTE, LAMBDA{ и тому подобных.
Для циклов я ввел правило - стековый эффект внутри цикла должен быть нулевым(аналогия со стеком возвратов).
Для ветвлений ввел массив трасс ветвления, в который вписываются вычисляемые стековые эффекты каждой трассы.
Для EXECUTE нужно менять структуру словарной статьи - вводить туда значение стекового эффекта
(сейчас я привязку слов к их стековым эффектам реализовал в обход словарей). Пока такие слова ( типа EXECUTE) не использую.

Немного оптимизировал код определений через двоеточие в части сокращения числа перестановок указателя стека.
Убрал слово DUP как лишнее, так как вместо него можно просто написать номер верхней ячейки.
С DROP такое не проходит, хотя запись, например ]3, означает, что если в стеке было 4 параметра,
останется 3 нижних, верхнее удалится. Таким образом DROP тоже можно исключить.

Вот еще некоторые соображения на примере:
Код:
\ площадь треугольника по Герону
: S3 { a b c \ p }
  a b + c + 2 / TO p p a - p b - * p c - * p * sqrt ;                SEE S3

: s3 /[312+3+(2)/41-42-*43-*4*q'1 ;                                  SEE s3

: TST 100 0 DO 3 4 5 S3 DROP LOOP ; TIME
: tst 100 0 DO 3 4 5 s3 DROP LOOP ; time

CODE S3
621623 8945FC           MOV     FC [EBP] , EAX
621626 B80C000000       MOV     EAX , # C
62162B 8D6DFC           LEA     EBP , FC [EBP]
62162E E8B11AF3FF       CALL    5530E4  ( DRMOVE )
621633 8945FC           MOV     FC [EBP] , EAX
621636 B801000000       MOV     EAX , # 1
62163B 8D6DFC           LEA     EBP , FC [EBP]
62163E E8DD1BF3FF       CALL    553220  ( (RALLOT) )
621643 6810000000       PUSH    , # 10
621648 6868325500       PUSH    , # 553268
62164D 8945FC           MOV     FC [EBP] , EAX
621650 8B442414         MOV     EAX , 14 [ESP]
621654 03442410         ADD     EAX , 10 [ESP]
621658 0344240C         ADD     EAX , C [ESP]
62165C B902000000       MOV     ECX , # 2
621661 99               CDQ
621662 F7F9             IDIV    ECX
621664 89442408         MOV     8 [ESP] , EAX
621668 2B442414         SUB     EAX , 14 [ESP]
62166C 8945F8           MOV     F8 [EBP] , EAX
62166F 8B442408         MOV     EAX , 8 [ESP]
621673 2B442410         SUB     EAX , 10 [ESP]
621677 F76DF8           IMUL    F8 [EBP]
62167A 8945F8           MOV     F8 [EBP] , EAX
62167D 8B442408         MOV     EAX , 8 [ESP]
621681 2B44240C         SUB     EAX , C [ESP]
621685 F76DF8           IMUL    F8 [EBP]
621688 8945F8           MOV     F8 [EBP] , EAX
62168B 8B442408         MOV     EAX , 8 [ESP]
62168F F76DF8           IMUL    F8 [EBP]
621692 8D6DFC           LEA     EBP , FC [EBP]
621695 E88D57FFFF       CALL    616E27  ( sqrt )
62169A C3               RET     NEAR
END-CODE
( 120 bytes, 33 instructions )


CODE s3
6216AB 8945FC           MOV     FC [EBP] , EAX
6216AE 8B4504           MOV     EAX , 4 [EBP]
6216B1 034500           ADD     EAX , 0 [EBP]
6216B4 0345FC           ADD     EAX , FC [EBP]
6216B7 8945F8           MOV     F8 [EBP] , EAX
6216BA B802000000       MOV     EAX , # 2
6216BF 8BC8             MOV     ECX , EAX
6216C1 8B45F8           MOV     EAX , F8 [EBP]
6216C4 99               CDQ
6216C5 F7F9             IDIV    ECX
6216C7 8945F8           MOV     F8 [EBP] , EAX
6216CA 2B4504           SUB     EAX , 4 [EBP]
6216CD 8945F4           MOV     F4 [EBP] , EAX
6216D0 8B45F8           MOV     EAX , F8 [EBP]
6216D3 2B4500           SUB     EAX , 0 [EBP]
6216D6 F76DF4           IMUL    F4 [EBP]
6216D9 8945F4           MOV     F4 [EBP] , EAX
6216DC 8B45F8           MOV     EAX , F8 [EBP]
6216DF 2B45FC           SUB     EAX , FC [EBP]
6216E2 F76DF4           IMUL    F4 [EBP]
6216E5 F76DF8           IMUL    F8 [EBP]
6216E8 8D6DF8           LEA     EBP , F8 [EBP]
6216EB E83757FFFF       CALL    616E27  ( sqrt )
6216F0 8D6D10           LEA     EBP , 10 [EBP]
6216F3 C3               RET     NEAR
END-CODE
( 73 bytes, 25 instructions )

2836 ns ( время TST)
1274 ns ( время tst)


Вычисление на стеке в итоге помещает результат в конкретную ячейку, в качестве
имени которой в дальнейших вычислениях используется номер этой ячейки.
Необходимости в явном присвоении (как для локальных переменных в SPF - см. пример выше ) нет,
что дополнительно повышает эффективность кода.
Еще кое-что:
Использование номеров ячеек в качестве имен локальных переменных вполне годится, потому, что
внутри определения локальных переменных немного и наделять их каким особым смыслом нет необходимости.
PS. С Новым Годом!

_________________
С уважением, chess


Вернуться к началу
 Профиль Отправить личное сообщение  
Ответить с цитатой  
 Заголовок сообщения: Re: Еще один способ работы с параметрами на стеке
СообщениеДобавлено: Ср май 18, 2022 22:21 
Не в сети
Аватара пользователя

Зарегистрирован: Чт июл 20, 2006 11:31
Сообщения: 2157
Откуда: Екб
Благодарил (а): 0 раз.
Поблагодарили: 41 раз.
Вариант реализации локальных переменных без использования хипа и стека возвратов
с использованием только стека параметров на основе выражений типа стексов.
Этот вариант вполне подошел также и для Win64FasmForth ( 64-разрядная форт-система для Windows )
в качестве оптимизатора, которого в Win64FasmForth нет.
Пример:

Код:
: 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+
  S" 123 " S" abc" S+ CR TYPE

: s+ ( a1 u1 a2 u2 -- a u )
  4$24 + ALLOCATE THROW
  5$152 MOVE
  5|5243452 + 2|21 MOVE +
; SEE s+
S" 123 " S" abc" s+  CR TYPE

CODE S+
435F58   E8 4F 39 FD FF                                     call        $4098AC  ( DUP )
435F5D   48 B8 00 00 00 00 00 00 00 00                      mov rax,$0
435F67   E8 CF 48 FD FF                                     call        $40A83B  ( >R )
435F6C   E8 3B 39 FD FF                                     call        $4098AC  ( DUP )
435F71   48 B8 00 00 00 00 00 00 00 00                      mov rax,$0
435F7B   E8 BB 48 FD FF                                     call        $40A83B  ( >R )
435F80   E8 B6 48 FD FF                                     call        $40A83B  ( >R )
435F85   E8 B1 48 FD FF                                     call        $40A83B  ( >R )
435F8A   E8 AC 48 FD FF                                     call        $40A83B  ( >R )
435F8F   E8 A7 48 FD FF                                     call        $40A83B  ( >R )
435F94   E8 13 39 FD FF                                     call        $4098AC  ( DUP )
435F99   48 B8 30 00 00 00 00 00 00 00                      mov rax,$30
435FA3   E8 93 48 FD FF                                     call        $40A83B  ( >R )
435FA8   E8 FF 38 FD FF                                     call        $4098AC  ( DUP )
435FAD   48 B8 8C BE 40 00 00 00 00 00                      mov rax,$40BE8C
435FB7   E8 7F 48 FD FF                                     call        $40A83B  ( >R )
435FBC   E8 EB 38 FD FF                                     call        $4098AC  ( DUP )
435FC1   48 B8 18 00 00 00 00 00 00 00                      mov rax,$18
435FCB   E8 B4 49 FD FF                                     call        $40A984  ( RP@ )
435FD0   E8 6D 47 FD FF                                     call        $40A742  ( + )
435FD5   E8 A0 3B FD FF                                     call        $409B7A  ( @ )
435FDA   E8 CD 38 FD FF                                     call        $4098AC  ( DUP )
435FDF   48 B8 28 00 00 00 00 00 00 00                      mov rax,$28
435FE9   E8 96 49 FD FF                                     call        $40A984  ( RP@ )
435FEE   E8 4F 47 FD FF                                     call        $40A742  ( + )
435FF3   E8 82 3B FD FF                                     call        $409B7A  ( @ )
435FF8   E8 45 47 FD FF                                     call        $40A742  ( + )
435FFD   E8 AA 38 FD FF                                     call        $4098AC  ( DUP )
436002   E8 A5 38 FD FF                                     call        $4098AC  ( DUP )
436007   48 B8 38 00 00 00 00 00 00 00                      mov rax,$38
436011   E8 6E 49 FD FF                                     call        $40A984  ( RP@ )
436016   E8 27 47 FD FF                                     call        $40A742  ( + )
43601B   E8 3A 3C FD FF                                     call        $409C5A  ( ! )
436020   E8 BC 5C FD FF                                     call        $40BCE1  ( ALLOCATE )
436025   E8 94 E7 FC FF                                     call        $4047BE  ( THROW )
43602A   E8 7D 38 FD FF                                     call        $4098AC  ( DUP )
43602F   48 B8 30 00 00 00 00 00 00 00                      mov rax,$30
436039   E8 46 49 FD FF                                     call        $40A984  ( RP@ )
43603E   E8 FF 46 FD FF                                     call        $40A742  ( + )
436043   E8 12 3C FD FF                                     call        $409C5A  ( ! )
436048   E8 5F 38 FD FF                                     call        $4098AC  ( DUP )
43604D   48 B8 10 00 00 00 00 00 00 00                      mov rax,$10
436057   E8 28 49 FD FF                                     call        $40A984  ( RP@ )
43605C   E8 E1 46 FD FF                                     call        $40A742  ( + )
436061   E8 14 3B FD FF                                     call        $409B7A  ( @ )
436066   E8 41 38 FD FF                                     call        $4098AC  ( DUP )
43606B   48 B8 30 00 00 00 00 00 00 00                      mov rax,$30
436075   E8 0A 49 FD FF                                     call        $40A984  ( RP@ )
43607A   E8 C3 46 FD FF                                     call        $40A742  ( + )
43607F   E8 F6 3A FD FF                                     call        $409B7A  ( @ )
436084   E8 23 38 FD FF                                     call        $4098AC  ( DUP )
436089   48 B8 18 00 00 00 00 00 00 00                      mov rax,$18
436093   E8 EC 48 FD FF                                     call        $40A984  ( RP@ )
436098   E8 A5 46 FD FF                                     call        $40A742  ( + )
43609D   E8 D8 3A FD FF                                     call        $409B7A  ( @ )
4360A2   E8 96 2F FD FF                                     call        $40903D  ( MOVE )
4360A7   E8 00 38 FD FF                                     call        $4098AC  ( DUP )
4360AC   48 B8 20 00 00 00 00 00 00 00                      mov rax,$20
4360B6   E8 C9 48 FD FF                                     call        $40A984  ( RP@ )
4360BB   E8 82 46 FD FF                                     call        $40A742  ( + )
4360C0   E8 B5 3A FD FF                                     call        $409B7A  ( @ )
4360C5   E8 E2 37 FD FF                                     call        $4098AC  ( DUP )
4360CA   48 B8 30 00 00 00 00 00 00 00                      mov rax,$30
4360D4   E8 AB 48 FD FF                                     call        $40A984  ( RP@ )
4360D9   E8 64 46 FD FF                                     call        $40A742  ( + )
4360DE   E8 97 3A FD FF                                     call        $409B7A  ( @ )
4360E3   E8 C4 37 FD FF                                     call        $4098AC  ( DUP )
4360E8   48 B8 18 00 00 00 00 00 00 00                      mov rax,$18
4360F2   E8 8D 48 FD FF                                     call        $40A984  ( RP@ )
4360F7   E8 46 46 FD FF                                     call        $40A742  ( + )
4360FC   E8 79 3A FD FF                                     call        $409B7A  ( @ )
436101   E8 3C 46 FD FF                                     call        $40A742  ( + )
436106   E8 A1 37 FD FF                                     call        $4098AC  ( DUP )
43610B   48 B8 28 00 00 00 00 00 00 00                      mov rax,$28
436115   E8 6A 48 FD FF                                     call        $40A984  ( RP@ )
43611A   E8 23 46 FD FF                                     call        $40A742  ( + )
43611F   E8 56 3A FD FF                                     call        $409B7A  ( @ )
436124   E8 14 2F FD FF                                     call        $40903D  ( MOVE )
436129   E8 7E 37 FD FF                                     call        $4098AC  ( DUP )
43612E   48 B8 30 00 00 00 00 00 00 00                      mov rax,$30
436138   E8 47 48 FD FF                                     call        $40A984  ( RP@ )
43613D   E8 00 46 FD FF                                     call        $40A742  ( + )
436142   E8 33 3A FD FF                                     call        $409B7A  ( @ )
436147   E8 60 37 FD FF                                     call        $4098AC  ( DUP )
43614C   48 B8 38 00 00 00 00 00 00 00                      mov rax,$38
436156   E8 29 48 FD FF                                     call        $40A984  ( RP@ )
43615B   E8 E2 45 FD FF                                     call        $40A742  ( + )
436160   E8 15 3A FD FF                                     call        $409B7A  ( @ )
436165   C3                                                 ret
END-CODE
( 526 bytes, 89 instructions )

123 abc

CODE s+
436190   48 8B 4D 08                                        mov rcx,$08[rbp]
436194   48 89 45 F8                                        mov -$08[rbp],rax
436198   48 89 4D F0                                        mov -$10[rbp],rcx
43619C   48 8D 6D F0                                        lea rbp,-$10[rbp]
4361A0   E8 9D 45 FD FF                                     call        $40A742  ( + )
4361A5   E8 37 5B FD FF                                     call        $40BCE1  ( ALLOCATE )
4361AA   E8 0F E6 FC FF                                     call        $4047BE  ( THROW )
4361AF   48 8B 5D 18                                        mov rbx,$18[rbp]
4361B3   48 89 45 F8                                        mov -$08[rbp],rax
4361B7   48 89 45 E8                                        mov -$18[rbp],rax
4361BB   48 8B 45 10                                        mov rax,$10[rbp]
4361BF   48 89 5D F0                                        mov -$10[rbp],rbx
4361C3   48 8D 6D E8                                        lea rbp,-$18[rbp]
4361C7   E8 71 2E FD FF                                     call        $40903D  ( MOVE )
4361CC   48 8B 55 08                                        mov rdx,$08[rbp]
4361D0   48 8B 75 00                                        mov rsi,$00[rbp]
4361D4   48 89 45 18                                        mov $18[rbp],rax
4361D8   48 89 45 F0                                        mov -$10[rbp],rax
4361DC   48 8B 45 10                                        mov rax,$10[rbp]
4361E0   48 89 75 08                                        mov $08[rbp],rsi
4361E4   48 89 55 00                                        mov $00[rbp],rdx
4361E8   48 89 75 F8                                        mov -$08[rbp],rsi
4361EC   48 8D 6D F0                                        lea rbp,-$10[rbp]
4361F0   E8 4D 45 FD FF                                     call        $40A742  ( + )
4361F5   48 8B 5D 00                                        mov rbx,$00[rbp]
4361F9   48 89 45 00                                        mov $00[rbp],rax
4361FD   48 8B C3                                           mov rax,rbx
436200   E8 38 2E FD FF                                     call        $40903D  ( MOVE )
436205   E8 38 45 FD FF                                     call        $40A742  ( + )
43620A   C3                                                 ret
END-CODE
( 123 bytes, 30 instructions )

123 abc

PS.
Оптимизация происходит как по объему кода так и по времени выполнения.
Здесь используются две формы записи:
Основная, например 5|5243452 ( 1 2 3 4 5 --> 5 2 4 3 4 5 2 )
Сокращенная 4$24 ( соответствует 4|123424 в основной форме )

_________________
С уважением, chess


Вернуться к началу
 Профиль Отправить личное сообщение  
Ответить с цитатой  
 Заголовок сообщения: Re: Еще один способ работы с параметрами на стеке
СообщениеДобавлено: Пн май 30, 2022 10:04 
Не в сети
Аватара пользователя

Зарегистрирован: Чт июл 20, 2006 11:31
Сообщения: 2157
Откуда: Екб
Благодарил (а): 0 раз.
Поблагодарили: 41 раз.
Ввел для Win64FasmForth концепцию NOTFOUND - использование информации заложенной в самом имени слов для
формирования кода слов.
Попробовал ввести локальное именование слов с использованием NOTFOUND, получилось.
Попутно ввел макросы и локально-именованные макросы.
Код:
REQUIRE { ~mak\locals.f           \ locals
\ сокращения
: I: : IMMEDIATE ;
I: ` [COMPILE] POSTPONE ;
: d. DUP . ;  : h. HEX d. DECIMAL ;
: .s CR .S S0 @ SP! ;

: nfd ( a u -- )  ?SLITERAL ;
: interpret_ \ -> \ меняем интерпретатор под nfd
  BEGIN
    PARSE-NAME DUP
  WHILE
    SFIND ?DUP
    IF   STATE @ = IF COMPILE, ELSE EXECUTE THEN
    ELSE S" nfd" SFIND IF  EXECUTE ELSE  2DROP ?SLITERAL THEN
    THEN
    ?STACK
  REPEAT 2DROP
;
' interpret_ &INTERPRET !

0 WARNING !
: nfd { a u } \ пребразователь символов 'c' 'cc' в число
a C@ [CHAR] ' = a u + 1- C@ [CHAR] ' = AND u 3 = u 4 = OR AND 0=
IF a u nfd EXIT THEN
u 3 = IF a 1+ C@ ELSE a 2+ C@ 8 LSHIFT a 1+ C@ OR THEN
STATE @ IF LIT, THEN ;

\ макросы
: LOAD-LEX ( A U -- ) DP @ SWAP DUP ALLOT MOVE 0 C,  ;
: load-str ( -- a u )
  5 ALLOT DP @ >R
  BEGIN NextWord ( -- a u )
  2DUP  1 =   \ a u a f
        IF C@ DUP ';' = SWAP DUP '"' = SWAP ']' = OR  OR \ a u f
             IF   2DROP 1
             ELSE OVER C@ '\' =
                  IF   DROP 0xD PARSE DROP OVER - ERASE  \ a a1 a
                  ELSE LOAD-LEX THEN 0
             THEN
        ELSE DROP DUP 0=
             IF 2DROP REFILL DROP ELSE LOAD-LEX THEN 0
        THEN
  UNTIL
  DP @ R@ 5 - DP ! 0xE9 C, DUP R@ - W,
  DUP DP ! R@ SWAP R> - 1-
;
: LOAD-STR  ( a u -- )  load-str  DLIT,
;
\ Макросы многострочные - допускают комментарии вида \ .....
: M: ( name "text ;"  ) : IMMEDIATE LOAD-STR ` EVALUATE POSTPONE ; ;

\ локально-именованные: слова, макросы, переменные, массивы ( упрощенная концепция МОДУЛЕЙ )
CREATE LCODE 0xC000 ALLOT LCODE VALUE DPL     \ область памяти для кода слов с локальными именами
CREATE LDATA 0xC000 ALLOT LDATA VALUE LDHERE  \ область памяти для локально-именованных переменных и массивов
0 VALUE XHERE  VARIABLE XDPL                  \ переменные сохранения указателей компиляции

\ область памяти для локальных имен и их адресов
0x800 CONSTANT LENLVOC     \ длина словаря
CREATE ALVOC LENLVOC ALLOT  BL ALVOC C!
1 VALUE LHERE

: LVOC ( -- A LEN )  ALVOC LENLVOC ; LVOC BL FILL

\ формирование локального имени ( после последнего символа имени идет символ пробела )
: lname, \ a u -- axt
  TUCK LHERE SWAP MOVE             \ лексему в LVOC
  LHERE + DUP BL SWAP C!           \ после лексемы записали BL
  1+ DUP TO LHERE                  \ установить указатель в LVOC после байта BL после лексемы - туда запишем XT кода для лексемы-имени
;
: L{  DPL XDPL ! HERE TO XHERE  DPL DP ! ;                  \ переключение на компиляцию в область LCODE
: }L  DPL HERE XDPL @ - + TO DPL XHERE DP ! ;               \ переключение на компиляцию в область CODE

: init-lvoc  LVOC BL FILL LVOC DROP 1+ TO LHERE ;           \ стирание локального словаря в части локальных имен, код лок. слов не удаляется
: headl ( a u --  ) lname, DPL SWAP ! LHERE 5 + TO LHERE ;

M: nf1-exit { a u s } \ -- a u
a u + 1- C@ s <> IF a u nfd EXIT THEN a u ;
VARIABLE iol 0 iol !     \ направление ввода-вывода в locname-переменные типа value

\ начало формирования кода с локальным именем
: nfd ( a u -- )
'('  nf1-exit 1- headl L{  ;

\ окончание формирования кода с локальным именем
I: )  RET,  }L  ;

\ локально-именованные строки
: nfd  ( a u -- )
  '"' nf1-exit 1- headl L{ LOAD-STR RET, }L ;             \ name" текст строки "

\ локально-именованные макросы
: nfd  ( a u -- )
  '[' nf1-exit 1- headl L{ LOAD-STR ` EVALUATE RET, }L ;  \ name[ текст макроса ]

\ склеивание определений - локальный словарь не удаляется, слово определенное по +: добавляется в основной словарь
: +: : ;
: : init-lvoc : ;

\ процедура поиска имени в лок. словаре
: lsearch { a u a1 u1 \ a2 }
  BL a1 u1 + C!  a u a1 u1 1+ SEARCH >R DROP TO a2 R>
  IF a2 u1 TRUE ELSE a u FALSE THEN
;
I: is  1 iol ! ; \ устанавливает режим записи, после исполнения записи устанавливает режим чтения

\ компиляция слов с локальными именами
\ с блокировкой компиляции слов вида Name1...Name9 при совпадению
\ лексем вида '1' ... '9'( числа ) из входного потока c последним символом слов NameN
: nfd { a u }
  a C@ '1' '9' 1+ WITHIN u 1 = AND IF a u nfd EXIT THEN
  LVOC a u lsearch ( a u f )  0=
  IF 2DROP a u nfd EXIT THEN
  + 1+ @ iol @ IF 19 + 0 iol ! THEN COMPILE,
;
\ локально-именованные переменые
: nfd ( a u --  ) \ типа value
  '!' nf1-exit 1- headl LDHERE LIT, ` !
  L{ LDHERE LIT, ` @ RET, LDHERE LIT, ` ! RET, LDHERE 1 CELLS + TO LDHERE }L
;
\ локально-именованные статические массивы
: nfd ( a u --  ) \ размер задается числовым литералом  [ 20 ] arr]
  ']' nf1-exit 1- headl
  L{ LDHERE LIT, RET, LDHERE + TO LDHERE }L
;
\ исполнить слово или комбинатор независимо от STATE и от флага IMMEDIATE
: nfd { a u }
  a u + 1- C@ '`' = u 1 > AND 0= IF a u nfd EXIT THEN
  LVOC a u 1- lsearch \ для локальных слов, определенных с использованием IMMEDIATE слов
  IF   + 1+ @ EXECUTE
  ELSE a u 1- TYPE SPACE ." not found " CR
  THEN
;


Примеры:
Код:
: S+ \ a1 u1 a2 u2
     u2! a2! u1! a1!
     u1 u2 + DUP u! ALLOCATE THROW a!
     a1 a u1      MOVE
     a2 a u1 + u2 MOVE
     a u
;
SEE S+
S" 123"  S" abcd" S+ CR TYPE

: type-str
  str" 123456789ABCDEF "
  aDO[ OVER + SWAP DO ]
  str aDO` I C@ . LOOP
;
SEE type-str
CR type-str

Код:
CODE S+
439528   E8 7F 03 FD FF                                     call        $4098AC  ( DUP )
43952D   48 B8 B5 B9 42 00 00 00 00 00                      mov rax,$42B9B5
439537   E8 1E 07 FD FF                                     call        $409C5A  ( ! )
43953C   E8 6B 03 FD FF                                     call        $4098AC  ( DUP )
439541   48 B8 BD B9 42 00 00 00 00 00                      mov rax,$42B9BD
43954B   E8 0A 07 FD FF                                     call        $409C5A  ( ! )
439550   E8 57 03 FD FF                                     call        $4098AC  ( DUP )
439555   48 B8 C5 B9 42 00 00 00 00 00                      mov rax,$42B9C5
43955F   E8 F6 06 FD FF                                     call        $409C5A  ( ! )
439564   E8 43 03 FD FF                                     call        $4098AC  ( DUP )
439569   48 B8 CD B9 42 00 00 00 00 00                      mov rax,$42B9CD
439573   E8 E2 06 FD FF                                     call        $409C5A  ( ! )
439578   E8 1C 64 FE FF                                     call        $41F999  ( LCODE+59  )
43957D   E8 C3 63 FE FF                                     call        $41F945  ( LCODE+5  )
439582   E8 BB 11 FD FF                                     call        $40A742  ( + )
439587   E8 20 03 FD FF                                     call        $4098AC  ( DUP )
43958C   E8 1B 03 FD FF                                     call        $4098AC  ( DUP )
439591   48 B8 D5 B9 42 00 00 00 00 00                      mov rax,$42B9D5
43959B   E8 BA 06 FD FF                                     call        $409C5A  ( ! )
4395A0   E8 3C 27 FD FF                                     call        $40BCE1  ( ALLOCATE )
4395A5   E8 14 B2 FC FF                                     call        $4047BE  ( THROW )
4395AA   E8 FD 02 FD FF                                     call        $4098AC  ( DUP )
4395AF   48 B8 DD B9 42 00 00 00 00 00                      mov rax,$42B9DD
4395B9   E8 9C 06 FD FF                                     call        $409C5A  ( ! )
4395BE   E8 00 64 FE FF                                     call        $41F9C3  ( LCODE+83  )
4395C3   E8 4F 64 FE FF                                     call        $41FA17  ( LCODE+D7  )
4395C8   E8 CC 63 FE FF                                     call        $41F999  ( LCODE+59  )
4395CD   E8 6B FA FC FF                                     call        $40903D  ( MOVE )
4395D2   E8 98 63 FE FF                                     call        $41F96F  ( LCODE+2F  )
4395D7   E8 3B 64 FE FF                                     call        $41FA17  ( LCODE+D7  )
4395DC   E8 B8 63 FE FF                                     call        $41F999  ( LCODE+59  )
4395E1   E8 5C 11 FD FF                                     call        $40A742  ( + )
4395E6   E8 5A 63 FE FF                                     call        $41F945  ( LCODE+5  )
4395EB   E8 4D FA FC FF                                     call        $40903D  ( MOVE )
4395F0   E8 22 64 FE FF                                     call        $41FA17  ( LCODE+D7  )
4395F5   E8 F3 63 FE FF                                     call        $41F9ED  ( LCODE+AD  )
4395FA   C3                                                 ret
END-CODE
( 211 bytes, 37 instructions )


123abcd

CODE type-str
439628   E8 14 64 FE FF                                     call        $41FA41  ( LCODE+101  )
43962D   E8 23 03 FD FF                                     call        $409955  ( OVER )
439632   E8 0B 11 FD FF                                     call        $40A742  ( + )
439637   E8 E9 02 FD FF                                     call        $409925  ( SWAP )
43963C   E8 D3 16 FD FF                                     call        $40AD14  ( XDO )
439641   68 61 96 43 00                                     push        $439661
439646   52                                                 push        edx
439647   53                                                 push        ebx
439648   E8 05 16 FD FF                                     call        $40AC52  ( I )
43964D   E8 69 05 FD FF                                     call        $409BBB  ( C@ )
439652   E8 93 A9 FC FF                                     call        $403FEA  ( . )
439657   FF 04 24                                           inc dword PTR [esp]
43965A   71 EC                                              jNo $439648
43965C   48 8D 64 24 18                                     lea rsp,$18[rsp]
439661   C3                                                 ret
END-CODE
( 58 bytes, 15 instructions )


49 50 51 52 53 54 55 56 57 65 66 67 68 69 70

Внутренности locname слова str
Код:
$41FA41 see

CODE call 41FA41
41FA41   E9 10 00 00 00                                     jmp $41FA56  ( LCODE+116  )
41FA46   31 32 33 34  35 36 37 38  39 41 42 43  44 45 46 00 123456789ABCDEF.
41FA56   E8 51 9E FE FF                                     call        $4098AC  ( DUP )
41FA5B   48 B8 46 FA 41 00 00 00 00 00                      mov rax,$41FA46
41FA65   E8 42 9E FE FF                                     call        $4098AC  ( DUP )
41FA6A   48 B8 0F 00 00 00 00 00 00 00                      mov rax,$F
41FA74   C3                                                 ret
END-CODE
( 52 bytes, 6 instructions )

_________________
С уважением, chess


Вернуться к началу
 Профиль Отправить личное сообщение  
Ответить с цитатой  
 Заголовок сообщения: Re: Еще один способ работы с параметрами на стеке
СообщениеДобавлено: Вс июн 05, 2022 23:33 
Не в сети
Аватара пользователя

Зарегистрирован: Чт июл 20, 2006 11:31
Сообщения: 2157
Откуда: Екб
Благодарил (а): 0 раз.
Поблагодарили: 41 раз.
Реализовал измеритель времени однократного исполнения отдельных слов для WinFAsmForth64,
сначала пишем на fasm в ядро форт-системы:
Код:
cfa_AHEADER 0,'xmeter',xmeter
    movd xmm0, eax
    xor   eax, eax
    cpuid
    rdtsc
    movd xmm1, eax
    movd  ebx, xmm0
    call  rbx
    xor   eax, eax
    cpuid
    rdtsc
    movd  ecx, xmm1
    sub   eax, ecx
    movd xmm2, eax
    xor   eax, eax
    cpuid
    rdtsc
    movd xmm1, eax
    movd  ebx, xmm0
    xor   eax, eax
    cpuid
    rdtsc
    movd  ecx, xmm1
    sub   eax, ecx
    mov   ebx, eax
    movd  eax, xmm2
    sub   eax, ebx
ret

потом дописываем в уже сформированной форт-системе:
Код:
: dT (  "name" --  )
  ' xmeter  CR NIP . ." ticks "  CR S0 @ SP! ;

использование:
Код:
dT DROP

результат:
Код:
81 ticks

_________________
С уважением, chess


Вернуться к началу
 Профиль Отправить личное сообщение  
Ответить с цитатой  
Показать сообщения за:  Поле сортировки  
Начать новую тему Ответить на тему  [ Сообщений: 49 ]  На страницу Пред.  1, 2, 3, 4

Часовой пояс: UTC + 3 часа [ Летнее время ]


Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 20


Вы не можете начинать темы
Вы можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
phpBB сборка от FladeX // Русская поддержка phpBB