Comments 47
Вот это называется, пригорело (психанул)). Тем не менее, очень интересно ).
Могобукав, но так и не понял, quickbasic таки генерил нативный код или нет?
Понятно, что vb5 опционально умел, VB6 по умолчанию.
quickbasic таки генерил нативный код или нет?
Конечно генерировал. В первоначальной статье это было продемонстрировано.
Продемонстрировано оно было весьма сомнительно. Машинного ассемблерного кода, эквивалентного исходному тексту, я там не увидел.
А ИИ говорит, что полноценная генерация появилась позже, в MS Basic Pds 7 и VB for DOS.
Продемонстрировано оно было весьма сомнительно.
Что именно вызывает вызывает сомнение? Что скриншоты сняты не с экрана, а сфабрикованы/нарисованы?
Машинного ассемблерного кода, эквивалентного исходному тексту, я там не увидел.
Давайте ещё раз. Возможно когда вы читали статью, у вас не загрузились картинки или что-то такое.
Вот исходный текст:

Смотрим на нижнюю часть, потому что это основное тело программы. В Quick Basic-е можно было не иметь процедуры main. В Python-е и прочих PHP можно. В VB, к слову, так нельзя. Так вот, смотрим на основе тело программы.
DECLARE SUB — это просто объявление прототипа процедуры, оно не должно скомпилироваться ни во что. Дальше идут стейтменты, которые непосредственно что-то делают.
Теперь смотрим на кусок машинного кода из EXE-файла, порождённого при компиляции:

Здесь на картинке .(скриншоте) я взял дизасм-листинг и «врезал» между строк строчки исходного бейсик-кода. Таким образом, для каждой бейсик-строчки под ней написан блок машинны команд, соответствующих этой строке.
CLS транслируется в вызов функции CLS (
call 0014:0019B) из стандартной библиотеки:.PRINT "We are ready..." транслируется в
mov ax, str_constзатемpush ax, затем call функции из стандартной библиотеки, отвечающей за PRINT.Синтаксическая структура FOR транслируется в целый ряз инструкций: пролог цикла задаёт начальное значение переменной (mov ax, 0BEEF), далее идёт джамп на концевое условие (CMP+JLE), п
Внутри цикла был вызов процедуры HELLO с передачей ему переменной i — это скомпилировалось в 3 инструкции, которые кладут на стек адрес переменной i и вызываются собственно процедуру HELLO.
Здесь ни сырой исходный бейсик код как текст. Ни токенизированный бейсик текст в виде байтов, каждый из которых означате токен. Ни какая-то сериализация AST. Ни набор инструкций для какой-то QB-специфичной виртуальной машины. Ни что-либо ещё такого.
Здесь ровно те машинные инструкции, которые получились бы на выходе Borland C, если бы ему на вход скормить аналогичный сишный код, делающий аналогичный цикл. Ну, максимум, с поправками на какие-то ABI-шиные особенности и моменты с разницей в соглашениях о вызове.
Что тут может быть сомнительным?
Для начала, где вызовы sleep?
Потом переменная цикла по адресу dc6. Цикл от beef до cafe с шагом 123h, а не 1 до 13. С телефона лень считать, тут вообще хотя бы 13 шагов?
Пардон, там в папке целая гора скриншотов и заготовок для статьи, так что я перетащил и прикрепил к комменту не ту картинку.
Приведённый выше дизасм соответствует вот этому исходному тексту:

Там по ходу статьи исходничек претерпевал некоторые косметические изменения (в основном чтобы картинки были не занимали в высоту больше места, чем мне хочется).
Ещё раз сделал косметические правки в исходнике, чтобы он хорошо умещался на картинке.
Исходник (слева) и его дизасм:

То же самое, но блоками и стрелкам показал соответствие между строками исходного текста и кусочками машинного кода, которые из этих строк получились:

Напоминаю, что показанный на скриншотах машинный код не сгенерировался в момент запуска EXE (путём какой-то там мифической интерпретации/дотрансляции), а изначально находится в EXE-файле.
Достаточно ли этой картинки чтобы опровергнуть утверждения «QuickBasic не настоящий компилятор, когда он генерирует EXE-файл он просто сшивает интерпретатор и исходник и выдаёт это за скомпилированный EXE»?
Понимаете, взрослые мальчики не стесняются щетины на своих щеках,. А взрослые компиляторы, с любого ЯП, не стесняются демонстрировать свой ассемблерный выхлоп, что бы программист знал как компилируется его код. ;)
ХЗ, на что опирался ИИ и вообще что там было.
скомипилировал вершину программистской мысли (да, да, print "hello world") в qb45, pds 7.1, tb1.1, pb 2.0.

никаких настроек кроме "Компилировать в exe" и "генерировать stand-alone" не устанавливал.
Песочница:

каждый компилятор в своем каталоге, никаких PATH, все exe скопировал в один каталог. Все запускаются нормально, никаких библиотек не просят.
Сообщения "syntax error" и прочие странности, как заметил ТС, имеются в exe от Microsoft, в двух других их нет.
PDS Basic 7.1 генерит файлы для real time DOS OS/2, возможно поэтому его файл больше, чем qb.
вот и все, что я хотел сказать о войне бейсках
Ни буя в НЛП шной статье не было продемонстрировано, точнее был продемонстрировано глубокое незнание вопроса
Ищите в статье ассемблерный листинг, он там под катом спрятан. ;)
Причем этот ассемблерный листинг создавал САМ компилятор BC (Basic Compiler)? нужно всего лишь добавить ключик /a в строку компиляции
И вообще, бурления из-за чего? Ну компилятор был 100 лет назад, ну интерпретатор, какая сейчас разница.
Вот Питонисты не ноют, а пишут 100500ю статью "как ускорить Питон" =)
Бурления не было, были лулзы с дутой статьи, переполненной подтасовками и манипуляцией;)
С чего началась та статья? с "масонского заговора в интернете" загубившего и захейтевшего "чудесный" продукт уступавший как прямым, так и косвенным конкурентом;)
Существует целый ряд инструментов, технологий и вообще вещей, которым по какой-то непонятной вселенской несправедливости не повезло: нашлась масса непонятных людей,
И в правду пригорело! Столько воды в статье. Лаконичность - явно не конек автора.
Да этих Басиков самых разных до и больше,и все Басиками называются.
В том числе и FreeBasic, и RapidQ Basic. Все там можно написать, если руки приложить.

Уж если кто и натягивает сову на глобус и другие предметы, так это автор этой статьи.
Во-первых, в той статье опровергался тезис о том, что QuickBasic тупо подшивает исходный текст программы в EXE-файл и при запуске EXE-файла начинается интерпретация исходного текста. Тезис был опровергнут просто-напросто демонстрацией машинного кода, в который переродился исходный QuickBasic-код. Если бы имела место интерпретация в момент запуска, готового машинного кода в EXE-файле, соответсвующего логике исходной программы, явно бы не было.
Но здесь @axe_chitaпытается это переиграть, обнаружив в бинарнике тексты сообщений об ошибках:
Шта? В откомпилированной программе, каким то неведомым чудом могли остаться синтаксические ошибки? Это как? Или "Duplicate definition", разве компилятор не должен был прекратить компиляцию при таком раскладе? Идем дальше, и видим "CASE ELSE expected" это как!? ;-)
Так продемонстируйте же факт синтаксического разбора исходного кода в уже готовом EXE-файле? Прямо с выдачей этих самых сообщений в случае, когда что-то не так с систаксисом исходной программы? Сам по себе факт наличия этих строк с сообщениям об ошибках ничего не доказывает. Он мог бы лишь навести на мысль об интерпретации исходного кода в момент запуска, породить просто в голове такую гипотезу, но демонстрация наличия в EXE-файле машинного кода (который соответствовал бизнес-логике исходного QuickBasic-кода) опровергает эту гипотезу.
---------
Во-вторых, и это главное, автор на протяжении всей статьи навязывает своё толкование понятия «интерпретируемый» и «интерпретация».
Выполнение P-code почему-то ему религия не позволяет называть выполнением: «нет, это не выполнение, ни в коем случае не выполнение, это интерпретация — вы не перепутайте». И дальше всё опровергается именно в таком ключе, присыпанное разными глупостями.
Непонятно только почему в таком случае выполнение x86-кода непосредственно процессором автор отказывается тоже называть не выполнением кода, а его интерпретацией. Ведь там мы имеем декодирование инструкций, ведь там мы имеем некую логику проверку корректности операндов инструкции, ведь там, как известно, CISC-инструкции транслируются в RISC-микроинструкции.
Пусть и это тогда называется не выполнением машинного кода, а интерпретацией. И все программы, в том числе написанные на C, C++, да хоть даже ассемблере, мы будем называть интерпретируемыми программами. Если автора устраивает такой расклад, я умываю руки и мне не о чем больше спорить.
Любая P-code инструкция, точнее её опкод, это просто индекс в таблице, определяющей, куда будет осуществлён переход (джамп) с одного куска native-кода на другой кусок native-кода. Работа виртуальной машины — это просто выполнение native-кода с периодическими джампами туда-сюда. Почему-то это нужно называть словом «интерпретация»... (Кто кого интерпретирует?)
Когда в C++ коде происходит вызов виртуальной функции класса, машинный код тоже берёт адрес из vftable и делает переход неизвестно куда (в том смысле, что это заведомо неизвестно на этапе компиляции). Повод ли это считать, что C++-программа, в которой есть вызовы виртуальных функций классов, тоже считается интерпретируемой? Если нет, то где принципиальная грань?
Уж если кто и натягивает сову на глобус и другие предметы, так это автор этой статьи.
Месье погорелый кулхацкер, вы наверное по жизни зонтом не пользуетесь? Ну меж струек пытаетесь проскользнуть? 8)) Всю статью ужом крутитесь "тут играем, тут не играем, а сюда не смотрите тут жирное пятно, а это вообще женский романс "темно вишнёвая шаль"" ? ;) И так на протяжение всей статьи ;)
Во-первых, в той статье опровергался тезис о том,
Надо "не опровергать ЧТО-ТО". Надо добираться до истины, найти первопричины почему сложилось "такое устойчивое мнение". Но у вас горел афедрон Вас переполняло "негодование и ненависть. Кровь ещё не закончила кипеть от негодования."
Но здесь @axe_chitaпытается это переиграть, обнаружив в бинарнике тексты сообщений об ошибках:
Да ты ШО! А их не должно было быть? Месье кулхацкер, я понимаю как пылает Ваш афедрон, но сообщения об ошибках исполнения есть во всех исполняемых файлах скомпилированных с высокоуровневых ЯП.
Так продемонстируйте же факт синтаксического разбора исходного кода в уже готовом EXE-файле?
Так это ВЫ, раз уж подались в адвокаты "мертвого льва", объясните какого буя делает ошибка исполнения "Syntax error" в исполняемом файле и в каких случаях она происходит? :)
Во-вторых, и это главное, автор на протяжении всей статьи навязывает своё толкование понятия «интерпретируемый» и «интерпретация».
Это не мое толкование, это общепринятое понятие. А то что Вы придумали свое "личное и сугубо авторитетное мнение имени себя" которое отличается от общепринятого, то это Ваши интимные проблемы. И не надо его навязывать всем :)
Выполнение P-code почему-то ему религия не позволяет называть выполнением: «нет, это не выполнение, ни в коем случае не выполнение, это интерпретация — вы не перепутайте».
Для подгорелых объясняю, PCODE не имеет ничего общего с машинным кодом исполняемым напрямую процессором. Более того в отсутствии виртуальной машины, это просто поток байтов.
Непонятно только почему в таком случае выполнение x86-кода непосредственно процессором автор отказывается тоже называть не выполнением кода, а его интерпретацией. Ведь там мы имеем декодирование инструкций, ведь там мы имеем некую логику проверку корректности операндов инструкции, ведь там, как известно, CISC-инструкции транслируются в RISC-микроинструкции.
А вот мисьЁ кулхацкер опять пытается манипулировать и подменять понятия в которых ни буя не соображает перемещая внимание с уровня процессора х86, на уровень микроархитектуры процессора которая внутренне может быть абсолютно разной, но на уровне процессора все они ведут себя абсолютно одинаково. Именно по этой причине я для сравнения компиляторов выбрал 8088 процессор, в котором нет ничего что вы назвали. ;)
Любая P-code инструкция, точнее её опкод, это просто индекс в таблице, определяющей, куда будет осуществлён переход (джамп) с одного куска native-кода на другой кусок native-кода.
А что происходит на 8088 процессоре при джампе? Правильно дети, очередь предвыбранных команд в конвейере CPU очищается, и заполняется заново, исполняется код подпрограммы реализующий данный оптокод PCODE, а потом нас ждет джамп в виде return который опять обнулит очередь команд, а тут у нас опять джамп и процессор постоянно тротлит конвейер. И всё это тормозит по кругу исполнение программы на PCODE. ;)
Когда в C++ коде происходит вызов виртуальной функции класса,
Идите в БАНЮ хацкер погорелого театра, вообще то вы не Си плюс плюс защищаете а КвикВаРсик. 8D
Действительно, немая пауза: Ассемблерный листинг с командами мы имеем, но почему он так щедро пересыпан нестандартными прерываниями INT 26/34/35/3A/3D? Да потому что это FLOATING POINT EMULATION, интерпретатор команд математического сопроцессора который содержится в модуле исполнения BRUN45.
И что это доказывает? Что QuickBasic-код не компилируется в машинный, а интерпретируется?
В архитектуре AVR8 нет FP-сопроцессора и FP-инструкций. Если мы пишем на C или C++ и компилируем с помощью avr-gcc, то FP-математика тоже будет эмулироваться (конечно, не с помощью прерываний). Какой вывод, по мнению автора, из этого нужно сделать? Что C и C++ в случае компилирования AVR8 становятся интерпретируемыми языками? Что avr-gcc — неполноценный компилятор? Или только факт использования инструкции INT волшебным образом делает разницу? Или где та чёртова грань или хоть какая-то логика? К чему эта демонстрация эмуляции FP-математики?
И что это доказывает?
Это показывает почему "мертвый лев" был тормознутым и проигрывал конкурентам. 8))
В архитектуре AVR8
Идите в БАНЮ хацкер погорелого театра, обсуждение идет в рамка архитектуры х86 процессоров. Хотя нет. Раз Вы мусьЁ, упомянули архитектуру AVR8, то я требую для сравнения производительности и качества компиляторов QuickBasic предоставить для сравнения версию QuickBasic работающую на AVR8, порождающую код для AVR8, и это QuickBasic должен быть выпущен фирмой Microsoft. До тех пор пока не будет представлена такая версия QuickBasic, я буду считать Вас балаболом. 8Р
Так с тем, что он мог порождать исполняемые файлы никто не спорит. Вот только эти файлы были двух видов Stand-Alone EXE файл (включавший в себя RunTime Module) и EXE требовавшие наличия в же каталоге BRUN45.EXE или нахождения его где то в %path%. При отсутствии или повреждении этого файла эти "крутые" экзешники куксились и просились к мамке. 8D
И что это доказывает? Что QuickBasic-код не компилируется в машинный, а интерпретируется в момент выполнения?
Аналогичным образом программа на C или C++, если стандартная библиотека не будет статически влинкована в исполняемый файл на этапе сборки, будет зависеть от внешнего файла со стандартной библиотекой, и закуксится и попроситься к мамке, если не получится её нигде обнаружить.
Каким боком зависимость от внешнего файла, при том опциональная (на выбор разработчика — хочешь влинкуем всё в EXE, а хочешь будет внешняя зависимость) доказывает что язык является интерпретируемым и опровергает, что программа компилируется в машинный код?
Вот уж кто мастер натягивания совы на глобус с такой-то аргументацией...
И что это доказывает? Что QuickBasic-код не компилируется в машинный, а интерпретируется в момент выполнения?
Что у неё внутри неонка этого модуля был интерпретатор операций с плавающей запятой. :))
Аналогичным образом программа на C или C++,
Идите в БАНЮ хацкер погорелого театра, мы КвирБаРсик обсуждаем, а не Си или плюсы;)
если стандартная библиотека не будет статически влинкована в исполняемый файл на этапе сборки
МусьЁ кулхацкер, во времена DOS при линковке все связывалось статически ибо ОС однозадачная ;)
Каким боком зависимость от внешнего файла, при том опциональная (на выбор разработчика — хочешь влинкуем всё в EXE, а хочешь будет внешняя зависимость) доказывает что язык является интерпретируемым и опровергает, что программа компилируется в машинный код?
Это доказывает, что с точки зрения DOS программиста, EXE требующий для исполнения совсем другой EXE файл выглядел ущербным. ;)
Ого, деды яростно спорят за какой то старинный язык

Табличка на входе "курилка для дедов" не насторожила? А зачем тогда заходить, если тут "накурено" ?
ПыСы. Сам не знаю чем отличаются компилируемые exe в Бейсике, хотя многократно тестировал их производительность. От 3 до 20x скорости больше, чем в редакторе запускать.
Больше всего программ и утилиток я написал на VB6, эх... кряхтит.
Больше всего программ и утилиток я написал на VB6
А на чем еще можно за 5 минут набросать рабочую программу, да еще и с GUI, да еще и запускающуюся на любом компе (с виндой)?
Да блин печаль беда, на питоне с апишкой нормально поговорить можно(но на питоне гуй вообще писать боль и ад) , а на VB я даже и не пробовал. Хотя можно написать переходник...хм..вы подкинули интересную идею.
Я на VBDOS для клиентов быстро собирал прототип с полноценным TUI , а потом "с чувством, толком, расстановкой" переписывал критические места на Turbo/Borland C, потом прилинковывал их к проекту. Или оформлял в виде либы если процедуры/функции использовались повторно.
ПыСы. Сам не знаю чем отличаются компилируемые exe в Бейсике, хотя многократно тестировал их производительность. От 3 до 20x скорости больше, чем в редакторе запускать.
Для этого я в статье и привел табличку с результатами кто на свете всех милее, всех румяней, и белее быстрее в одинаковых условиях, как по скорости компиляции, так и по качеству кода:
"Чтобы избежать разнотолков "как было на самом деле", будем использовать не DOSBox, а PCEm v17 на референсной машине (Xi8088) с 8088@4.77мгц, DOS 5 (RUS). И получаем следующие результаты:

А вот текст программы на которой проверялись интерпретаторы (GWBASIC/QBASIC) и компиляторы (все остальные)
5 CLS : z = TIMER
10 SCREEN 0
100 FOR PY = 0 TO 21
110 FOR PX = 0 TO 31
120 XZ = PX * 3.5 / 32 - 2.5
130 YZ = PY * 2 / 22 - 1
140 X = 0
150 Y = 0
160 FOR I = 0 TO 14
170 IF X * X + Y * Y > 4 THEN GOTO 215
180 XT = X * X - Y * Y + XZ
190 Y = 2 * X * Y + YZ
200 X = XT
210 NEXT I
215 IF I = 15 THEN I = 0
220 LOCATE PY + 1, PX * 2 + 1
230 COLOR 0, I
235 PRINT " "
240 NEXT PX
260 NEXT PY
270 PRINT (TIMER - z)
280 a$=input$(1)Бойцы вспоминают минувшие дни
И битвы, где вместе сражались они
Тут сражения не было, в те времена Мелкомягкие капитально сливали Борланду в гонке компиляторов. ;)
В чем именно сливали? В производительности, в объемах продаж, популярности?
По всем перечисленным параметрам в конце 80-х начале 90-х среды разработки сливали борланду и остальным. Плюс микрософт Си был настолько забагованным что по ББСкам ходили описания изза чего может вылететь компилятор. файл ЕМНИП назывался knootout.msc
джентльменам конечно верят на слово, но подобные утверждения подкрепленные цифрами вызывают больше доверия.
Я правда переехал с борланд с, на ватком с из-за простого перехода на 32бит, но насколько помню, конкуренция была равная - борланд быстро компилировался, а мс с лучше оптимизировал. Можно журналы др.добба поднял, есть архивы в нете
Ну у меня примерно такие же воспоминания. При этом, что интересно, оба компилятора были "чужими" - и Борладно и Микрософт купили их у кого-то.
Во времена 16 битного DOS Microsoft С страдал одно неприятной фигней, его преследовали нокауты, когда он вылетал при компиляции ничем не примечательного кода, мог выдать бажный код с адресной арифметикой дальних указателей. И самое смешное, тот же самый код без изменений спокойно компилился turbo/borland С без всяких проблем.
А вот с 32 битными DOS программами, borland прошел мимо, PowerPack в наших краях так и не завёлся. И народ в массе своей ушел на Watcom. По оптимизации,в DOS32, самым продвинутым был NDP486, он выдавал самый быстрый код, Watcom уверенно держал второе место. За ним дыша в затылок шел DJGPP
«Астанавитес!» (с)
Приложения на Electron JS в этом смысле пошли дальше.

«Как натянуть сову на глобус, не привлекая внимания санитаров?» или по следам «мёртвого льва которого пнули»