Alleksh Опубликовано 4 января, 2019 Поделиться Опубликовано 4 января, 2019 (изменено) И так, вам необходимо реализовать структуру, в которой необходимо хранить больше одного числа? Два числа? Число и строку? Число, строку, исполняемый код? Вам определённо нужно прочитать эту статью. Для начала стоит ознакомиться с некоторыми командами: HIDE - прячет последнее слово из словаря. REVEAL - восстанавливает спрятанное слово в словарь. HEADER - берёт следующую строку из буфера, создает слово с этим именем. ALLOT - берёт n со стека, выделяет n байт и возвращает начало выделенной памяти. , - выделяет 2 байта, записывает в них значение со стека. ,C - выделяет и записывает 1 байт. ,S - Аналогично ',' , только для строки. Адрес должен находиться в стеке. Давайте узнаем, как работает VARIABLE: Она вызывает функцию CREATE, выделяет 2 байта, записывает туда 0. Давайте узнаем, что делает CREATE: Идёт вызов функции HEADER, определение которой нам известно. Выделяет один байт, записывает 0x22.Примечание: Во второй части гайда я рассказывал, что это инструкция ENT, которая определяет, что нужно далее делать. Выделяет еще два байта, записывает туда 0x534. Давайте узнаем, что это за функция! А это - функция DOVAR, которая записывает адрес следующего байта и возвращает нас в предыдущее слово. То есть, когда мы пишем VAR - исполняется функция DOVAR. DOVAR - то же, что и EXIT, лишь оставляет в памяти адрес следующих двух байт. То есть VAR @ можно на заменить 25FD @: Ладно, мы понимаем, как можно записывать переменные и строки. Но как записывать исполняемую часть? Давайте посмотрим на исходный код слова " : ": Определение HEADER, HIDE нам известно. Про 0x22 мы уже говорили... А что значит "[" ? Тут всё крайне просто - в STATE хранится режим, в котором мы сейчас находимся(1 - компиляция, 0 - диалог). Завершение компиляции - слово " ; " Выделяет два байта, записывает в них адрес 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 ; Как можно увидеть по дампу - функция работает отлично. Чтобы получить нужные нам данные можно написать: Всё работает отлично! Давайте теперь создадим массив таких предметов. Вот и появилась первая проблема - размер строк не зарезервирован, то есть - он разный, и невозможно подобрать определённое кол-во элементов массиве, размер будет разным. У этой проблемы есть два решения: 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 THENSORTSLOT@ 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 ; Попробуем инициализировать массив: Всё отлично! Размер массива инициализирован. Попробуем добавить элемент "Diamond" в массив. Просмотрим дамп памяти массива: Всё отлично! Теперь по адресу 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-компьютеры-пятая-часть-работа-с-сетью-дисками-чат/ Изменено 5 января, 2019 пользователем Alleksh 1 1 Ссылка на комментарий Поделиться на другие сайты Поделиться
Рекомендуемые сообщения
Для публикации сообщений создайте учётную запись или авторизуйтесь
Вы должны быть пользователем, чтобы оставить комментарий
Создать учетную запись
Зарегистрируйте новую учётную запись в нашем сообществе. Это очень просто!
Регистрация нового пользователяВойти
Уже есть аккаунт? Войти в систему.
Войти