Forth и другие саморасширяющиеся системы программирования Locations of visitors to this page
Текущее время: Пт мар 29, 2024 04:49

...
Google Search
Forth-FAQ Spy Grafic

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




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

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

Обзор темы - Компилирующий ассемблер
Автор Сообщение
  Заголовок сообщения:   Ответить с цитатой
Однострочные макросы в исходниках заменил на многострочные.
Устранил краевой эффект в схеме многопроходной компиляции -
иногда из-за этого были глюки c комментариями.

Добавил группу команд циклических сдвигов ROL, ROR.
Могут быть полезны для быстрых манипуляций байтами в числах.
Все залил на http://www.chess2007.nm.ru/~chess.zip

примеры - перестановки байтов в ячейке

Код:
STARTLOG
: swapb ( n[4321] -- n[4312] )
$ 8 #wAo<< ;   SEE swapb

0x44332211 swapb  HEX CR U. DECIMAL

: 2swapb ( n[4321] -- n[2143] )
$ 10 #Ao<< ;   SEE 2swapb

0x44332211 2swapb HEX CR U. DECIMAL

: rotb ( n[4321] -- n[4123] )
$ 8 #wAo<< A0123 $ 8 #Ao>> ; SEE rotb

0x44332211 rotb   HEX CR U. DECIMAL
\ и т.д.

лог
Код:
CODE swapb (5 bytes)
5ABD07 66               D16:
5ABD08 C1C008           ROL     AX , 8
5ABD0B C3               RET     NEAR
END-CODE                (3 instructions)

44331122

CODE 2swapb (4 bytes)
5ABD1F C1C010           ROL     EAX , 10
5ABD22 C3               RET     NEAR
END-CODE                (2 instructions)

22114433

CODE rotb (10 bytes)
5ABD37 66               D16:
5ABD38 C1C008           ROL     AX , 8
5ABD3B 0FC8             BSWAP   EAX
5ABD3D C1C808           ROR     EAX , 8
5ABD40 C3               RET     NEAR
END-CODE                (5 instructions)

44221133
Ok
Сообщение Добавлено: Пт июн 20, 2008 15:03
  Заголовок сообщения:   Ответить с цитатой
chess писал(а):
По хорошему-то еще надо бы сделать пропуск возможных комментариев.

Для простоты, да и для практики считаю достаточным, ввел возможность делать комментарии типа \ ....
Реализация:
Код:
: 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  ;

\ Пример

M: S1 \ комментарии
L1: L2 JMP  \ комментарии
            \ комментарии
L2: L1 JMP  \ комментарии
;
: s1 S1 ;

STARTLOG

SEE S1 SEE s1

лог

Код:
CODE S1 (47 bytes)
5A7FD7 E880A1FAFF       CALL    55215C  ( _SLITERAL-CODE )
5A7FDC   22 00 00 00  4C 31 3A 00  4C 32 00 4A  4D 50 00 00 "...L1:.L2.JMP..
5A7FEC   00 00 00 00  00 4C 32 3A  00 4C 31 00  4A 4D 50 00 .....L2:.L1.JMP.
5A7FFC   00 00 00 00  E8 8B FB FB  FF C3 17 80  5A 00 00 02 ....и‹ыыяГ.ЂZ...
5A8000 E88BFBFBFF       CALL    567B90  ( EVALUATE )
5A8005 C3               RET     NEAR
END-CODE                (3 instructions)

CODE s1 (5 bytes)
5A8017 EB00             JMP     5A8019
5A8019 EBFC             JMP     5A8017
5A801B C3               RET     NEAR
END-CODE                (3 instructions)

Ok

forther писал(а):
Я не согласен. Очень хорошая задача для конкурса. И полезная.

Полезная, но по-моему неинтересная.
Сообщение Добавлено: Ср июн 18, 2008 12:30
  Заголовок сообщения:   Ответить с цитатой
mOleg писал(а):
chess писал(а):
А вообще, по-моему, громоздко получилось.
Может в конкурс задач выложить?

можете, но, я думаю, для конкурса тяжеловато может оказаться.


Я не согласен. Очень хорошая задача для конкурса. И полезная. Я не думаю, что можно сделать лучше того решения, которое я уже видел, но будет приятно ошибиться.
Сообщение Добавлено: Ср июн 18, 2008 00:27
  Заголовок сообщения:   Ответить с цитатой
chess писал(а):
А вообще, по-моему, громоздко получилось.
Может в конкурс задач выложить?

можете, но, я думаю, для конкурса тяжеловато может оказаться.
Сообщение Добавлено: Вт июн 17, 2008 21:11
  Заголовок сообщения:   Ответить с цитатой
chess писал(а):
Для макросов нужно делать по-другому - проще.

Попробовал сделать многострочные макросы.

Формируется строка в PAD, затем словом SLIT, помещается в словарную статью макроса,
которую заканчивает отложенный код слова EVALUATE.

Синтаксис создания макросов такой:

M: Name .....
.....
.....
;

Реализация:
Код:
: 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
   THEN
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  ;

\ Примеры

M: S1 L1: *A L1 JMP ;

M: S2
L1: L2 JMP
L2: L1 JMP
;

: s1 S1 ;
: s2 S2 ;

STARTLOG
SEE S1 SEE s1
SEE S2 SEE s2

лог
Код:
CODE S1 (27 bytes)
5A7F97 E8C0A1FAFF       CALL    55215C  ( _SLITERAL-CODE )
5A7F9C   0E 4C 31 3A  00 2A 41 00  4C 31 00 4A  4D 50 00 00 .L1:.*A.L1.JMP..
5A7FAC E8DFFBFBFF       CALL    567B90  ( EVALUATE )
5A7FB1 C3               RET     NEAR
END-CODE                (3 instructions)

CODE s1 (5 bytes)
5A7FFB F7E8             IMUL    EAX
5A7FFD EBFC             JMP     5A7FFB
5A7FFF C3               RET     NEAR
END-CODE                (3 instructions)

CODE S2 (38 bytes)
5A7FC3 E894A1FAFF       CALL    55215C  ( _SLITERAL-CODE )
5A7FC8   19 00 4C 31  3A 00 4C 32  00 4A 4D 50  00 00 4C 32 ..L1:.L2.JMP..L2
5A7FD8   3A 00 4C 31  00 4A 4D 50  00 00 00 E8  A8 FB FB FF :.L1.JMP...иЁыыя
5A7FE3 E8A8FBFBFF       CALL    567B90  ( EVALUATE )
5A7FE8 C3               RET     NEAR
END-CODE                (3 instructions)

CODE s2 (5 bytes)
5A800F EB00             JMP     5A8011
5A8011 EBFC             JMP     5A800F
5A8013 C3               RET     NEAR
END-CODE                (3 instructions)

PS.
По хорошему-то еще надо бы сделать пропуск возможных комментариев.
А вообще, по-моему, громоздко получилось.
Может в конкурс задач выложить?
Сообщение Добавлено: Вт июн 17, 2008 16:51
  Заголовок сообщения:   Ответить с цитатой
вопрос писал(а):
То есть как это не любит? Надо поправить ...

Эта библиотека заточена именно на строки.
Организовывать на ее базе многострочные макросы не стал. Вернулся к однострочным.
Для макросов нужно делать по-другому - проще.
Измененый ассм по прежнему там же http://www.chess2007.nm.ru/~chess.zip
Скриптом SPF4A.spf можно встроить ассм в СПФ(поместив его в корень и запустив).
Сообщение Добавлено: Ср июн 11, 2008 17:53
  Заголовок сообщения:   Ответить с цитатой
Цитата:
Библиотека str5.f немного кривит - в многострочных строках не любит комментариев до конца строки ( \ ....)
То есть как это не любит? Надо поправить ... :(
Сообщение Добавлено: Сб июн 07, 2008 19:10
  Заголовок сообщения:   Ответить с цитатой
Ввел автораспознавание наличия меток в определениях для исключения синтаксиса L: Word .... L; для
определений с метками вперед.
Теперь только стандартный синтаксис : Word .... ; это же относится и к определениям, в котором есть метки вперед и нет завершающего RET, теперь это пишется так : Word ... -;
Схема многопроходной компиляции начинает работать только в случае наличия меток в определениях,
без них идет обычная однопроходная компиляция.

Также ввел возможность писать макросы многострочно(не только для ассемблера) - подключением ~ac\lib\str5.f.
Библиотека str5.f немного кривит - в многострочных строках не любит комментариев до конца строки ( \ ....)

PS. Пример по циклам только для демонстрации, так как хотя код правильный, но делать так некорректно.
Выравнивания в циклах не делал.

Код:
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 теперь считает кроме числа байтов еще количество инструкций в определении)
Код:
CODE S1 (7 bytes)
5A8FA7 EB02             JMP     5A8FAB  --|     <--|
5A8FA9 EB02             JMP     5A8FAD    | --|    |
5A8FAB EBFA             JMP     5A8FA7  <-|   | ---|
5A8FAD C3               RET     NEAR    <-----|
END-CODE (4 instructions)

CODE cicl (24 bytes)
5A9083 894424FC         MOV     FC [ESP] , EAX
5A9087 8D6424FC         LEA     ESP , FC [ESP]
5A908B 8B4500           MOV     EAX , 0 [EBP]
5A908E 8D6D04           LEA     EBP , 4 [EBP]
5A9091 FF0C24           DEC     [ESP]
5A9094 75FB             JNE     5A9091
5A9096 8D642404         LEA     ESP , 4 [ESP]
5A909A C3               RET     NEAR
END-CODE (8 instructions)

CODE sum-cubes. (67 bytes)
5A90B3 C745FC00000000   MOV     FC [EBP] , # 0
5A90BA 8D6DFC           LEA     EBP , FC [EBP]
5A90BD 894424FC         MOV     FC [ESP] , EAX
5A90C1 8D6424FC         LEA     ESP , FC [ESP]
5A90C5 8B4500           MOV     EAX , 0 [EBP]
5A90C8 8D6D04           LEA     EBP , 4 [EBP]
5A90CB 8945FC           MOV     FC [EBP] , EAX
5A90CE 8D6DFC           LEA     EBP , FC [EBP]
5A90D1 8B0424           MOV     EAX , [ESP]
5A90D4 8945FC           MOV     FC [EBP] , EAX
5A90D7 F7E8             IMUL    EAX
5A90D9 F76DFC           IMUL    FC [EBP]
5A90DC 034500           ADD     EAX , 0 [EBP]
5A90DF 8D6D04           LEA     EBP , 4 [EBP]
5A90E2 FF0C24           DEC     [ESP]
5A90E5 75E4             JNE     5A90CB
5A90E7 8D642404         LEA     ESP , 4 [ESP]
5A90EB E8C0CBFAFF       CALL    555CB0  ( CR )
5A90F0 E803D2FAFF       CALL    5562F8  ( . )
5A90F5 C3               RET     NEAR
END-CODE (20 instructions)

1392146832

CODE cicl1 (3 bytes)
5A9167 EBFE             JMP     5A9167
5A9169 C3               RET     NEAR
END-CODE (2 instructions)

CODE cicl2 (19 bytes)
5A91B7 8945FC           MOV     FC [EBP] , EAX
5A91BA 33C0             XOR     EAX , EAX
5A91BC 8D6DFC           LEA     EBP , FC [EBP]
5A91BF 0BC0             OR      EAX , EAX
5A91C1 8B4500           MOV     EAX , 0 [EBP]
5A91C4 8D6D04           LEA     EBP , 4 [EBP]
5A91C7 74EE             JE      5A91B7
5A91C9 C3               RET     NEAR
END-CODE (8 instructions)

Ok
Сообщение Добавлено: Сб июн 07, 2008 18:08
  Заголовок сообщения:   Ответить с цитатой
Идея очень хорошая, но chess не желает сделать подробную инструкцию :D .
Сообщение Добавлено: Сб май 31, 2008 16:10
  Заголовок сообщения:   Ответить с цитатой
chess писал(а):
Попробуйте сделать это на Swift и тогда поймете, что макросами тут и не пахнет

Очень интересно , что автор имеет ввиду? Вы часом не преследуете идею написать ФОРТ используя только определения ФОРТ?
Так может вспомнить, что ассемблер уже написан в определниях ФОРТ, которые заменют мнемонику на код команды.
вообщем мой мозг еще не проникся великой идеей... :shuffle;
Сообщение Добавлено: Сб май 31, 2008 15:55
  Заголовок сообщения:   Ответить с цитатой
Для упрощения синтаксиса ассемблера можно использовать, например,
прием замыкания выходного потока(код в кодофайле) на входной поток.

Простой пример использования этого приема:

Код:
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

\ EOF

: dup  -4 P+ @P=A ;
: drop  A=@P 4 P+ ;
: /string $ 4 @P+A -A A+@P 4 P+ ;

STARTLOG
SEE dup
SEE drop
SEE /string
лог
Код:
CODE dup
5A593B 8D6DFC           LEA     EBP , FC [EBP]
5A593E 894500           MOV     0 [EBP] , EAX
5A5941 C3               RET     NEAR
END-CODE
( 7 Bytes )

CODE drop
5A5953 8B4500           MOV     EAX , 0 [EBP]
5A5956 8D6D04           LEA     EBP , 4 [EBP]
5A5959 C3               RET     NEAR
END-CODE
( 7 Bytes )

CODE /string
5A596F 014504           ADD     4 [EBP] , EAX
5A5972 F7D8             NEG     EAX
5A5974 034500           ADD     EAX , 0 [EBP]
5A5977 8D6D04           LEA     EBP , 4 [EBP]
5A597A C3               RET     NEAR
END-CODE
( 12 Bytes )

Ok
Сообщение Добавлено: Пт май 30, 2008 18:08
  Заголовок сообщения:   Ответить с цитатой
Alexander писал(а):
Вообще в последнем посте CHESS'a идет речь об ассемблерных макросах в ЯП ФОРТ.

Вы заблуждаетесь. Речь идет о формировании поля кода форт-слов с помощью ранее определенных форт-слов и машинных команд совместно. Причем эти форт-слова и машинные команды используются на равных основаниях.
Компиляция машинных команд в поле кода определяемого слова происходит не по-фортовски путем компиляции
вызова форт-слова или инлайн-вставки кода этого слова, а путем формирования(генерации) кода машинных команд
в поле кода определяемого слова на основании имен машинных команд(иногда с использованием параметров со стека форт-системы), которых нет в словарях(ASSEMBLER-WORDLIST не нужен) в виде словарных статей. От переключения контекста я тут ушел, так удобнее.
Попробуйте сделать это на Swift и тогда поймете, что макросами тут и не пахнет.
Сообщение Добавлено: Пт май 23, 2008 16:22
  Заголовок сообщения:   Ответить с цитатой
chess писал(а):
Совместное использование ассемблера и форта при создании форт-определений...

Обычно люди пользуются словарными статьями (VOCABULARY) и переключают контекст с помощью нехитрых слов, определенных как IMMEDIATE, например, так:
Код:
: [+ASSEMBLER]  ASSEMBLER-WORDLIST +ORDER ; IMMEDIATE

Вообще в последнем посте CHESS'a идет речь об ассемблерных макросах в ЯП ФОРТ.
Сообщение Добавлено: Пт май 23, 2008 10:49
  Заголовок сообщения:   Ответить с цитатой
Пожелание chessу

Оформить статью по видению проблематики предметной области и поместить ссылку на нее, например, в wikipedии/ассемблер
Сообщение Добавлено: Пт май 23, 2008 08:33
  Заголовок сообщения:   Ответить с цитатой
Совместное использование ассемблера и форта при создании форт-определений

Если в текст на форте вставляем законченный фрагмент на ассемблере ничего делать не надо, так как
регистры процессора внутри форт-определений инициируются параметрами либо со стека либо из памяти,
и поэтому их начальные состояния значения не имеют.
В случае же когда алгоритм кодируется на ассемблере и нужно вставить в текст на ассемблере слова на форте
может возникнуть ситуация когда форт-слова портят регистры используемые в последующем тексте на ассемблере.
В этом случае можно использовать команды PUSHAD - сохранение всех регистров в стеке возвратов(содержимое регистров при этом не меняется), а затем после исполнения фрагмента на форте восстановить их командой POPAD.

Например вывод числа с вершины стека без изменения стека будет выглядеть так.
Код:
: dup. PUSHAD . POPAD ;

STARTLOG

15 dup.

SEE dup.
лог
Код:
15

CODE dup.
5A5400 60               PUSHAD
5A5401 E88E0EFBFF       CALL    556294  ( . )
5A5406 61               POPAD
5A5407 C3               RET     NEAR
END-CODE
( 8 Bytes )

Ok ( 15 )
Для удобства можно ввести алиасы для PUSHAD и POPAD, например !r и @r сответственно
Тогда то же самое
Код:
: dup. !rg . @rg ;
Сообщение Добавлено: Чт май 22, 2008 18:27

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


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