Развитие
мысли про локальные переменные.
~profit/lib/static.f:
Код:
\ Статические переменные, хранящиеся непосредственно в шитом
\ коде определения.
\ В комбинации с словом B! или KEEP (слово LOCAL, см. пример
\ внизу) можно использовать как полностью bac4th-совместимые
\ локальные переменные.
...
\EOF
: previousValue
STATIC a
a @
SWAP a ! ;
REQUIRE SEE lib/ext/disasm.f
SEE previousValue
\ 559330 E904000000 JMP 559339 ( previousValue+9 )
\ 559335 0000 ADD [EAX] , AL
\ 559337 0000 ADD [EAX] , AL
\ 559339 8BD0 MOV EDX , EAX
\ 55933B A135935500 MOV EAX , 559335 ( previousValue+5 )
\ 559340 891535935500 MOV 559335 ( previousValue+5 ) , EDX
\ 559346 C3 RET NEAR
1 previousValue .
2 previousValue .
3 previousValue .
: sum ( a b -- )
STATIC a
STATIC b
a ! b !
a @ b @ +
STATIC c c !
c @ ;
: fact ( n -- n! ) \ Не самый удачный пример, согласен.
DUP 0= IF \ Но тем не менее показывает как сохраняются локальные
DROP 1 ELSE \ значения в статических переменных
LOCAL n
DUP n !
1- RECURSE
n @ * THEN ;
Пока неполностью уверился в применимости такого. Кто меня аргументированой критикой разубедит окончательно -- буду только благодарен.
По реализации:
Можно забивать ячейки не нулями а NOP'ами и выравнивать не ALIGN'ом, а ALIGN-NOP'ом, чтобы дизассемблер не терялся. Но тогда на время исполнения придётся выносить отдельную операцию обнуления или же честно предупреждать что вначале у переменных значение будет дурацкое (четыре байта-NOP'а) и обнулять надо их явно.
Или можно брать ячейки для статических переменных не посреди шитого кода, разрывая его jmp'ом, а после RET'а, но с этим чуть надо посидеть... Тогда и предыдущий вопрос отпадает.