Обновить

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

Время на прочтение35 мин
Охват и читатели8.8K
Всего голосов 14: ↑7 и ↓7+2
Комментарии25

Комментарии 25

НЛО прилетело и опубликовало эту надпись здесь
НЛО прилетело и опубликовало эту надпись здесь

Могобукав, но так и не понял, quickbasic таки генерил нативный код или нет?

Понятно, что vb5 опционально умел, VB6 по умолчанию.

quickbasic таки генерил нативный код или нет?

Конечно генерировал. В первоначальной статье это было продемонстрировано.

Продемонстрировано оно было весьма сомнительно. Машинного ассемблерного кода, эквивалентного исходному тексту, я там не увидел.

А ИИ говорит, что полноценная генерация появилась позже, в MS Basic Pds 7 и VB for DOS.

Продемонстрировано оно было весьма сомнительно.

Что именно вызывает вызывает сомнение? Что скриншоты сняты не с экрана, а сфабрикованы/нарисованы?

Машинного ассемблерного кода, эквивалентного исходному тексту, я там не увидел.

Давайте ещё раз. Возможно когда вы читали статью, у вас не загрузились картинки или что-то такое.

Вот исходный текст:

B
B

Смотрим на нижнюю часть, потому что это основное тело программы. В 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ю статью "как ускорить Питон" =)

Ну компилятор был 100 лет назад, ну интерпретатор, какая сейчас разница.

Да, много чего было на моём веку! Я бы предложил вспомнить АЛМО: Язык системного программирования АЛМО (АЛгоритмический Машинно-Ориентированный) задумывался как язык-посредник при трансляции с различных языков

И в правду пригорело! Столько воды в статье. Лаконичность - явно не конек автора.

Да этих Басиков самых разных до и больше,и все Басиками называются.
В том числе и 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, да еще и запускающуюся на любом компе (с виндой)?

Да блин печаль беда, на питоне с апишкой нормально поговорить можно(но на питоне гуй вообще писать боль и ад) , а на VB я даже и не пробовал. Хотя можно написать переходник...хм..вы подкинули интересную идею.

Бойцы вспоминают минувшие дни

И битвы, где вместе сражались они

«Астанавитес!» (с)

Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации