Линейка процессоров Intel и AMD в целом имеет большое совпадение в наборе команд, которые они реализуют (например, иногда один другой изобретает некоторые новые вещи, и есть пробел, пока другая компания не догонит) - вот почему вы могут запускать программы на обеих архитектурах. То же самое можно сказать и о том, что вы не можете запускать его на других архитектурах процессора - у них нет такого же набора команд для стартеров, но есть много разных вещей.
Операционные системы также имеют свои отличия. Например, когда вы компилируете программу под Windows, вы обычно получаете файл .exe. Этот .exe имеет формат, который понимает только Windows и сильно отличается от формата, используемого Linux, например.
Кроме того, поддержка, предоставляемая ОС, совершенно другая: в Windows есть разные функции ядра, которые вы можете вызывать по сравнению с, например, OpenBSD. Даже на более абстрактных уровнях это несовместимо. Например. Для обозначения дисков Windows использует буквы дисков, такие как C: \, D: \ и т. Д. под Linux это одна большая файловая система, в которой вы монтируете разные разделы, например. под/медиа или так далее.
Существуют различные попытки, такие как Wine и Cygwin, выполнять программы с одной платформы на другую. Используя Wine, вы можете запускать исполняемые файлы Windows непосредственно в Linux, поскольку он пытается имитировать то, что предоставляет Windows (не все работает). Cygwin - это другой продукт - вы можете запускать программы Windows, которые работают аналогично программам GNU в Linux, но их нужно специально скомпилировать, просто давая вам намек на то, что это всего лишь два мира.
Именно поэтому Java и .NET (с поддержкой Mono в Linux) пытаются объединить эти два. Когда вы создаете приложение Java, вы должны иметь возможность запускать его на Linux с более или менее одинаковым кодом - некоторые вещи могут быть не одинаковыми, а большинство.
Что касается 2), см. Ответы на http: // stackoverflow.com/вопросы/1442921/how-un-portable-is-assembly-language-really –