Сегодня они пишут xonix, а завтра напишут на баше отдельную операционную систему с фреймворком и СУБД.
Наконец, завтра наступило. В bash (после некоторого допиливания) можно запустить серьезную ОС, например, CP/M. А для CP/M определенно есть СУБД, компиляторы и многое другое.
Почему не нужно и зачем нужно делать эмуляторы на bash, работающий эмулятор i8080 на bash и несколько советов по ускорению работы bash-скриптов -
Bash работает неторопливо. Даже для такого простого процессора, как i8080, едва ли скорость эмуляции будет хотя бы 1% от реальной. На моем Celeron с частотой 2.2ГГц эмулятор работает со скоростью примерно 100 операций в секунду, в то время как реальный процессор i8080 на 2.5МГц отрабатывает 600 тысяч операций в секунду.
Другая важная проблема: в bash невозможно работать с двоичными данными. Если вы хотите вывести в порт или считать из файла символ с кодом 0x01, то bash — явно не тот язык, который вам нужен.
Третья проблема. Разработка эмулятора — это задачка не на час и не на два. Не стоит писать эмулятор без редактора с подсветкой синтаксиса и без отладчика. Когда я начала «сочинять» свой эмулятор, то думала: «А, нужно сделать всего-навсего 84 команды! Ерунда какая!». Дойдя до 51го кода операции, я наконец осознала, что команда != код операции, и что предстоит реализовать еще 200 кодов. Если бы я сразу учла, что кодов операций за две сотни, то не стала бы писать эмулятор. А раз уж начала писать — пришлось доделывать.
Затем, что это супер-пупер-мега круто. Затем, что это дает огромный опыт программирования на bash. Затем, что программы в эмуляторе будут выполняться очень-очень медленно, и можно будет уследить за изменением флагов и регистров.
Скорость выполнения кода для эмулятора критически важна. Если вы хотите, чтобы ваш скрипт на bash выполнялся как можно быстрее, то:
Вызов expr или bc в цикле может замедлить вашу программу в несколько раз.
Считывание файлов в массив командой readarray дает иногда огромный выигрыш по сравнению с командой read в цикле (зависит от длины файла), и уж точно гораздо симпатичнее выглядит.
Команда инкремента работает быстрее команды сложения.
Для перевода чисел из шестнадцатеричной системы счисления в десятеричную я использовала свою функцию:
Учитывая то, что я говорила про expr, можно догадаться: работала эта функция не очень быстро. Добрый mkot подсказал мне простой способ перевода чисел из одной системы счисления в другую:
Благодаря всего лишь одной этой замене скорость эмуляции возросла в три раза. Поэтому читайте Advanced Bash-Scripting Guide внимательнее, и не придумывайте тормозных велосипедов.
Заключительный совет. Старайтесь не использовать знаки $ там, где это возможно, потому что доллары США негативно влияют на свободную оболочку:
На разработку эмулятора ушло около 8 часов. Вероятно, в нем не обошлось без багов (особенно переживаю за логические функции), но в целом он работает, и довольно успешно. Часть советов по оптимизации я применила в эмуляторе, а часть — нет, с надеждой, что дополнительные правки ускорят выполнение программ в эмуляторе незначительно. К сожалению, эмулятор не поддерживает работу с портами и прерываниями, зато в нем есть функция «Вывод символа на экран» из программы Монитор для Радио 86РК.
К сожалению, исходный код эмулятора на сегодняшний день (1 июня 2017) утерян.
Запускать следующим образом:
На экран будет выведено содержимое регистров и флагов.
Программы следует записывать в шестандцатеричном виде, по одному байту в строке.
Пример программы, выполняющей пустой цикл 256 раз:
Любителям программировать в машинных кодах наверняка поможет краткое руководство из виртуального компьютерного музея.
Ах да, насчет CP/M. Запустить её, конечно, можно. Но загрузка ОС и печать приглашения на экран может занять несколько минут.
На сегодня всё. Счастливого всем хакинга.
Наконец, завтра наступило. В bash (после некоторого допиливания) можно запустить серьезную ОС, например, CP/M. А для CP/M определенно есть СУБД, компиляторы и многое другое.
Почему не нужно и зачем нужно делать эмуляторы на bash, работающий эмулятор i8080 на bash и несколько советов по ускорению работы bash-скриптов -
Почему не нужно делать эмуляторы на bash
Bash работает неторопливо. Даже для такого простого процессора, как i8080, едва ли скорость эмуляции будет хотя бы 1% от реальной. На моем Celeron с частотой 2.2ГГц эмулятор работает со скоростью примерно 100 операций в секунду, в то время как реальный процессор i8080 на 2.5МГц отрабатывает 600 тысяч операций в секунду.
Другая важная проблема: в bash невозможно работать с двоичными данными. Если вы хотите вывести в порт или считать из файла символ с кодом 0x01, то bash — явно не тот язык, который вам нужен.
Третья проблема. Разработка эмулятора — это задачка не на час и не на два. Не стоит писать эмулятор без редактора с подсветкой синтаксиса и без отладчика. Когда я начала «сочинять» свой эмулятор, то думала: «А, нужно сделать всего-навсего 84 команды! Ерунда какая!». Дойдя до 51го кода операции, я наконец осознала, что команда != код операции, и что предстоит реализовать еще 200 кодов. Если бы я сразу учла, что кодов операций за две сотни, то не стала бы писать эмулятор. А раз уж начала писать — пришлось доделывать.
Зачем нужно делать эмуляторы на bash
Затем, что это супер-пупер-мега круто. Затем, что это дает огромный опыт программирования на bash. Затем, что программы в эмуляторе будут выполняться очень-очень медленно, и можно будет уследить за изменением флагов и регистров.
Советы по ускорению кода на bash
Скорость выполнения кода для эмулятора критически важна. Если вы хотите, чтобы ваш скрипт на bash выполнялся как можно быстрее, то:
- не используйте expr и bc, если это возможно;
- считывайте файлы командой readarray, а не построчно командой read;
- замените все A=$(( A + 1 )) на (( ++A ));
- не изобретайте велосипеды, аналогичные существующим командам bash;
- старайтесь не использовать знак $.
Вызов expr или bc в цикле может замедлить вашу программу в несколько раз.
$ time ( for ((i = 0; i < 100000; ++i)); do echo `expr 1 + 2` ; done )
real 0m17.000s
user 0m13.261s
sys 0m8.061s
$ time ( for ((i = 0; i < 100000; ++i)); do echo "$(( 1 + 2 ))" ; done )
real 0m3.980s
user 0m2.371s
sys 0m0.237s
Считывание файлов в массив командой readarray дает иногда огромный выигрыш по сравнению с командой read в цикле (зависит от длины файла), и уж точно гораздо симпатичнее выглядит.
$ time ( for ((i = 0; i < 10; ++i)); do while read line ; do rom[${tmpcnt}]=$line ; (( ++tmpcnt )) ; done < bas.e80 ; done )
real 0m6.888s
user 0m5.516s
sys 0m0.336s
$ time ( for ((i = 0; i < 10; ++i)); do readarray -t rom < bas.e80 ; done )
real 0m0.146s
user 0m0.048s
sys 0m0.004s
Команда инкремента работает быстрее команды сложения.
$ time ( for ((i = 0; i < 100000; ++i)); do a=$(( a + 1 )) ; done )
real 0m4.489s
user 0m3.692s
sys 0m0.108s
$ time ( for ((i = 0; i < 100000; ++i)); do (( ++a )) ; done )
real 0m4.053s
user 0m3.296s
sys 0m0.140s
Для перевода чисел из шестнадцатеричной системы счисления в десятеричную я использовала свою функцию:
hex2dec () {
uw=`expr index "0123456789ABCDEF" "${1:0:1}"`
lw=`expr index "0123456789ABCDEF" "${1:1:1}"`
res=$(( ( ${uw} - 1 ) * 16 + ${lw} - 1 ))
}
Учитывая то, что я говорила про expr, можно догадаться: работала эта функция не очень быстро. Добрый mkot подсказал мне простой способ перевода чисел из одной системы счисления в другую:
hex2dec () {
define -i res
res="16#$1"
}
Благодаря всего лишь одной этой замене скорость эмуляции возросла в три раза. Поэтому читайте Advanced Bash-Scripting Guide внимательнее, и не придумывайте тормозных велосипедов.
Заключительный совет. Старайтесь не использовать знаки $ там, где это возможно, потому что доллары США негативно влияют на свободную оболочку:
$ time ( for ((i = 0; i < 100000; ++i)); do a=$(( $a + 1 )) ; done )
real 0m5.155s
user 0m4.828s
sys 0m0.088s
$ time ( for ((i = 0; i < 100000; ++i)); do a=$(( a + 1 )) ; done )
real 0m4.489s
user 0m3.692s
sys 0m0.108s
Эмулятор i8080
На разработку эмулятора ушло около 8 часов. Вероятно, в нем не обошлось без багов (особенно переживаю за логические функции), но в целом он работает, и довольно успешно. Часть советов по оптимизации я применила в эмуляторе, а часть — нет, с надеждой, что дополнительные правки ускорят выполнение программ в эмуляторе незначительно. К сожалению, эмулятор не поддерживает работу с портами и прерываниями, зато в нем есть функция «Вывод символа на экран» из программы Монитор для Радио 86РК.
К сожалению, исходный код эмулятора на сегодняшний день (1 июня 2017) утерян.
Запускать следующим образом:
$ ./emu.sh program.e80
На экран будет выведено содержимое регистров и флагов.
Программы следует записывать в шестандцатеричном виде, по одному байту в строке.
Пример программы, выполняющей пустой цикл 256 раз:
3D
C2
00
00
76
Любителям программировать в машинных кодах наверняка поможет краткое руководство из виртуального компьютерного музея.
Ах да, насчет CP/M. Запустить её, конечно, можно. Но загрузка ОС и печать приглашения на экран может занять несколько минут.
На сегодня всё. Счастливого всем хакинга.