Совместное использование ассемблера и форта при создании форт-определений
Если в текст на форте вставляем законченный фрагмент на ассемблере ничего делать не надо, так как
регистры процессора внутри форт-определений инициируются параметрами либо со стека либо из памяти,
и поэтому их начальные состояния значения не имеют.
В случае же когда алгоритм кодируется на ассемблере и нужно вставить в текст на ассемблере слова на форте
может возникнуть ситуация когда форт-слова портят регистры используемые в последующем тексте на ассемблере.
В этом случае можно использовать команды PUSHAD - сохранение всех регистров в стеке возвратов(содержимое регистров при этом не меняется), а затем после исполнения фрагмента на форте восстановить их командой POPAD.
Например вывод числа с вершины стека без изменения стека будет выглядеть так.
Вообще в последнем посте CHESS'a идет речь об ассемблерных макросах в ЯП ФОРТ.
Вы заблуждаетесь. Речь идет о формировании поля кода форт-слов с помощью ранее определенных форт-слов и машинных команд совместно. Причем эти форт-слова и машинные команды используются на равных основаниях.
Компиляция машинных команд в поле кода определяемого слова происходит не по-фортовски путем компиляции
вызова форт-слова или инлайн-вставки кода этого слова, а путем формирования(генерации) кода машинных команд
в поле кода определяемого слова на основании имен машинных команд(иногда с использованием параметров со стека форт-системы), которых нет в словарях(ASSEMBLER-WORDLIST не нужен) в виде словарных статей. От переключения контекста я тут ушел, так удобнее.
Попробуйте сделать это на Swift и тогда поймете, что макросами тут и не пахнет. _________________ С уважением, chess
Для упрощения синтаксиса ассемблера можно использовать, например,
прием замыкания выходного потока(код в кодофайле) на входной поток.
Простой пример использования этого приема:
Code:
REQUIRE IDN ~chess\assm\sp-assm.f
\ получаем значение литерала из его кода на вершине кодофайла
\ и кладем это значение на стек параметров,
\ а потом снимаем его оттуда и кладем на стек компиляции
I: !1 OP0 @ 4 - @ >CS ;
\ макрос немедленного исполнения делает !1, а затем корректно
\ полностью удаляет код использованного литерала с вершины кодофайла
MI" 1x !1 DROP "MI
\ макрос дает еще один синтаксис использования команды Pa(LEA EBP, SM [EBP])
\ и теперь можно писать и так $ SM Pa и так SM P+
MI" P+ 1x Pa "MI
Попробуйте сделать это на Swift и тогда поймете, что макросами тут и не пахнет
Очень интересно , что автор имеет ввиду? Вы часом не преследуете идею написать ФОРТ используя только определения ФОРТ?
Так может вспомнить, что ассемблер уже написан в определниях ФОРТ, которые заменют мнемонику на код команды.
вообщем мой мозг еще не проникся великой идеей...
Ввел автораспознавание наличия меток в определениях для исключения синтаксиса L: Word .... L; для
определений с метками вперед.
Теперь только стандартный синтаксис : Word .... ; это же относится и к определениям, в котором есть метки вперед и нет завершающего RET, теперь это пишется так : Word ... -;
Схема многопроходной компиляции начинает работать только в случае наличия меток в определениях,
без них идет обычная однопроходная компиляция.
Также ввел возможность писать макросы многострочно(не только для ассемблера) - подключением ~ac\lib\str5.f.
Библиотека str5.f немного кривит - в многострочных строках не любит комментариев до конца строки ( \ ....)
PS. Пример по циклам только для демонстрации, так как хотя код правильный, но делать так некорректно.
Выравнивания в циклах не делал.
Code:
REQUIRE IDN ~chess\assm\assm.f
\ пример определения с метками вперед и назад
STARTLOG
: S1
L1:
L2 JMP
L3 JMP
L2:
L1 JMP
L3: ;
SEE S1
\ Многострочные макросы(шаблоны)
\ цикл for-next
MI" for ( n -- )
$ -4 @X=A ( копируем начальное значение индекса цикла со стека параметров )
( и кладем его поверх адреса возврата на стек возврата )
$ -4 Xa ( устанавливаем указатель стека возвратов на ячейку с положенным индексом )
A=@P 4 P+ ( убираем начальное значение индекса цикла со стека параметров )
L1: ( фиксируем адрес в теле кода создаваемого определения )
"MI
MI" next
@X-- ( уменьшаем на единицу индекс цикла в стеке возвратов )
L1 J0<> ( делаем переход на ранее зафиксированный адрес в теле кода определения )
( если индекс не равен 0-лю, если индекс уже 0, то идем на следующую команду )
$ 4 Xa ( устанавливаем указатель стека возвратов на ячейку с адресом возврата )
"MI
MI" i ( -- i )
DUP A=@X ( читаем текущий индекс цикла на вершине стека возвратов и кладем на стек параметров )
"MI
: cicl for next ; SEE cicl
\ сумма кубов чисел
: sum-cubes.
0 SWAP for i DUP DUP * * + next CR . ; SEE sum-cubes.
1000 sum-cubes.
\ циклы begin-again(until)
MI" begin L1: "MI
MI" again L1 JMP "MI : cicl1 begin again ; SEE cicl1
MI" until A|A DROP L1 J0= "MI : cicl2 begin 0 until ; SEE cicl2
лог (SEE теперь считает кроме числа байтов еще количество инструкций в определении)
Эта библиотека заточена именно на строки.
Организовывать на ее базе многострочные макросы не стал. Вернулся к однострочным.
Для макросов нужно делать по-другому - проще.
Измененый ассм по прежнему там же http://www.chess2007.nm.ru/~chess.zip
Скриптом SPF4A.spf можно встроить ассм в СПФ(поместив его в корень и запустив). _________________ С уважением, chess
CODE s2 (5 bytes)
5A800F EB00 JMP 5A8011
5A8011 EBFC JMP 5A800F
5A8013 C3 RET NEAR
END-CODE (3 instructions)
PS.
По хорошему-то еще надо бы сделать пропуск возможных комментариев.
А вообще, по-моему, громоздко получилось.
Может в конкурс задач выложить? _________________ С уважением, chess
А вообще, по-моему, громоздко получилось.
Может в конкурс задач выложить?
можете, но, я думаю, для конкурса тяжеловато может оказаться. _________________ Мне бы только мой крошечный вклад внести,
За короткую жизнь сплести
Хотя бы ниточку шёлка.
fleur
А вообще, по-моему, громоздко получилось.
Может в конкурс задач выложить?
можете, но, я думаю, для конкурса тяжеловато может оказаться.
Я не согласен. Очень хорошая задача для конкурса. И полезная. Я не думаю, что можно сделать лучше того решения, которое я уже видел, но будет приятно ошибиться.
По хорошему-то еще надо бы сделать пропуск возможных комментариев.
Для простоты, да и для практики считаю достаточным, ввел возможность делать комментарии типа \ ....
Реализация:
Code:
: lex+ \ добавить очередную лексему в буфер
NextWord 2DUP >R >R NIP DUP 1 =
IF DROP R@ C@ [CHAR] ; =
IF RDROP RDROP PAD 500 + HLD @ SLIT,
POSTPONE EVALUATE POSTPONE ; HLD 0! EXIT
ELSE R@ C@ [CHAR] \ =
IF R@ 13 PARSE DROP R@ - 0 FILL THEN THEN \ тут не помню что впереди 10 или 13
ELSE 0= IF REFILL DROP THEN THEN
R> PAD 500 + HLD @ + R@ CMOVE> HLD @ R> + 1+ HLD !
;
: M: : IMMEDIATE
PAD 500 + 500 0 FILL HLD 0!
BEGIN lex+ HLD @ 0= UNTIL ;
Однострочные макросы в исходниках заменил на многострочные.
Устранил краевой эффект в схеме многопроходной компиляции -
иногда из-за этого были глюки c комментариями.
Добавил группу команд циклических сдвигов ROL, ROR.
Могут быть полезны для быстрых манипуляций байтами в числах.
Все залил на http://www.chess2007.nm.ru/~chess.zip
All times are GMT + 3 Hours Goto page Previous1, 2, 3 ... 13, 14, 15
Page 15 of 15
You can post new topics in this forum You can reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum