
Комментарии 25
Вот это называется, пригорело (психанул)). Тем не менее, очень интересно ).
Могобукав, но так и не понял, 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»?
И вообще, бурления из-за чего? Ну компилятор был 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++-программа, в которой есть вызовы виртуальных функций классов, тоже считается интерпретируемой? Если нет, то где принципиальная грань?
Действительно, немая пауза: Ассемблерный листинг с командами мы имеем, но почему он так щедро пересыпан нестандартными прерываниями 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-математики?
Так с тем, что он мог порождать исполняемые файлы никто не спорит. Вот только эти файлы были двух видов Stand-Alone EXE файл (включавший в себя RunTime Module) и EXE требовавшие наличия в же каталоге BRUN45.EXE или нахождения его где то в %path%. При отсутствии или повреждении этого файла эти "крутые" экзешники куксились и просились к мамке. 8D
И что это доказывает? Что QuickBasic-код не компилируется в машинный, а интерпретируется в момент выполнения?
Аналогичным образом программа на C или C++, если стандартная библиотека не будет статически влинкована в исполняемый файл на этапе сборки, будет зависеть от внешнего файла со стандартной библиотекой, и закуксится и попроситься к мамке, если не получится её нигде обнаружить.
Каким боком зависимость от внешнего файла, при том опциональная (на выбор разработчика — хочешь влинкуем всё в EXE, а хочешь будет внешняя зависимость) доказывает что язык является интерпретируемым и опровергает, что программа компилируется в машинный код?
Вот уж кто мастер натягивания совы на глобус с такой-то аргументацией...
Ого, деды яростно спорят за какой то старинный язык

Табличка на входе "курилка для дедов" не насторожила? А зачем тогда заходить, если тут "накурено" ?
ПыСы. Сам не знаю чем отличаются компилируемые exe в Бейсике, хотя многократно тестировал их производительность. От 3 до 20x скорости больше, чем в редакторе запускать.
Больше всего программ и утилиток я написал на VB6, эх... кряхтит.
Больше всего программ и утилиток я написал на VB6
А на чем еще можно за 5 минут набросать рабочую программу, да еще и с GUI, да еще и запускающуюся на любом компе (с виндой)?
Бойцы вспоминают минувшие дни
И битвы, где вместе сражались они
«Астанавитес!» (с)

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