Перейти к содержанию

Гайд по RedPower. Low-level №3. Собственные структуры данных.


Alleksh

Рекомендуемые сообщения

И так, вам необходимо реализовать структуру, в которой необходимо хранить больше одного числа? Два числа? Число и строку? Число, строку, исполняемый код?
Вам определённо нужно прочитать эту статью.
Для начала стоит ознакомиться с некоторыми командами:
HIDE - прячет последнее слово из словаря.

REVEAL - восстанавливает спрятанное слово в словарь.
HEADER - берёт следующую строку из буфера, создает слово с этим именем.
ALLOT - берёт n со стека, выделяет n байт и возвращает начало выделенной памяти.
, - выделяет 2 байта, записывает в них значение со стека.
,C - выделяет и записывает 1 байт.
,S - Аналогично ',' , только для строки. Адрес должен находиться в стеке.
Давайте узнаем, как работает VARIABLE:
image.png.5f80d16594ec467b6458167d7342c500.png
Она вызывает функцию CREATE, выделяет 2 байта, записывает туда 0.
Давайте узнаем, что делает CREATE:
image.png.1e40bbd06e948e84a02a3a87b6c43f0e.png
Идёт вызов функции HEADER, определение которой нам известно.
Выделяет один байт, записывает 0x22.
Примечание:
Во второй части гайда я рассказывал, что это инструкция ENT, которая определяет, что нужно далее делать.

Выделяет еще два байта, записывает туда 0x534.
Давайте узнаем, что это за функция!
image.png.48382c9eb468ba976ebfcb507667f46c.png
А это - функция DOVAR, которая записывает адрес следующего байта и возвращает нас в предыдущее слово.
image.png.5d914ce6efe04337dd7a079b19ceb892.png
То есть, когда мы пишем VAR - исполняется функция DOVAR. DOVAR - то же, что и EXIT, лишь оставляет в памяти адрес следующих двух байт.
image.png.a252c56b14c3a0ecc49d965101360227.png
То есть VAR @ можно на заменить 25FD @:

image.png.9fc8a9152f7f077ec45037459d9a1cf4.png

Ладно, мы понимаем, как можно записывать переменные и строки. 
Но как записывать исполняемую часть?
Давайте посмотрим на исходный код слова " : ":
image.png.b762128086dc4c43d9475aa22a312aee.png
Определение HEADER, HIDE нам известно. Про 0x22 мы уже говорили...
А что значит "[" ?

image.png.665daf61c03a375d803a544c7ef0dac1.png
Тут всё крайне просто - в STATE хранится режим, в котором мы сейчас находимся(1 - компиляция, 0 - диалог).
Завершение компиляции - слово " ; "
image.png.ec2e2cea329cb598b0c6740a2cffe3e7.png
Выделяет два байта, записывает в них адрес EXIT.
Вызывает " ] ", который возвращает нас обратно в диалоговый режим.
Вызывает REVEAL, определение которого нам известно.

Теперь, понимая всё это, давайте напишем слово для генерации структур данных, обозначающих предмет.
Для начала разметка:
Первый байт(он же 0x00) - 0x22, вхождение в строку.
0x01-0x02 - 0x0534(DOVAR)
0x01-0x02 - RedPower id #1
0x03-0x04 - RedPower id #2
0x05-0xXX - наша строка, где на 0xXX будет храниться 0x00, что является концом строки.
Давайте напишем функцию, которая будет выделять память для этого:
HEX
: ADD_ITEM
HEADER 22 ,C 534 ,
SORTSLOT@ DROP , ,
CR ." Enter string size: "
100 80 ACCEPT UATOI 1+ DUP 1+ ALLOT 
CR ." Enter item name: "
OVER ACCEPT DROP ;
image.png.d7d70adc7bf7bb27884cbe08d8a45de5.png
Как можно увидеть по дампу - функция работает отлично.
Чтобы получить нужные нам данные можно написать:
image.png.cbfd5569c68a2d03c04c728f4e7cfdba.png
Всё работает отлично!
Давайте теперь создадим массив таких предметов.
Вот и появилась первая проблема - размер строк не зарезервирован, то есть - он разный, и невозможно подобрать определённое кол-во элементов массиве, размер будет разным.
У этой проблемы есть два решения:
1) Создавать массив с определенным кол-вом выделенных байт, каждая структура данных будет указывать на место следующей, кол-во элементов указываем в начале массива.
2) Создать массив с определенным кол-вом элементов, у которых будет точный размер.
Давайте реализуем первый.
Разметка:
0x00-0x01 - размер массива(байт).
0x02-0x03 - кол-во элементов в массиве.
0x04-0xXX - элементы массива(где XX - размер массива в байтах + 2).
Разметка элемента:
0x00-0x01  - указатель на место в памяти следующего элемента.
0x02-0x03 - RedPower id #1
0x04-0x05 - RedPower id #2
0x05-0xXX - наша строка, где на 0xXX будет храниться 0x00, что является концом строки.

Реализация:
: ALLOCATE_MASSIVE CREATE DUP ALLOT ! ;
VARIABLE MASSIVE_ADDR
VARIABLE ELEM_ADDR
VARIABLE MASSIVE_SIZE
: MASSIVE_GET_ELEMSIZE MASSIVE_ADDR @ 2 + @ ;
: MASSIVE_SET_ELEMSIZE MASSIVE_ADDR @ 2 + ! ;
: ADD_ELEMENT_TO_MASSIVE
MASSIVE_ADDR !
MASSIVE_ADDR  @ @ MASSIVE_SIZE !
MASSIVE_GET_ELEMSIZE 1+ MASSIVE_SET_ELEMSIZE
MASSIVE_ADDR 4 + ELEM_ADDR !
MASSIVE_GET_ELEMSIZE 0<>
IF MASSIVE_GET_ELEMSIZE 1- 0 DO 
ELEM_ADDR @ @ ELEM_ADDR !
LOOP THEN
SORTSLOT@ DROP
ELEM_ADDR @ 2 + ! ELEM_ADDR @ 4 + !

CR ." Enter string size: "
100 80 ACCEPT UATOI  DUP 4 + ELEM_ADDR !
CR ." Enter string: "
ELEM_ADDR @ OVER 6 + ACCEPT ; 
Попробуем инициализировать массив:
image.png.0a581eff0d65d0f88364400273c6ea19.png
Всё отлично! Размер массива инициализирован.
Попробуем добавить элемент "Diamond" в массив.
Просмотрим дамп памяти массива:
image.png.4b8bd57dd1accc369ad9870cdb60b0ba.png
Всё отлично! Теперь по адресу 0x2FF2 размещен указатель на 0x2FFF, где будет находится следующий элемент массива.

Удачи Вам в Ваших разработках!

Первая часть: https://f.simpleminecraft.ru/index.php?/topic/5936-redpower-компьютеры/
Вторая часть: https://f.simpleminecraft.ru/index.php?/topic/5941-redpower-компьютеры-вторая-часть-понимание-системы/

Третья часть: https://f.simpleminecraft.ru/index.php?/topic/5951-redpower-компьютеры-третья-часть-еще-глубже-ускорение-заводов/

Четвертая часть: https://f.simpleminecraft.ru/index.php?/topic/5965-redpower-компьютеры-четвёртая-часть-собственные-структуры-данных/

Пятая часть: https://f.simpleminecraft.ru/index.php?/topic/5989-гайд-по-redpower-компьютеры-пятая-часть-работа-с-сетью-дисками-чат/

 

 

Изменено пользователем Alleksh
  • Нравится 1
  • Рейтинг 1
Ссылка на комментарий
Поделиться на другие сайты

Для публикации сообщений создайте учётную запись или авторизуйтесь

Вы должны быть пользователем, чтобы оставить комментарий

Создать учетную запись

Зарегистрируйте новую учётную запись в нашем сообществе. Это очень просто!

Регистрация нового пользователя

Войти

Уже есть аккаунт? Войти в систему.

Войти
  • Последние посетители   0 пользователей онлайн

    • Ни одного зарегистрированного пользователя не просматривает данную страницу
×
×
  • Создать...