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

...
Google Search
Forth-FAQ Spy Grafic

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




Ответить
Имя пользователя:
Заголовок:
Текст сообщения:
Введите текст вашего сообщения. Длина сообщения в символах не более: 60000

Размер шрифта:
Цвет шрифта
Настройки:
BBCode ВКЛЮЧЕН
[img] ВЫКЛЮЧЕН
[flash] ВЫКЛЮЧЕН
[url] ВКЛЮЧЕН
Смайлики ВЫКЛЮЧЕНЫ
Отключить в этом сообщении BBCode
Не преобразовывать адреса URL в ссылки
Вопрос
Теперь гостю придется вводить здесь пароль. Не от своей учетной записи, а ПАРОЛЬ ДЛЯ ГОСТЯ, получить который можно после регистрации на форуме через ЛС.:
Этот вопрос предназначен для выявления и предотвращения автоматических регистраций.
   

Обзор темы - Еще один способ работы с параметрами на стеке
Автор Сообщение
  Заголовок сообщения:  Re: Еще один способ работы с параметрами на стеке  Ответить с цитатой
Реализовал измеритель времени однократного исполнения отдельных слов для 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
Сообщение Добавлено: Вс июн 05, 2022 23:33
  Заголовок сообщения:  Re: Еще один способ работы с параметрами на стеке  Ответить с цитатой
Ввел для 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 )
Сообщение Добавлено: Пн май 30, 2022 10:04
  Заголовок сообщения:  Re: Еще один способ работы с параметрами на стеке  Ответить с цитатой
Вариант реализации локальных переменных без использования хипа и стека возвратов
с использованием только стека параметров на основе выражений типа стексов.
Этот вариант вполне подошел также и для 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 в основной форме )
Сообщение Добавлено: Ср май 18, 2022 22:21
  Заголовок сообщения:  Re: Еще один способ работы с параметрами на стеке  Ответить с цитатой
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. С Новым Годом!
Сообщение Добавлено: Сб янв 01, 2022 17:29
  Заголовок сообщения:  Re: Еще один способ работы с параметрами на стеке  Ответить с цитатой
Как понимаю, Вы закидываете часть переменных выше вершины стека.
Но как происходит контроль измерения глубины?
При изменении этого самого стека?
Сообщение Добавлено: Вт май 18, 2021 14:15
  Заголовок сообщения:  Re: Еще один способ работы с параметрами на стеке  Ответить с цитатой
Использовал доп. словарь.
Вход в словарь (не_Forth) с помощью другой формы
определения слова через двоеточие.
Выход в словарь Forth по закрывающему символу ';',
переопределенному в словаре не_Forth.
Словарь поэтому практически не отсвечивает.

Код:
S+: | a1 u1 a2 u2 |
u1 u2 + DUP ALLOC | u a |
a1 a u1      MOVE
a2 a u1 + u2 MOVE
TO a1 nNIP u1
;
SEE S+
CR  S" alfa ." S" .. omega" s+  TYPE

: 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+
CR  S" alfa ." S" .. omega" s+  TYPE

лог
Код:
CODE S+
620577 8945FC           MOV     FC [EBP] , EAX
62057A 034504           ADD     EAX , 4 [EBP]
62057D 8D6DFC           LEA     EBP , FC [EBP]
620580 8945FC           MOV     FC [EBP] , EAX
620583 8D6DFC           LEA     EBP , FC [EBP]
620586 E8AC4DFFFF       CALL    615337  ( hAlloc )
62058B 8945FC           MOV     FC [EBP] , EAX
62058E 8B4510           MOV     EAX , 10 [EBP]
620591 8945F8           MOV     F8 [EBP] , EAX
620594 8B45FC           MOV     EAX , FC [EBP]
620597 8945F4           MOV     F4 [EBP] , EAX
62059A 8B450C           MOV     EAX , C [EBP]
62059D 8D6DF4           LEA     EBP , F4 [EBP]
6205A0 E8DF37F3FF       CALL    553D84  ( MOVE )
6205A5 8945FC           MOV     FC [EBP] , EAX
6205A8 8B4508           MOV     EAX , 8 [EBP]
6205AB 8945F8           MOV     F8 [EBP] , EAX
6205AE 8B45FC           MOV     EAX , FC [EBP]
6205B1 8D6DF8           LEA     EBP , F8 [EBP]
6205B4 034514           ADD     EAX , 14 [EBP]
6205B7 8945FC           MOV     FC [EBP] , EAX
6205BA 8B450C           MOV     EAX , C [EBP]
6205BD 8D6DFC           LEA     EBP , FC [EBP]
6205C0 E8BF37F3FF       CALL    553D84  ( MOVE )
6205C5 894510           MOV     10 [EBP] , EAX
6205C8 8B4500           MOV     EAX , 0 [EBP]
6205CB 8D6D10           LEA     EBP , 10 [EBP]
6205CE C3               RET     NEAR
END-CODE
( 88 bytes, 28 instructions )

alfa ... omega

CODE s+
6205DF 8945FC           MOV     FC [EBP] , EAX
6205E2 B810000000       MOV     EAX , # 10
6205E7 8D6DFC           LEA     EBP , FC [EBP]
6205EA E8F92AF3FF       CALL    5530E8  ( DRMOVE )
6205EF 8945FC           MOV     FC [EBP] , EAX
6205F2 B802000000       MOV     EAX , # 2
6205F7 8D6DFC           LEA     EBP , FC [EBP]
6205FA E8252CF3FF       CALL    553224  ( (RALLOT) )
6205FF 6818000000       PUSH    , # 18
620604 686C325500       PUSH    , # 55326C
620609 8945FC           MOV     FC [EBP] , EAX
62060C 8B442418         MOV     EAX , 18 [ESP]
620610 03442410         ADD     EAX , 10 [ESP]
620614 8945F8           MOV     F8 [EBP] , EAX
620617 89442408         MOV     8 [ESP] , EAX
62061B 8B45F8           MOV     EAX , F8 [EBP]
62061E 8D6DFC           LEA     EBP , FC [EBP]
620621 E87649F3FF       CALL    554F9C  ( ALLOCATE )
620626 E8894AF3FF       CALL    5550B4  ( THROW )
62062B 8944240C         MOV     C [ESP] , EAX
62062F 8B44241C         MOV     EAX , 1C [ESP]
620633 8945FC           MOV     FC [EBP] , EAX
620636 8B44240C         MOV     EAX , C [ESP]
62063A 8945F8           MOV     F8 [EBP] , EAX
62063D 8B442418         MOV     EAX , 18 [ESP]
620641 8D6DF8           LEA     EBP , F8 [EBP]
620644 E83B37F3FF       CALL    553D84  ( MOVE )
620649 8945FC           MOV     FC [EBP] , EAX
62064C 8B442414         MOV     EAX , 14 [ESP]
620650 8945F8           MOV     F8 [EBP] , EAX
620653 8B44240C         MOV     EAX , C [ESP]
620657 03442418         ADD     EAX , 18 [ESP]
62065B 8945F4           MOV     F4 [EBP] , EAX
62065E 8B442410         MOV     EAX , 10 [ESP]
620662 8D6DF4           LEA     EBP , F4 [EBP]
620665 E81A37F3FF       CALL    553D84  ( MOVE )
62066A 8945FC           MOV     FC [EBP] , EAX
62066D 8B44240C         MOV     EAX , C [ESP]
620671 8945F8           MOV     F8 [EBP] , EAX
620674 8B442408         MOV     EAX , 8 [ESP]
620678 8D6DF8           LEA     EBP , F8 [EBP]
62067B C3               RET     NEAR
END-CODE
( 157 bytes, 42 instructions )

alfa ... omega


Ps. Увеличив число команд виртуальной форт-машины,
и поддержав прозрачный синтаксис локальных переменных
( на самом деле использование стека в стандартном Форте
это и есть оперирование локальными переменными пусть и
неявно заданными) можно получить эффективность кода
не хуже чем у форта с оптимизатором, при этом практически
исключив инструментальный динамический контекст.
Сообщение Добавлено: Сб май 15, 2021 23:53
  Заголовок сообщения:  Re: Еще один способ работы с параметрами на стеке  Ответить с цитатой
Наращивание возможностей транспилятора с параллельным изменением синтаксиса
Код:
\ Конкатенация строк в хипе
: S+ | a1 u1 a2 u2 |
u1 u2 s+ dup halloc | us as |
a1 as u1       move
a2 as u1 s+ u2 move
IS a1 nNIP u1
;
SEE S+
CR  S" 12 " S" ab" S+  TYPE


ЛОГ
Код:
[424+dh162V362+4V:1'N2  \ выражение S+ на первичном языке
b  2Ooo  3o 2 O1o: N

CODE S+
62072F 8945FC           MOV     FC [EBP] , EAX
620732 034504           ADD     EAX , 4 [EBP]
620735 8D6DFC           LEA     EBP , FC [EBP]
620738 8945FC           MOV     FC [EBP] , EAX
62073B 8D6DFC           LEA     EBP , FC [EBP]
62073E E8A84CFFFF       CALL    6153EB  ( hAlloc )
620743 8945FC           MOV     FC [EBP] , EAX
620746 8B4510           MOV     EAX , 10 [EBP]
620749 8945F8           MOV     F8 [EBP] , EAX
62074C 8B45FC           MOV     EAX , FC [EBP]
62074F 8945F4           MOV     F4 [EBP] , EAX
620752 8B450C           MOV     EAX , C [EBP]
620755 8D6DF4           LEA     EBP , F4 [EBP]
620758 E82736F3FF       CALL    553D84  ( MOVE )
62075D 8945FC           MOV     FC [EBP] , EAX
620760 8B4508           MOV     EAX , 8 [EBP]
620763 8945F8           MOV     F8 [EBP] , EAX
620766 8B45FC           MOV     EAX , FC [EBP]
620769 8D6DF8           LEA     EBP , F8 [EBP]
62076C 034514           ADD     EAX , 14 [EBP]
62076F 8945FC           MOV     FC [EBP] , EAX
620772 8B450C           MOV     EAX , C [EBP]
620775 8D6DFC           LEA     EBP , FC [EBP]
620778 E80736F3FF       CALL    553D84  ( MOVE )
62077D 894510           MOV     10 [EBP] , EAX
620780 8B4500           MOV     EAX , 0 [EBP]
620783 8D6D10           LEA     EBP , 10 [EBP]
620786 C3               RET     NEAR
END-CODE
( 88 bytes, 28 instructions )

12 ab

PS. В основном процесс транспиляции освоен, остались экстенсивные дополнения.
Сообщение Добавлено: Чт май 13, 2021 00:58
  Заголовок сообщения:  Re: Еще один способ работы с параметрами на стеке  Ответить с цитатой
Версия простейшего транспилятора
Код:
CREATE VocPar 2000 ALLOT  0 VALUE dvp \ словарь имен параметров
CREATE StrOut 1000 ALLOT  0 VALUE dso \ выходная строка на первичном языке

I: [[  { \ cw a u  }
BEGIN NextWord 2DUP TO u TO a S" ]]" COMPARE
  IF   a VocPar dvp + u MOVE
       dvp u + 1+ TO dvp
       cw 1+ TO cw
       cw '0' + VocPar dvp + C!
       dvp 2+ TO dvp 0
  ELSE 1 THEN
UNTIL
S" /[" StrOut SWAP MOVE
cw '0' +  StrOut 2 + C!
dso 3 + TO dso
;
: NOTFOUND { a u }
VocPar 2000 a u SEARCH
IF DROP u + 1+ C@ StrOut dso + C! dso 1+ TO dso
ELSE 2DROP a u NOTFOUND EXIT THEN
;
I: em  StrOut dso EVALUATE
;
I: m; ` em StrOut 1000 ERASE  ` ;
;

Проверка
Код:
: s1  /[4321441 ;
SEE s1
11 22 33 44 t[ s1 ]t
: s2 [[ a1 u1 a2 u2 ]]
a2 u1 a1 u2 u2 a1
m;
SEE s2
11 22 33 44 t[ s2 ]t


ЛОГ
Код:
[4321441
b      6

CODE s1
6201B7 8945FC           MOV     FC [EBP] , EAX
6201BA 8B4500           MOV     EAX , 0 [EBP]
6201BD 8945F8           MOV     F8 [EBP] , EAX
6201C0 8B4504           MOV     EAX , 4 [EBP]
6201C3 8945F4           MOV     F4 [EBP] , EAX
6201C6 8B4508           MOV     EAX , 8 [EBP]
6201C9 8945F0           MOV     F0 [EBP] , EAX
6201CC 8B45FC           MOV     EAX , FC [EBP]
6201CF 8945EC           MOV     EC [EBP] , EAX
6201D2 8B45FC           MOV     EAX , FC [EBP]
6201D5 8945E8           MOV     E8 [EBP] , EAX
6201D8 8B4508           MOV     EAX , 8 [EBP]
6201DB 8D6DE8           LEA     EBP , E8 [EBP]
6201DE C3               RET     NEAR
END-CODE
( 40 bytes, 14 instructions )

11 22 33 44
11 22 33 44 33 22 11 44 44 11

[4321441
b      6

CODE s2
6201EF 8945FC           MOV     FC [EBP] , EAX
6201F2 8B4500           MOV     EAX , 0 [EBP]
6201F5 8945F8           MOV     F8 [EBP] , EAX
6201F8 8B4504           MOV     EAX , 4 [EBP]
6201FB 8945F4           MOV     F4 [EBP] , EAX
6201FE 8B4508           MOV     EAX , 8 [EBP]
620201 8945F0           MOV     F0 [EBP] , EAX
620204 8B45FC           MOV     EAX , FC [EBP]
620207 8945EC           MOV     EC [EBP] , EAX
62020A 8B45FC           MOV     EAX , FC [EBP]
62020D 8945E8           MOV     E8 [EBP] , EAX
620210 8B4508           MOV     EAX , 8 [EBP]
620213 8D6DE8           LEA     EBP , E8 [EBP]
620216 C3               RET     NEAR
END-CODE
( 40 bytes, 14 instructions )

11 22 33 44
11 22 33 44 33 22 11 44 44 11

PS. 100% точный перевод на первичный язык.
Это конечно лишь часть транспилятора.
Сообщение Добавлено: Ср май 12, 2021 01:08
  Заголовок сообщения:  Re: Еще один способ работы с параметрами на стеке  Ответить с цитатой
Ввел операторы между содержимым ячейки и непосредсвенно заданным операндом
Результат всегда помещается в ячейку.
Код:
: t[ CR DEPTH .SN CR ;
: ]t DEPTH .SN stack0 ;
1 TO OTL
: pr1 /[31`2'+ ; SEE pr1  16 2 32 t[ pr1 ]t
: pr2 /[33`2'- ; SEE pr2  16 2 32 t[ pr2 ]t
: pr3 /[31`2'* ; SEE pr3  16 2 32 t[ pr3 ]t
: pr4 /[33`2'/ ; SEE pr4  16 2 32 t[ pr4 ]t
: pr5 /[31`2'% ; SEE pr5  16 2 32 t[ pr5 ]t
: pr6 /[33`2'| ; SEE pr6  16 2 32 t[ pr6 ]t
: pr7 /[31`2'& ; SEE pr7  16 2 32 t[ pr7 ]t
: pr8 /[33`2'^ ; SEE pr8  16 2 32 t[ pr8 ]t
: pr9 /[31`2'M ; SEE pr9  16 2 32 t[ pr9 ]t
: prA /[33`2'm ; SEE prA  16 2 32 t[ prA ]t
: prB /[31`2'l ; SEE prB  16 2 32 t[ prB ]t
: prC /[33`2'r ; SEE prC  16 2 32 t[ prC ]t


ЛОГ.
Код:
[31`2'+
b c_#_o

CODE pr1
61DCD7 83450402         ADD     4 [EBP] , # 2
61DCDB C3               RET     NEAR
END-CODE
( 5 bytes, 2 instructions )

16 2 32
18 2 32

[33`2'-
b c_#_o

CODE pr2
61DCEF 8D40FE           LEA     EAX , FE [EAX]
61DCF2 C3               RET     NEAR
END-CODE
( 4 bytes, 2 instructions )

16 2 32
16 2 30

[31`2'*
b c_#_o

CODE pr3
61DD03 695D0402000000   IMUL    EBX , 4 [EBP] , # 2
61DD0A 895D04           MOV     4 [EBP] , EBX
61DD0D C3               RET     NEAR
END-CODE
( 11 bytes, 3 instructions )

16 2 32
32 2 32

[33`2'/
b c_#_o

CODE pr4
61DD1F C7C102000000     MOV     ECX , # 2
61DD25 99               CDQ
61DD26 F7F9             IDIV    ECX
61DD28 C3               RET     NEAR
END-CODE
( 10 bytes, 4 instructions )

16 2 32
16 2 16

[31`2'%
b c_#_o

CODE pr5
61DD3B 8BD8             MOV     EBX , EAX
61DD3D 8B4504           MOV     EAX , 4 [EBP]
61DD40 C7C102000000     MOV     ECX , # 2
61DD46 99               CDQ
61DD47 F7F9             IDIV    ECX
61DD49 895504           MOV     4 [EBP] , EDX
61DD4C 8BC3             MOV     EAX , EBX
61DD4E C3               RET     NEAR
END-CODE
( 20 bytes, 8 instructions )

16 2 32
0 2 32

[33`2'|
b c_#_o

CODE pr6
61DD5F 81C802000000     OR      EAX , # 2
61DD65 C3               RET     NEAR
END-CODE
( 7 bytes, 2 instructions )

16 2 32
16 2 34

[31`2'&
b c_#_o

CODE pr7
61DD77 81650402000000   AND     4 [EBP] , # 2
61DD7E C3               RET     NEAR
END-CODE
( 8 bytes, 2 instructions )

16 2 32
0 2 32

[33`2'^
b c_#_o

CODE pr8
61DD8F 81F002000000     XOR     EAX , # 2
61DD95 C3               RET     NEAR
END-CODE
( 7 bytes, 2 instructions )

16 2 32
16 2 34

[31`2'M
b c_#_o

CODE pr9
61DDA7 C7C302000000     MOV     EBX , # 2
61DDAD 395D04           CMP     4 [EBP] , EBX
61DDB0 0F4F5D04         CMOVG   EBX , 4 [EBP]
61DDB4 895D04           MOV     4 [EBP] , EBX
61DDB7 C3               RET     NEAR
END-CODE
( 17 bytes, 5 instructions )

16 2 32
16 2 32

[33`2'm
b c_#_o

CODE prA
61DDCB C7C202000000     MOV     EDX , # 2
61DDD1 3BD0             CMP     EDX , EAX
61DDD3 0F4CC2           CMOVL   EAX , EDX
61DDD6 C3               RET     NEAR
END-CODE
( 12 bytes, 4 instructions )

16 2 32
16 2 2

[31`2'l
b c_#_o

CODE prB
61DDE7 C1650402         SHL     4 [EBP] , 2
61DDEB C3               RET     NEAR
END-CODE
( 5 bytes, 2 instructions )

16 2 32
64 2 32

[33`2'r
b c_#_o

CODE prC
61DDFF C1E802           SHR     EAX , 2
61DE02 C3               RET     NEAR
END-CODE
( 4 bytes, 2 instructions )

16 2 32
16 2 8

PS. Кратко пройдусь по всему набору операторов
(с - ячейка, # - непосредственное значение, o - оператор)

с1с2o - результат на вершину стека
с1с2'o - результат в ячейку с1
c#'o - результат в ячейку с
##o - результат на вершину стека
co - результат на вершину стека( оператор между вершиной стека и ячейкой )
o - фортовские операторы
с - содержимое ячейки на стек
с1:c2 - пересылка из ячейки в ячейку
:c - снять со стека в ячейку(':c - скопировать со стека в ячейку)
есть еще операторы укорочения стека nDROP ( ]n ) и nNIP( 'Nn )
Несмотря на введение доп. операторов язык остается по прежнему стековым.
Сообщение Добавлено: Вт май 04, 2021 00:55
  Заголовок сообщения:  Re: Еще один способ работы с параметрами на стеке  Ответить с цитатой
Ввел прямые операции между ячейками стека в общем случае минуя вершину стека.
Форт-операторы идут как их подмножество с более коротким синтаксисом.
Примеры реализации операторов + и - :
Код:
: s. DEPTH .SN stack0 ;
1 TO OTL
: pr1 /[312'+ ; SEE pr1  1 2 3 pr1 s.
: pr2 /[313'+ ; SEE pr2  1 2 3 pr2 s.
: pr3 /[323'+ ; SEE pr3  1 2 3 pr3 s.
: pr4 /[321'+ ; SEE pr4  1 2 3 pr4 s.
: pr5 /[331'+ ; SEE pr5  1 2 3 pr5 s.
: pr6 /[332'+ ; SEE pr6  1 2 3 pr6 s.
: pr7 /[312'- ; SEE pr7  1 2 3 pr7 s.
: pr8 /[313'- ; SEE pr8  1 2 3 pr8 s.
: pr9 /[323'- ; SEE pr9  1 2 3 pr9 s.
: prA /[321'- ; SEE prA  1 2 3 prA s.
: prB /[331'- ; SEE prB  1 2 3 prB s.
: prC /[332'- ; SEE prC  1 2 3 prC s.


ЛОГ.
Код:
[312'+
b cc_o

CODE pr1
60C6BB 8B4D00           MOV     ECX , 0 [EBP]
60C6BE 014D04           ADD     4 [EBP] , ECX
60C6C1 C3               RET     NEAR
END-CODE
( 7 bytes, 3 instructions )
3 2 3

[313'+
b cc_o

CODE pr2
60C6D3 014504           ADD     4 [EBP] , EAX
60C6D6 C3               RET     NEAR
END-CODE
( 4 bytes, 2 instructions )
4 2 3

[323'+
b cc_o

CODE pr3
60C6E7 014500           ADD     0 [EBP] , EAX
60C6EA C3               RET     NEAR
END-CODE
( 4 bytes, 2 instructions )
1 5 3

[321'+
b cc_o

CODE pr4
60C6FB 8B4D04           MOV     ECX , 4 [EBP]
60C6FE 014D00           ADD     0 [EBP] , ECX
60C701 C3               RET     NEAR
END-CODE
( 7 bytes, 3 instructions )
1 3 3

[331'+
b cc_o

CODE pr5
60C713 034504           ADD     EAX , 4 [EBP]
60C716 C3               RET     NEAR
END-CODE
( 4 bytes, 2 instructions )
1 2 4

[332'+
b cc_o

CODE pr6
60C727 034500           ADD     EAX , 0 [EBP]
60C72A C3               RET     NEAR
END-CODE
( 4 bytes, 2 instructions )
1 2 5

[312'-
b cc_o

CODE pr7
60C73B 8B4D00           MOV     ECX , 0 [EBP]
60C73E 294D04           SUB     4 [EBP] , ECX
60C741 C3               RET     NEAR
END-CODE
( 7 bytes, 3 instructions )
4294967295(-1) 2 3

[313'-
b cc_o

CODE pr8
60C753 294504           SUB     4 [EBP] , EAX
60C756 C3               RET     NEAR
END-CODE
( 4 bytes, 2 instructions )
4294967294(-2) 2 3

[323'-
b cc_o

CODE pr9
60C767 294500           SUB     0 [EBP] , EAX
60C76A C3               RET     NEAR
END-CODE
( 4 bytes, 2 instructions )
1 4294967295(-1) 3

[321'-
b cc_o

CODE prA
60C77B 8B4D04           MOV     ECX , 4 [EBP]
60C77E 294D00           SUB     0 [EBP] , ECX
60C781 C3               RET     NEAR
END-CODE
( 7 bytes, 3 instructions )
1 1 3

[331'-
b cc_o

CODE prB
60C793 2B4504           SUB     EAX , 4 [EBP]
60C796 C3               RET     NEAR
END-CODE
( 4 bytes, 2 instructions )
1 2 2

[332'-
b cc_o

CODE prC
60C7A7 2B4500           SUB     EAX , 0 [EBP]
60C7AA C3               RET     NEAR
END-CODE
( 4 bytes, 2 instructions )
1 2 1
Ok

PS. Такие операторы нужны для работы с ячейками стека как с локальными переменными.
Сообщение Добавлено: Пн апр 26, 2021 00:56
  Заголовок сообщения:  Re: Еще один способ работы с параметрами на стеке  Ответить с цитатой
Ввел поддержку операций над непосредственно заданными операндами
Код:
: tst /`5`4*`3-`A*`4/`5+`A* ;
SEE tst
tst
: tst1 5 4 * 3 - 10 * 4 / 5 + 10 *  ;
SEE tst1
tst1

LOG
Код:
CODE tst
60C197 8945FC           MOV     FC [EBP] , EAX
60C19A B8D6010000       MOV     EAX , # 1D6
60C19F 8D6DFC           LEA     EBP , FC [EBP]
60C1A2 C3               RET     NEAR
END-CODE
( 12 bytes, 4 instructions )


CODE tst1
60C1B7 8945FC           MOV     FC [EBP] , EAX
60C1BA B8AA000000       MOV     EAX , # AA
60C1BF B904000000       MOV     ECX , # 4
60C1C4 99               CDQ
60C1C5 F7F9             IDIV    ECX
60C1C7 8D4005           LEA     EAX , 5 [EAX]
60C1CA 69C00A000000     IMUL    EAX , EAX , # A
60C1D0 8D6DFC           LEA     EBP , FC [EBP]
60C1D3 C3               RET     NEAR
END-CODE
( 29 bytes, 9 instructions )

Ok ( 470 470 )

PS Использовал прием модификации исходного текста во время компиляции,
поэтому все вылилось в добавку двух строчек в текст транслятора.
Сообщение Добавлено: Сб апр 17, 2021 16:16
  Заголовок сообщения:  Re: Еще один способ работы с параметрами на стеке  Ответить с цитатой
Ввел слова прямого изменения содержимого ячеек стека.
Как правило такие ячейки используются как счетчики в циклах.
Код:
: d. CR DEPTH .SN S0 @ SP! ;

1 TO OTL \ вкл декомпилятор

\ примеры увеличения-уменьшения содержимого ячеек
: tst /[4"1A'2F"32'41 ; SEE tst
10 20 30 40 tst  d.

: tst1 /[2"13'25* ;  SEE tst1
3 12 tst1 d.

LOG
Код:
[4"1A'2F"32'41   \ (1c + 10) (2c - 15) (3c + 2) (4c - 1)
b +c#-c#+c#-c#

CODE tst
60B133 8345080A         ADD     8 [EBP] , # 10
60B137 836D040F         SUB     4 [EBP] , # 15
60B13B 83450002         ADD     0 [EBP] , # 2
60B13F 8D40FF           LEA     EAX , FF [EAX]
60B142 C3               RET     NEAR
END-CODE
( 16 bytes, 5 instructions )

20 5 32 39

[2"13'25*
b +c#-c#o

CODE tst1
60B153 83450003         ADD     0 [EBP] , # 3
60B157 8D40FB           LEA     EAX , FB [EAX]
60B15A F76D00           IMUL    0 [EBP]
60B15D 8D6D04           LEA     EBP , 4 [EBP]
60B160 C3               RET     NEAR
END-CODE
( 14 bytes, 5 instructions )

42

PS.
Синтаксис на данном этапе может меняться.
В конечном итоге можно написать транспилятор
для более удобного представления таких выражений, например аналогичных SPF-му
виду для локальных переменных, только с возможностью многократного применения
конструкций типа { a b c | d e f ... } и использования имен обычных слов форта.
Сама текущая нотация будет первичным(промежуточным) языком.
Сообщение Добавлено: Чт апр 08, 2021 23:54
  Заголовок сообщения:  Re: Еще один способ работы с параметрами на стеке  Ответить с цитатой
Более сложный случай применения принятой модели вычислений:
определим форму записи чисел с плав. точкой как 3,14159265,
и напишем преобразователь из нее в форму, принятую в SPF.

Код:
\ 12 3456 1-a 2-u 3-sq 4-sz 5-pt 6-an
: NOTFOUND
/[20ddd12+1$Ib(0(:H?'3tIb(-=?I1-:5'4tL
/321b(,-?`it`i=4y=&Z?12`N"1X;t
/2iih:6162V(e62+w(.65+w62iv"1X ;

Проверяем как это работает
Код:
\ длина окружности
: Lkr. ( R -- Lkr) 2,0 /`*`P`*`. ; SEE Lkr.
10,0 Lkr.
\ площадь круга
: Skr. ( R -- Skr) /`d`*`P`*`. ; SEE Skr.
10,0 Skr.

LOG
Код:
CODE Lkr.
60C1AB E8B87AF4FF       CALL    553C68  ( _FLIT-CODE8 )
60C1B0  A;   0 C,  0 C,  0 C,  0 C,  0 C,  0 C,  0 C, 40 C,
60C1B8 DEC9             FMULP   ST(1)
60C1BA D9EB             FLDPI
60C1BC DEC9             FMULP   ST(1)
60C1BE E8DC67FAFF       CALL    5B299F  ( F. )
60C1C3 C3               RET     NEAR
END-CODE
( 25 bytes, 6 instructions )
62,831853

CODE Skr.
60C1D7 D9C0             FLD     ST(0)
60C1D9 DEC9             FMULP   ST(1)
60C1DB D9EB             FLDPI
60C1DD DEC9             FMULP   ST(1)
60C1DF E8BB67FAFF       CALL    5B299F  ( F. )
60C1E4 C3               RET     NEAR
END-CODE
( 14 bytes, 6 instructions )
314,15927
Ok
Сообщение Добавлено: Ср мар 31, 2021 23:39
  Заголовок сообщения:  Re: Еще один способ работы с параметрами на стеке  Ответить с цитатой
Увлекаться сокращением текста сильно не стоит, иначе будут получаться нечитаемые тексты.
Вот пример слова определяющего мин. мах. и сумму байтов в строке.
Код:
: MaxMinSumBytes /[2{1b12GIb}M{Lcys}x1mx2x1+L"1. ;
S" 325435463ehgfdchgGFFGKJH" MaxMinSumBytes

LOG
Код:
h 2 1837
Ok
Сообщение Добавлено: Вт мар 30, 2021 00:50
  Заголовок сообщения:  Re: Еще один способ работы с параметрами на стеке  Ответить с цитатой
О реализация повторного использования кода на примере.
Код:
: example \ a1 (1) u1 (2) a2 (3) u2 (4) --
\   1                2
/[4{24+dh}162V362+4V{65T}x1364V164+2V\x2"1X ;

Выделяем кусок текста скобками { } а затем пишем х1
если повторяем первый выделенный таким образом кусок
Сам выделенный кусок будет исполнятся, а x1 в коде
будет компиляцией выделенного текста в другом месте.
Следующий выделенный кусок обозначается как х2 и тд.
Получается распределенный по коду словарик с именами х1.. хn.
Разница только в том, что код в каждой позиции повторения может быть
для одного выделения разным, так как в общем случае код позиционно зависимый.
Семантика одинакова и соответствует исходному тексту.
Сообщение Добавлено: Пн мар 29, 2021 19:46

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


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