Насколько непереносимым является язык ассемблера / на самом деле /?

Я понимаю, что написание чего-либо на ассемблере или добавление ассемблера в любую программу вредит ее переносимости. Но насколько плохо? Я имею в виду, что в наши дни в основном все ПК имеют x86 или x64, верно? Итак, если я встраиваю ассемблер в программу на C, почему она все равно не компилируется, куда бы она ни пошла?

Относится ли это понятие непереносимости только к тому моменту, когда вы действительно вникаете в специфические особенности конкретного процессора, чтобы выжать каждую каплю производительности из фрагмента кода?

Игра для ПК "Roller Coaster Tycoon" была написана почти полностью на ассемблере, если я правильно помню. Итак ... Насколько это могло быть действительно непереносимым?


person Carson Myers    schedule 18.09.2009    source источник


Ответы (4)


Помимо самого процессора, конечно, всегда есть другие соображения: каковы соглашения о вызовах на вашей целевой платформе? Как struct значения передаются другим функциям (например, API)? Какие регистры могут быть заблокированы вызываемым пользователем? Какие гарантированно сохранятся для звонящего? Как сделать системный вызов? Какая схема памяти подготовлена ​​для вас ОС при запуске процесса?

person Dirk    schedule 18.09.2009
comment
+1, хотя я полагаю, что соглашения о вызовах и структуры данных не будут иметь значения, если ваша программа не взаимодействует с другими процессами. Что касается структуры памяти - что, если бы вы связали свою программу со стандартной библиотекой C целевой платформы и использовали ее malloc() и т. Д.? - person Carson Myers; 18.09.2009
comment
@Carson: соглашения о вызовах функций тоже имеют значение, поскольку вы, вероятно, захотите иметь возможность вызывать функцию, написанную на C, из смешанной сборки и наоборот. - person unwind; 18.09.2009
comment
FASM имеет хорошую переносимость между Windows и Linux. Насчет других ассемблеров не знаю. - person Imagist; 18.09.2009
comment
Как только вы получаете доступ к API ОС, вы взаимодействуете с другими процессами. Я не понимаю, как можно без этого программировать что-нибудь интересное. - person Nathan Fellman; 28.10.2009

При переносе сборки также возникает проблема ABI, которая варьируется от ОС к ОС. Перенос программы C из Unix в Windows (или даже из Linux в OpenBSD) может быть простой перекомпиляцией, но для программы сборки вы можете обнаружить, что некоторые регистры сохранения вызываемого объекта становятся сохранением вызывающего объекта или что параметры с плавающей запятой являются прошло иначе.

И это не только теоретически, а именно. register r2 версий PowerPC для Linux и Mac OS X. На практике проблема может быть не такой уж серьезной, например, AMD опубликовала «рекомендуемый» ABI одновременно со своим 64-битным набором инструкций.

person Pascal Cuoq    schedule 18.09.2009

Если вы думаете, что «ПК == Windows», то добавление ассемблера в программу на C не повредит. Если вы войдете в мир Unix, у вас будет много разных процессоров: PPC в PS3 или XBox, старые Mac и множество мощных серверов. Для многих небольших устройств у вас будет ARM. Встроенные устройства (на которые сегодня приходится подавляющее большинство установленных ЦП) обычно используют собственный ЦП со специальным набором инструкций.

Таким образом, хотя многие ПК сегодня могут запускать код Intel, он составляет лишь небольшую часть всех процессоров.

Тем не менее, код x86 тоже не всегда один и тот же. Есть две основные причины использования ассемблерного кода: вам нужен доступ к специальным функциям (например, регистрам прерываний) или вы хотите оптимизировать код. В первом случае код довольно переносимый. В последнем случае каждый процессор немного отличается. У некоторых из них есть SSE. Но вскоре SSE был заменен SSE2, который был заменен на SSE3 и SSE4. У AMD есть собственный бренд. Скоро будет AVX. На уровне кода операции каждый из них имеет немного разную синхронизацию в разных версиях ЦП.

Что еще хуже, некоторые коды операций содержат ошибки, которые исправляются в определенных степпингах процессора. Вдобавок ко всему, некоторые коды операций намного быстрее на одних версиях процессоров, чем на других.

Затем вам нужно будет связать этот ассемблерный код с частью C. Обычно это означает, что вам нужно либо иметь дело с проблемами ABI.

Итак, вы можете видеть, что это может быть сколь угодно сложно.

person Aaron Digulla    schedule 18.09.2009
comment
+1: Пример: Linux поддерживает десяток, если не больше, архитектур ЦП. Другой пример - экосистема Apple Unix: код Cocoa потенциально обращается к x86 на последних компьютерах Mac, PPC на старых компьютерах Mac и ARM на iPhone. - person mouviciel; 18.09.2009
comment
хорошо сказано - хотя под ПК я имел в виду не Windows, а средний персональный компьютер (то, что вы, вероятно, найдете в любом доме, а не на сервере, за исключением Xbox и встроенных систем и т. д.). - person Carson Myers; 18.09.2009
comment
Я думаю, вы имели в виду PC = windows, иначе вы бы не предположили, что все x86 или x64 :-) - person Gunther Piez; 21.09.2009
comment
Intel прилагает много усилий для поддержания обратной совместимости, включая ошибки. Если код операции содержит ошибки, будьте уверены, что спецификация будет изменена, а не поведение в будущем. В противном случае будет добавлен бит режима, позволяющий использовать ошибочный код операции. - person Nathan Fellman; 28.10.2009

сборка - это написание инструкции непосредственно для конкретного процессора, а это значит, что да, если x86 будет жить вечно, ваш код каким-то образом переносим.

Но даже сейчас процессоры для рук возвращаются (то есть нетбук следующего поколения), и я уверен, что процессор не изменится в следующем году.

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

person RageZ    schedule 18.09.2009