ProgramCrafter 550 Опубликовано: 7 апреля, 2022 Что это? Пока разрабатывается OpenComputers II, у меня уже появилась идея для OpenComputers III. Основывается она на далеко не новом принципе: сделать компьютер, в котором все вычисления происходят в памяти/регистрах, а единственная возможная команда - MOV (скопировать значение из одного регистра в другой). Но я не встречал никаких виртуальных машин для такой архитектуры, поэтому решил написать свою. Для чего? Пока что - исключительно ради фана. Потом - может быть, получится развести схему для такого процессора и начать производить его, но это точно не близко. Где потыкать? Текущие реализации (2 штуки, не во всех случаях работают одинаково): https://github.com/ProgramCrafter/python-mov-vm - на Python https://github.com/ProgramCrafter/rust-mov-vm - на Rust У меня была и реализация на Lua, но её я куда-то потерял. Сейчас думаю написать на Scala, как дополнительную архитектуру к OpenComputers. Что умеет? Пока что - печатать текст в консоль и считывать там же нажатия клавиш. Вообще, насколько я посчитал, любая инструкция x86 представляется в виде не более чем 8 MOV-инструкций, так что эта архитектура не должна быть существенно медленнее. Кроме того, каждая инструкция здесь 32-битная, поэтому предсказатель ветвлений и конвейер инструкций (в физическом варианте процессора) будут быстрее работать. Как выглядит какая-нибудь программа? Выводит ╔══════════════════════════════════════════════════════════╗ ║ TigerOS v0.0.1 | not licensed!!! ║ ╚══════════════════════════════════════════════════════════╝ Выход по нажатию пробела в консоли. Байткод: \x80<\x00\x1c\x80\n\x00\x1b\x80\x01\x00\x04\x00\x03\x00\x14\x00\x1d\x00\x15\x80\x07\x00\x16\x00\x17\x00\x1b\x00\x1e\x00\x10\x00\x05\x00\x03\x80\x03\x00\x1b\x00\x10\x00\x03\x80 \x00\x04\x00\x05\x00\x14\x80N\x00\x15\x80\x10\x00\x16\x00\x17\x00\x1b\xa5T\x00\x10\x00\x1c\x00\x03\x80\x02\x00\x04\x00\x05\x00\x03\xa5P\x00\x1e\x80\x17\x00\x1d\x80\x02\x00\x1b\xa5W\x00\x10\x80\n\x00\x10\xa5Q\x00\x10\x80 \x00\x10\x80 \x00\x10\x80T\x00\x10\x80i\x00\x10\x80g\x00\x10\x80e\x00\x10\x80r\x00\x10\x80O\x00\x10\x80S\x00\x10\x80 \x00\x10\x80v\x00\x10\x800\x00\x10\x80.\x00\x10\x800\x00\x10\x80.\x00\x10\x801\x00\x10\x80 \x00\x10\x80|\x00\x10\x80 \x00\x10\x80n\x00\x10\x80o\x00\x10\x80t\x00\x10\x80 \x00\x10\x80l\x00\x10\x80i\x00\x10\x80c\x00\x10\x80e\x00\x10\x80n\x00\x10\x80s\x00\x10\x80e\x00\x10\x80d\x00\x10\x80!\x00\x10\x80!\x00\x10\x80!\x00\x10\x00\x1c\x00\x03\x80$\x00\x04\x00\x05\x00\x03\x80 \x00\x1e\x80B\x00\x1d\x80\x02\x00\x1b\xa5Q\x00\x10\x80\n\x00\x10\xa5Z\x00\x10\x00\x1c\x00\x03\x80\x02\x00\x04\x00\x05\x00\x03\xa5P\x00\x1e\x80K\x00\x1d\x80\x02\x00\x1b\xa5]\x00\x10\x81\x00\x00\x10\x80\n\x00\x1b\x81\x01\x00\x10 Ассемблер (программа для перевода в байткод лежит вместе со всем на Python): Скрытый текст L0 mov 60 [w] L1 mov $L5 addr -- function L1 (char -> [char], n -> sub0, ret -> [L1RET]) L2.0 mov 1 sub1 L2.1 mov sub0 atz0 mov [L1RET] atz1 mov $L3 atz2 mov atz addr L3 mov [char] cio L4 mov sub sub0 L4D mov $L2.1 addr L4DD L5 -- main loop L6 mov cio sub0 mov 32 sub1 -- exit on Space mov sub atz0 mov $L19 atz1 mov $L7 atz2 mov atz addr L7 mov 9556 cio L8 mov [w] sub0 mov 2 sub1 mov sub sub0 mov 9552 [char] mov $L9 [L1RET] mov $L2.0 addr L9 mov 9559 cio L10 mov 10 cio L11 mov 9553 cio L11.5 mov 32 cio mov 32 cio mov 84 cio mov 105 cio mov 103 cio mov 101 cio mov 114 cio mov 79 cio mov 83 cio mov 32 cio mov 118 cio mov 48 cio mov 46 cio mov 48 cio mov 46 cio mov 49 cio mov 32 cio mov 124 cio mov 32 cio mov 110 cio mov 111 cio mov 116 cio mov 32 cio mov 108 cio mov 105 cio mov 99 cio mov 101 cio mov 110 cio mov 115 cio mov 101 cio mov 100 cio mov 33 cio mov 33 cio mov 33 cio L12 mov [w] sub0 mov 36 sub1 mov sub sub0 mov 32 [char] mov $L13 [L1RET] mov $L2.0 addr L13 mov 9553 cio L14 mov 10 cio L15 mov 9562 cio L16 mov [w] sub0 mov 2 sub1 mov sub sub0 mov 9552 [char] mov $L17 [L1RET] mov $L2.0 addr L17 mov 9565 cio L18 mov 256 cio L18D mov $L6 addr -- exit L19 mov 257 cio Структура команд Каждая команда является 32-битной: первые 16 бит описывают источник, следующие 16 - номер регистра назначения, куда надо записать значение источника. Если первый (старший) бит из 16, задающих источник, равен единице, то оставшиеся 15 бит - это число, которое будет записано в регистр назначения. Иначе эти 15 бит задают номер регистра-источника, из которого будет считано значение. Набор регистров Каждый регистр хранит 64-битное целое число. Всего регистров может быть не более 32768 из-за адресации. Номера регистров: Скрытый текст {'add0': 0, 'add1': 1, 'add': 2, 'sub0': 3, 'sub1': 4, 'sub': 5, 'mul0': 6, 'mul1': 7, 'mul': 8, 'div0': 9, 'div1': 10, 'div': 11, 'mod': 12, 'tlt0': 13, 'tlt1': 14, 'tlt': 15, 'cio': 16, 'io0': 17, 'io1': 18, 'io': 19, 'atz0': 20, 'atz1': 21, 'atz2': 22, 'atz': 23, 'memory': 24, '': 25, 'maddr': 26, 'addr': 27, 'reg0': 28, 'reg1': 29, 'reg2': 30, 'reg3': 31, 'reg4': 32, 'reg5': 33, 'reg6': 34, 'reg7': 35} Значение доступных на данный момент регистров: Скрытый текст add = add0 + add1 sub = sub0 - sub1 mul = mul0 * mul1 div = div0 / div1 (если div1 = 0, то div = div0) mod = div0 % div1 (если div1 = 0, то mod = 0) tlt = если tlt0 < tlt1, то 1; иначе 0 atz = если atz0 == 0, то atz1; иначе atz2 (очень удобно для условных прыжков) addr = текущая инструкция (аналог IP - Instruction Pointer в x86/x64) reg0-7 = регистры общего назначения (ничего не считают) cio - ввод-вывод текста через терминал; на Rust использует библиотеку termion, на Python - curses, на Lua(OpenComputers) - Term API. Чтение значения из cio возвращает -1, если не нажата ни одна кнопка, а иначе код нажатой клавиши (может быть, код символа, я не помню). Запись 256 в cio очищает экран, 257 - отключает curses и возвращается в обычную консоль, запись любого другого числа выводит на экран символ с данным кодом. memory - находится в разработке (возникает проблема с тем, что регистры 64-битные, а память квантуется по 32 бита, так как команды короткие). io - старый способ вывода данных на экран (не позволяет очистить экран, например) Пока виртуальные машины несовместимы друг с другом только при переполнении чисел в регистрах. Rust упадёт с ошибкой, Python начнёт спокойно использовать длинную арифметику, а Lua начнёт спокойно терять точность, используя double. 3 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
eu_tomat 2 155 Опубликовано: 7 апреля, 2022 @ProgramCrafter А как ты планируешь реализовать доступ к периферии? Или это очередной язык программирования, оторванный от игровой реальности? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
ProgramCrafter Автор темы 550 Опубликовано: 8 апреля, 2022 8 часов назад, eu_tomat сказал: А как ты планируешь реализовать доступ к периферии? Пока единственная идея, которая у меня появлялась - использовать регистры io. io0 - индекс устройства, io - регистр для обмена данными. Протокол обмена данными с разными компонентами надо, конечно, продумывать. Например, с дискетой или жёстким диском такой обмен данными будет очень медленным, по 8 байт за операцию. Но, например, роботу хватит. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
Laine_prikol 48 Опубликовано: 8 апреля, 2022 (изменено) 20 часов назад, ProgramCrafter сказал: Rust упадёт с ошибкой Чтобы в Rust при переполнении чисел не падал, надо явно указать поведение при арифметических операциях. Например, saturating_add - при прибавлении число просто clamp в лимит типа. https://doc.rust-lang.org/std/primitive.i32.html#method.saturating_add fn main() { println!("{}", i32::MAX.saturating_add(100)); // выведет 2147483647 } То же самое есть и для других операций - pow, sub, mul, div и т.д. Вообще насколько я помню при переполнении чисел программа падает только в debug режиме, в release должен быть просто wrapping Изменено 8 апреля, 2022 пользователем Laine_prikol Цитата Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
Taoshi 55 Опубликовано: 8 апреля, 2022 14 часа назад, ProgramCrafter сказал: по 8 байт за операцию. 64 бита не так уж мало. Этого хватает для гораздо большего, чем управление роботом. Конечно, все упирается в тактовую частоту такой шины. Если хотят создать процессор на ячейках памяти, то подачу команд и данных организовывают таким образом, что подача команды и обрабатываемых данных в качестве адреса вызывает готовый ответ без необходимости вычислений. А наличие возможности менять возвращаемое для поданной связки команда+данные содержимое реестра памяти открывает двери в по-своему увлекательный мир микропрограммирования, и с этого момента не помешает существование нишевого ИИ, помогающего инженеру решить самопоставленную задачу. По сути таким образом можно получить небинарную вычислительную среду на бинарных компонентах. В своё время разработчики вычислительной техники хотели использовать небинарную вычислительную среду, но столкнулись со сложностью как разработки самой таковой вычислительной техники, так и со сложностью создания по для оного. Кто знает, возможно, в наши дни эта тема снова может стать повесткой дня. А какие, кстати, задачи планируется решать на разрабатываемой архитектуре? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
ZO125 11 Опубликовано: 8 апреля, 2022 (изменено) Либо я не понял идею, либо она мне кажется странной. Я так понимаю автор решил создать несколько регистров "предварительно" содержащих результат любой возможной операции? А их содержимое просто копировать? Такой подход мне кажется как минимум неэффективным. Придется дожидаться установки последнего из возможных регистров перед выполнением следующей инструкции, что значительно уменьшит скорость операции mov, и как следствие вообще любого алгоритма исполняемого на такой архитектуре, иначе есть риск скопировать ммм... Помехи... Изменено 8 апреля, 2022 пользователем ZO125 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
prop 19 Опубликовано: 9 апреля, 2022 @ZO125 https://esolangs.org/wiki/Mov @Taoshi Про небинарные системы, есть источники, где ты это все подчерпнул? Про ИИ тоже хотелось бы поподробнее. @ProgramCrafter >реализация на питоне, расте, луа, а теперь и скале Ты из под скакалки хочешь запилить архитектуру https://ocdoc.cil.li/tutorial:modding_architecture для ос? Почему не на джаве? По поводу питонокода, нотация ISomething вроде сишарповская, в питоне вроде так непринято, просто к сведению. И ещё на хомяке в гитхабе у тебя "middle programmer", если имелось в виду "средний программист", то лучше поменять на decent programmer. === >очередной язык программирования, оторванный от игровой реальности Это что, ОБЕСЦЕНИВАНИЕ? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
Taoshi 55 Опубликовано: 9 апреля, 2022 1 час назад, prop сказал: Про небинарные системы, есть источники, где ты это все подчерпнул? Про ИИ тоже хотелось бы поподробнее 1.Строго говоря сейчас я не припомню где впервые читал о них. Было это около чуть более 20 лет тому. Но сейчас о троичном компьютере можно почитать например тут: https://cyberleninka.ru/article/n/istoriya-sozdaniya-troichnogo-kompyutera/viewer либо сдедать запрос в поисковой системе. В целом же использование двух состояний больше обусловлено общей тенденцией произошедшей из простоты создания бинарных систем. Ну а далее проще использовать то, что уже есть, чем перестраивать. Даже несмотря на то, что логически ничто не мешает пенести данные и алгоритмы из двоичных систем в троичные и т.д.. Но, как я понял, вы не преследовали идею перехода к системам минимальные частицы информации в которых могут находиться более чем в двух состояниях. 2.О ИИ, как я написал, "не помешает существование нишевого", имея ввиду что такового нет: На данном этапе развития отрасли проектирования ИИ все они довольно узкопрофильные и создаются под поставленные узкопрофильные задачи не охватывающие всего разнообразия когнитивной деятельности, потому только ваять лично либо искать кого-то кто заинтересуется и напишет соответствующую сетку. Если, конечно, мои сведения не устарели - эта сфера развивается ощутимо быстро. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
eu_tomat 2 155 Опубликовано: 9 апреля, 2022 В 08.04.2022 в 06:40, ProgramCrafter сказал: Протокол обмена данными с разными компонентами надо, конечно, продумывать. Например, с дискетой или жёстким диском такой обмен данными будет очень медленным, по 8 байт за операцию. Но, например, роботу хватит. А ты планируешь использовать только новую периферию, изначально написанную под этот мод, или создать протокол для работы с периферией CC и OC? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
prop 19 Опубликовано: 9 апреля, 2022 В 08.04.2022 в 08:40, ProgramCrafter сказал: Пока единственная идея, которая у меня появлялась - использовать регистры io. io0 - индекс устройства, io - регистр для обмена данными. Протокол обмена данными с разными компонентами надо, конечно, продумывать. Например, с дискетой или жёстким диском такой обмен данными будет очень медленным, по 8 байт за операцию. Но, например, роботу хватит. До периферии нужно ещё как-то заставить компьютер работать, вопрос в том как программа будет попадать в movmachine? Нащелкиванием через front panel или через реликтовые прото(перфокарты/дискеты) с boot'ером, неизвестно как оказавшиеся в данжах? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
eu_tomat 2 155 Опубликовано: 9 апреля, 2022 16 часов назад, Taoshi сказал: Если хотят создать процессор на ячейках памяти, то подачу команд и данных организовывают таким образом, что подача команды и обрабатываемых данных в качестве адреса вызывает готовый ответ без необходимости вычислений. Имеешь в виду программируемые логические матрицы? Кстати, да, хорошая альтернатива разработке специализированного процессора. Особенно, на этапе тестирования идеи. 16 часов назад, Taoshi сказал: В своё время разработчики вычислительной техники хотели использовать небинарную вычислительную среду, но столкнулись со сложностью как разработки самой таковой вычислительной техники, так и со сложностью создания по для оного. Кто знает, возможно, в наши дни эта тема снова может стать повесткой дня. Небинарные вычислительные среды существуют и совершенствуются. Есть довольно свежее видео: Скрытый текст Цитата Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
ProgramCrafter Автор темы 550 Опубликовано: 9 апреля, 2022 22 часа назад, Laine_prikol сказал: Чтобы в Rust при переполнении чисел не падал, надо явно указать поведение при арифметических операциях. Например, saturating_add - при прибавлении число просто clamp в лимит типа Да, я знаю, надо только записать в документацию поведение при переполнении. 15 часов назад, ZO125 сказал: Придется дожидаться установки последнего из возможных регистров перед выполнением следующей инструкции Необязательно, можно же так расположить команды, что в большинстве мест можно будет выполнять по два или больше mov одновременно. Например, условные переходы у меня сейчас используют особый регистр atz: он возвращает atz1, если atz0 == 0, иначе atz2. Значит, если я хочу при v == 0 прыгнуть в одно место, а при v != 0 в другое, то я могу одновременно записывать v, положение первого и второго места в atz0, atz1 и atz2. Я говорю вот что: во-первых, mov исполняется никак не медленнее любой инструкции x86 (может быть, медленнее nop, но это не точно); во-вторых, вроде бы, любую из старых инструкций x86 (до появления дополнений с векторизацией и тому подобным) можно превратить не более чем в 8 моих инструкций. Работать будет, конечно, медленно, но будет. 5 часов назад, prop сказал: Ты из под скакалки хочешь запилить архитектуру https://ocdoc.cil.li/tutorial:modding_architecture для ос? Почему не на джаве? Например, чтобы и скалу подучить. Для джавы у меня другой проект, OCTechnics 5 часов назад, prop сказал: По поводу питонокода, нотация ISomething вроде сишарповская, в питоне вроде так непринято, просто к сведению Да какая разница, я могу код и без этого писать... 5 часов назад, prop сказал: И ещё на хомяке в гитхабе у тебя "middle programmer", если имелось в виду "средний программист", то лучше поменять на decent programmer То есть, грейды junior-middle-senior только у нас так называют? 24 минуты назад, eu_tomat сказал: А ты планируешь использовать только новую периферию, изначально написанную под этот мод, или создать протокол для работы с периферией CC и OC? Скорее всего, только новую. Только что, prop сказал: Нащелкиванием через front panel или через реликтовые прото(перфокарты/дискеты) с boot'ером, неизвестно как оказавшиеся в данжах? Через протоеепромы, конечно. Например, просто перекрутить обычный EEPROM гаечным ключом сколько-то раз. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
ProgramCrafter Автор темы 550 Опубликовано: 9 апреля, 2022 16 часов назад, Taoshi сказал: А наличие возможности менять возвращаемое для поданной связки команда+данные содержимое реестра памяти открывает двери в по-своему увлекательный мир микропрограммирования Да, насколько я знаю, теории конечных автоматов с изменяющимися правилами ещё никто не создавал. (Кстати, может, именно поэтому не могут вывести "формулу всего" в физике?) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
ProgramCrafter Автор темы 550 Опубликовано: 9 апреля, 2022 16 часов назад, Taoshi сказал: А какие, кстати, задачи планируется решать на разрабатываемой архитектуре? Например, ОС написать. Или портировать что-нибудь из линуксов, я вообще хочу попробовать написать транслятор x86 в movasm. И будет наконец без помощи VirtualBox в майнкрафте серьёзная ОС. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
ProgramCrafter Автор темы 550 Опубликовано: 9 апреля, 2022 3 часа назад, ProgramCrafter сказал: теории конечных автоматов с изменяющимися правилами ещё никто не создавал Опс, я понял: если взять в качестве состояния не только текущую вершину, но и набор существующих на данный момент рёбер, то получится не менее конечный автомат, размер которого будет n * 2^(n^2/2). Теперь единственная проблема, что этот граф слишком большой, чтобы с ним по-нормальному работать, но как минимум, он не бесконечный. А значит, с ним можно работать, как с обычным... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
prop 19 Опубликовано: 9 апреля, 2022 5 часов назад, ProgramCrafter сказал: То есть, грейды junior-middle-senior только у нас так называют? Middle на каком стеке? Обычно так обозначается опыт, например, Middle Python программист, 5 лет опыта, далее перечисление проектов с датами и местом работы. Без опыта работы и конкретного указания проектов Middle Programmer выглядит странно. 5 часов назад, ProgramCrafter сказал: хочу попробовать написать транслятор x86 в movasm Так ведь есть уже GitHub - xoreaxeaxeax/movfuscator: The single instruction C compiler Цитата Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
ProgramCrafter Автор темы 550 Опубликовано: 9 апреля, 2022 1 час назад, prop сказал: Без опыта работы и конкретного указания проектов Middle Programmer выглядит странно Так это и не резюме (как минимум, пока что). 1 час назад, prop сказал: Так ведь есть уже Посмотрел, увидел, что компилирует только C/C++/что-то в LLVM, закрыл . Хотя, мб, можно линукс перегнать в такой формат. Но надо ещё разбираться, как используемые регистры у x86 соответствуют моим. Вообще, псевдокод, который я транслирую в movasm, по синтаксису питон, а по используемым функциям - странная смесь C++, раста и, конечно, самого питона. Например, аллокатор, который я сейчас пишу (да, здесь могут быть баги и тому подобное): _static_alloc = 1024 def _static_allocate(size): _static_alloc += size return _static_alloc - size def _static_deallocate(p): pass _alloc_cl_first = _static_allocate(4) _alloc_cl_first->first = 1048575 def _list_ins_between(L: *list_node, R: *list_node, u: pair<size_t, size_t>): v = _static_allocate(4) v->first = u.first v->second = u.second v->third = R v->fourth = L if L: L->third = v if R: R->fourth = v return v ... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах