Какая часть (конкретно) собственного исполняемого файла делает это непортативным?

Кажется, что все ответы здесь упускают очень важный момент. Подробно, как реализован «интерпретируемый» код.

Интерпретируемые языки сценариев медленнее, потому что их метод, объект и модель пространства глобальных переменных являются динамическими. На мой взгляд, это реальное определение языка сценариев, а не факт его интерпретации. Это требует много дополнительных поисков хеш-таблицы при каждом доступе к переменной или вызову метода. И это главная причина, почему все они ужасны при многопоточности и использовании GIL (Global Interpreter Lock). Этот поиск - то, где большая часть времени проведена. Это болезненный случайный поиск в памяти, который действительно больно, когда вы получаете ошибку кэша L1 / L2.

Google Javascript Core8 настолько быстр и нацелен почти на скорость C для простой оптимизации: они принимают объектную модель данных как фиксированную и создают внутренний код для доступа к ней, как структуру данных встроенной скомпилированной программы. Когда новая переменная или метод добавляются или удаляются, весь скомпилированный код отбрасывается и компилируется снова.

Техника хорошо объяснена в статье Дойча / Шиффмана «Эффективное внедрение системы Smalltalk-80».

На вопрос, почему php, python и ruby ​​не делают этого, довольно просто ответить: метод чрезвычайно сложен в реализации.

И только у Google есть деньги, чтобы заплатить за JavaScript, потому что быстрый интерпретатор JavaScript на основе браузера является их фундаментальной потребностью в их бизнес-модели на миллиард долларов.

6
задан starblue 17 November 2009 в 09:37
поделиться

8 ответов

Есть ряд причин. Основными из них, отсортированными по «дистанции от металла», являются:

  1. В операционных системах могут быть разные двоичные форматы исполняемых файлов. В этом случае вы вообще не сможете загрузить двоичный файл.
  2. Программа может использовать другой метод, чтобы указать, что они хотят разместить системный вызов (например, INT21 против INT80).
  3. Программа может полагаться на системные вызовы, которых нет в другой ОС (например, dlopen ())
  4. Программа может полагаться на стандартную библиотеку, отсутствующую в другой ОС.
  5. Программа может полагаться на другие библиотеки, которые недоступны в другой ОС. другая ОС.

Конечно, есть много других способов, по которым программа, запущенная в неожиданной среде, может привести к серьезному сбою.

12
ответ дан 8 December 2019 в 04:31
поделиться

Есть четыре проблемы:

  1. Различные операционные системы по-разному упаковывают свои двоичные исполняемые файлы (например, Linux ELF или формат Windows);
  2. Различные наборы инструкций на разных архитектурах ЦП;
  3. Разные операционные системы имеют разные системные вызовы (например, CreateProcess () в Win32 и fork () в Linux / Unix);
  4. Различия, такие как пути, допустимые символы, разделители каталогов и т. д.

Предполагается, что несистемные библиотеки присутствовать на обоих, иначе это еще одна разница.

5
ответ дан 8 December 2019 в 04:31
поделиться

It's mainly the APIs. For example Win32 APIs are not really available on Linux. It is possible to get around this though, see Wine. The executable format may also be different (ELF/PE), but that could be fixed fairly easily (Wine does this; it allows PE executables to be executed on Linux).

Also, your example of Solaris and Linux executables mixing would be fairly easy to implement, since the OSs are so similar (ELF for executable format, POSIX APIs, X window system, etc.). FreeBSD can already run Linux executables. The reason this is not so common is simply that there is not much of a demand for it. There are a whole lot more Windows programs than *NIX programs, so Wine was created. There are a whole lot more Linux programs than FreeBSD programs, so FreeBSD implemented the Linux compatibility layer. Solaris might eventually implement something similar too. However, don't expect the reverse (Solaris/BSD executables on Linux), since there is just no demand for it.

3
ответ дан 8 December 2019 в 04:31
поделиться

It is system specific libraries that are not always portable. For example, you cannot use the win32 window api on vanilla linux (and yes i realize there are work arrounds for this such as wine, its not the best example).

1
ответ дан 8 December 2019 в 04:31
поделиться

В дополнение к тому, что говорили другие, фактический формат исполняемого файла может отличаться. Поэтому, когда ОС загружает его, она не находит ожидаемых значений для кода, сегментов данных и т. Д. В нужных местах файла.

1
ответ дан 8 December 2019 в 04:31
поделиться

Системные библиотеки и API. Фактический простой код должен работать. Вот почему такие уровни, как Wine, не выполняют никакой эмуляции процессора, они просто повторно реализуют Windows API.

1
ответ дан 8 December 2019 в 04:31
поделиться

Как уже указывалось, несовместимость связана не столько с самими исполняемыми форматами, сколько с библиотеками, на которые ссылается исполняемый файл.

Я считаю, что Linux действительно совместим с рядом различных исполняемых файлов. форматы, хотя здесь я могу ошибаться

0
ответ дан 8 December 2019 в 04:31
поделиться

Помимо двоичного формата и других функций "упаковки" (которые тоже могут быть не совсем тривиальными) Есть также последствия, которые вы обнаруживаете почти во всех фрагментах кода. Такие вещи, как

  1. PIC, могут привести к тому, что каждый глобальный доступ будет полагаться на специфические для системы допущения при перезагрузке указателя GOT и допущения о дополнительных смещениях.
  2. Многие системы имеют специфический ABI, передавая небольшие структуры в регистры, пропуская регистры для целей выравнивания. , резервирование регистров для специальных целей. Некоторые из них (например, ARM EABI и OABI)
  3. имеют несколько проблем, связанных с локальным хранилищем потоков, переменные, экземпляры которых создаются для каждого потока, тесно связаны со средствами, определяемыми ОС. Выбор регистра, смещения и т. Д.
  4. Некоторые ОС (в первую очередь) окна поддерживают определенный формат обработки исключений, чтобы разрешить межъязыковую и даже межмашинную (через DCOM) обработку исключений.
  5. Кросс-программные системы более высокого уровня (например, COM, но также, например, совместимость Objective C на Mac или совместимость с определенной комбинацией версий KDE-gcc) также могут иметь определенные требования к макету VMT.
  6. Некоторые компоновщики и форматы поддерживают отрицательные смещения для раздела, а некоторые нет.

Обратите внимание, что это это просто набор вещей, на которые было бы интересно посмотреть. Вероятно, он не полон, и не все могут применяться. Некоторые из вышеперечисленных пунктов могут совпадать (например, резервирование реестра для TLS или PIC также является изменением ABI)

Совместимость с Objective C на Mac или совместимость с определенной комбинацией версий KDE-gcc) также может иметь определенные требования к макету VMT.
  • Некоторые компоновщики и форматы поддерживают отрицательные смещения для раздела, а некоторые нет.
  • Обратите внимание, что это просто куча вещей, которые было бы интересно изучить. Вероятно, он не полон, и не все могут применяться. Некоторые из вышеперечисленных пунктов могут совпадать (например, резервирование реестра для TLS или PIC также является изменением ABI)

    Совместимость с Objective C на Mac или совместимость с определенной комбинацией версий KDE-gcc) также может иметь определенные требования к макету VMT.
  • Некоторые компоновщики и форматы поддерживают отрицательные смещения для раздела, а некоторые нет.
  • Обратите внимание, что это просто куча вещей, которые было бы интересно изучить. Вероятно, он не полон, и не все могут применяться. Некоторые из вышеперечисленных пунктов могут совпадать (например, резервирование реестра для TLS или PIC также является изменением ABI)

    2
    ответ дан 8 December 2019 в 04:31
    поделиться
    Другие вопросы по тегам:

    Похожие вопросы: